inline std::pair< typename DIRECTED_GRAPH::edge_iterator, typename DIRECTED_GRAPH::edge_iterator > edges(DIRECTED_GRAPH const& g) { return edges(g.impl()); }
HtmlBuilder::HtmlBuilder(TextData const *src, int start, int end) { text = src->text(); if (end<0) end = text.size(); text = text.mid(start, end-start); MarkupEdges edges(src->markups()); MarkupStyles style; foreach (int k, edges.keys()) if (k<start) style = edges[k]; else break; if (!edges.contains(start)) { nowedges << start; nowstyles << style; } foreach (int k, edges.keys()) { if (k>=start && k<end) { style = edges[k]; nowedges << k; nowstyles << style; } else if (k>=end) { break; } } nowedges << end; QList<MarkupData::Style> allStyles; allStyles << MarkupData::Italic; allStyles << MarkupData::Bold; allStyles << MarkupData::Superscript; allStyles << MarkupData::Subscript; style = MarkupStyles(); for (int n=0; n<nowedges.size()-1; n++) { QString bit = text.mid(nowedges[n]-start, nowedges[n+1]-nowedges[n]); MarkupStyles newst = nowstyles[n]; // peel off stack anything that closes here while (!stack.isEmpty() && !newst.contains(stack.last())) { html += closingTag(stack.last()); style.remove(stack.takeLast()); } // anything that closes out of order needs to be peeled off too foreach (MarkupData::Style s, allStyles) { if (style.contains(s) && !newst.contains(s)) { while (true) { html += closingTag(stack.last()); style.remove(stack.last()); if (stack.takeLast()==s) break; } } } // add new stuff foreach (MarkupData::Style s, allStyles) { if (newst.contains(s) && !style.contains(s)) { html += openingTag(s); style.add(s); stack << s; } } html += bit; } // peel off rest while (!stack.isEmpty()) html += closingTag(stack.takeLast()); }
typename graph_traits < VertexListGraph >::degree_size_type edge_connectivity(VertexListGraph & g, OutputIterator disconnecting_set) { typedef typename graph_traits < VertexListGraph >::vertex_descriptor vertex_descriptor; typedef typename graph_traits < VertexListGraph >::degree_size_type degree_size_type; typedef color_traits < default_color_type > Color; typedef typename adjacency_list_traits < vecS, vecS, directedS >::edge_descriptor edge_descriptor; typedef adjacency_list < vecS, vecS, directedS, no_property, property < edge_capacity_t, degree_size_type, property < edge_residual_capacity_t, degree_size_type, property < edge_reverse_t, edge_descriptor > > > > FlowGraph; vertex_descriptor u, v, p, k; edge_descriptor e1, e2; bool inserted; typename graph_traits < VertexListGraph >::vertex_iterator vi, vi_end; degree_size_type delta, alpha_star, alpha_S_k; std::set < vertex_descriptor > S, neighbor_S; std::vector < vertex_descriptor > S_star, nonneighbor_S; std::vector < default_color_type > color(num_vertices(g)); std::vector < edge_descriptor > pred(num_vertices(g)); FlowGraph flow_g(num_vertices(g)); typename property_map < FlowGraph, edge_capacity_t >::type cap = get(edge_capacity, flow_g); typename property_map < FlowGraph, edge_residual_capacity_t >::type res_cap = get(edge_residual_capacity, flow_g); typename property_map < FlowGraph, edge_reverse_t >::type rev_edge = get(edge_reverse, flow_g); typename graph_traits < VertexListGraph >::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { u = source(*ei, g), v = target(*ei, g); boost::tie(e1, inserted) = add_edge(u, v, flow_g); cap[e1] = 1; boost::tie(e2, inserted) = add_edge(v, u, flow_g); cap[e2] = 1; rev_edge[e1] = e2; rev_edge[e2] = e1; } boost::tie(p, delta) = min_degree_vertex(g); S_star.push_back(p); alpha_star = delta; S.insert(p); neighbor_S.insert(p); neighbors(g, S.begin(), S.end(), std::inserter(neighbor_S, neighbor_S.begin())); std::set_difference(vertices(g).first, vertices(g).second, neighbor_S.begin(), neighbor_S.end(), std::back_inserter(nonneighbor_S)); while (!nonneighbor_S.empty()) { k = nonneighbor_S.front(); alpha_S_k = edmonds_karp_max_flow (flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); if (alpha_S_k < alpha_star) { alpha_star = alpha_S_k; S_star.clear(); for (boost::tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) if (color[*vi] != Color::white()) S_star.push_back(*vi); } S.insert(k); neighbor_S.insert(k); neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); nonneighbor_S.clear(); std::set_difference(vertices(g).first, vertices(g).second, neighbor_S.begin(), neighbor_S.end(), std::back_inserter(nonneighbor_S)); } std::vector < bool > in_S_star(num_vertices(g), false); typename std::vector < vertex_descriptor >::iterator si; for (si = S_star.begin(); si != S_star.end(); ++si) in_S_star[*si] = true; degree_size_type c = 0; for (si = S_star.begin(); si != S_star.end(); ++si) { typename graph_traits < VertexListGraph >::out_edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) if (!in_S_star[target(*ei, g)]) { *disconnecting_set++ = *ei; ++c; } } return c; }
int main( int argc, char** argv ) { std::cout << "Starting..\n"; std::vector<std::string> file_names; parse_args(argc, argv, file_names); file_names.push_back(std::string("b0e0.hgt")); InitGraphics(); glfwSetWindowTitle( "p7" ); // Ensure we can capture the escape key being pressed below glfwEnable( GLFW_STICKY_KEYS ); // Dark blue background glClearColor(0.7f, 0.7f, 0.7f, 0.0f); // Enable depth test glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LESS); // glFrontFace(GL_CCW); // Create and compile our GLSL program from the shaders GLuint programIDs[2] = { LoadShaders( "tvs.vertexshader", "cfs.fragmentshader" ), LoadShaders( "tvs2.vertexshader", "cfs.fragmentshader" )}; std::cout << "Linked shaders..\n"; // Get a handle for our "MVP" uniform GLuint MatrixIDs[2] = {glGetUniformLocation(programIDs[0], "MVP"), glGetUniformLocation(programIDs[1], "MVP")}; GLuint EdgexIDs[2] = {glGetUniformLocation(programIDs[0], "Edgex"), glGetUniformLocation(programIDs[1], "Edgex")}; GLuint EdgeyIDs[2] = {glGetUniformLocation(programIDs[0], "Edgey"), glGetUniformLocation(programIDs[1], "Edgey")}; GLuint HeightIDs[2] = {glGetUniformLocation(programIDs[0], "height"), glGetUniformLocation(programIDs[1], "height")}; GLuint TextureIDs[2] = {glGetUniformLocation(programIDs[0], "tex2d"), glGetUniformLocation(programIDs[1], "tex2d")}; GLuint TimeIDs[2] = {glGetUniformLocation(programIDs[0], "time"), glGetUniformLocation(programIDs[1], "time")}; GLuint AlphaIDs[2] = {glGetUniformLocation(programIDs[0], "alpha"), glGetUniformLocation(programIDs[1], "alpha")}; std::cout << "Got uniforms..\n"; std::cout << glGetString(GL_VERSION) << std::endl; std::cout << "Loadin textures...\n"; char texName[] = "texture3.jpg"; std::cout << texName << std::endl; int t1x,t1y,t1comp; FILE* t1f = fopen(texName, "rb"); unsigned char* tex1data = stbi_load_from_file(t1f, &t1x, &t1y, &t1comp,0); unsigned int tex_2d; glGenTextures(1, &tex_2d); glBindTexture(GL_TEXTURE_2D, tex_2d); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, t1x, t1y, 0, GL_RGB, GL_UNSIGNED_BYTE, tex1data); /* char texNameCl[] = "textureClouds3.png"; std::cout << texNameCl << std::endl; int t2x,t2y,t2comp; FILE* t2f = fopen(texNameCl, "rb"); unsigned char* tex2data = stbi_load_from_file (t2f, &t2x, &t2y, &t2comp,0); unsigned int tex_cl; glGenTextures(1, &tex_cl); glBindTexture(GL_TEXTURE_2D, tex_cl); //--> glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, t2x, t2y, 0, GL_RGB, GL_UNSIGNED_BYTE, tex2data); */ std::cout << "Done!\n"; const int side(1201); const int vBOsize(file_names.size()); //Vertices: short piece_map[360][181]; for(int i=0; i<360; i++) for(int y=0; y<=180; y++) piece_map[i][y] = -1; unsigned int numberOfVertices=side*side; GLuint vaoObjects[vBOsize+1], vertexBufferObject, vBOs[vBOsize+1]; std::vector<std::pair<int, int> > edges(vBOsize+1); // --> std::cout << "Generating arrays...\n"; glGenVertexArrays(vBOsize, vaoObjects); std::cout << "Done\n"; glGenBuffers(vBOsize, vBOs); int height; // <--- for(short i=0; i< vBOsize; i++) { std::vector< int > vertexPositionsVec(3*numberOfVertices); int* vertexPositions = &vertexPositionsVec[0]; loadVertices(file_names[i], vertexPositionsVec, true, side, edges[i], height); glBindVertexArray(vaoObjects[i]); glBindBuffer(GL_ARRAY_BUFFER, vBOs[i]); glVertexAttribPointer( 0, // attribute. No particular reason for 0, but must match the layout in the shader. 3, // size GL_INT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glBufferData(GL_ARRAY_BUFFER, sizeof(int)*3*numberOfVertices, vertexPositions, GL_STATIC_DRAW); if(i<vBOsize-1) { piece_map[edges[i].second+180][edges[i].first+90]=i; std::cout << edges[i].second+180 << " " << edges[i].first+90 << std::endl; } } //Indices:: GLuint indexBufferObject, iBOs[maxLoD], numberOfIndices; std::vector<GLuint> nOIs(maxLoD); glGenBuffers(maxLoD, iBOs); for(unsigned int density=1, i=0; i<maxLoD; i++, density*=2) { std::cout << "Entering for with i: " << i << "\n"; nOIs[i]=(side-1)/density; if((side-1)%density!=0) nOIs[i]+=1; nOIs[i]=6*(nOIs[i]*(nOIs[i])); std::cout << "Allocating memory...\n"; GLuint* indices = new GLuint [nOIs[i]]; std::cout << "Done.\n"; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iBOs[i]); std::cout << "Density: " << density << " Number of indices: " << nOIs[i] << std::endl; genIndices(indices, side, density); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*nOIs[i], indices, GL_STATIC_DRAW); std::cout << "Leaving for with i: " << i << "\n"; } // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units glm::mat4 Projection = // glm::mat4(1.0f); glm::perspective(45.0f, 4.0f / 3.0f, 100.f, 30000.0f); // Camera matrix // int xVw = edges[0].first*side, yVw = edges[0].second*side; int xVw = 6000, yVw = -6000; height = 3000; glm::mat4 View = glm::lookAt( glm::vec3(xVw,yVw,2*height), // Camera is at (4,3,-3), in World Space glm::vec3(xVw,yVw,0), // and looks at the origin glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down) ); // Model matrix : an identity matrix (model will be at the origin) glm::mat4 Model = glm::mat4(1.0f); // Our ModelViewProjection : multiplication of our 3 matrices glm::mat4 MVP = Projection * View * Model; // Remember, matrix multiplication is the other way around std::cout << "Init done.\n"; glfwSetKeyCallback(Key_Callback); double last_time = glfwGetTime(), last_reset=last_time; int FPScounter=0; x = edges[0].second*12010; startx=x; y = edges[0].first*12010; starty=y; std::cout << edges[0].first << " " << edges[0].second << std::endl; do { int ex = x/12010+180; int ey = y/12010+90; //time statistics: FPScounter++; double cur_time = glfwGetTime(); if(cur_time-last_reset>=2) { double FPS = (float)FPScounter/(cur_time-last_reset); std::cout << "FPS: " << FPS << " lod: " << iBOindex << std::endl; std::cout << ex << " " << ey << " " << alpha << std::endl; if(autolod && abs(FPS-optfps)>4) { if(FPS<optfps && iBOindex<maxLoD) iBOindex++; if(FPS>4*optfps && iBOindex > 0) iBOindex--; } FPScounter=0; last_reset=cur_time; } last_time=cur_time; // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use our shader glUseProgram(programIDs[ball]); glm::mat4 Vw; // Send our transformation to the currently bound shader, // in the "MVP" uniform Vw=MVP * glm::translate( mat4(1.0),vec3((-x + 6000)*ball,(-y - 6000)*ball,(z - 12000)*ball)) * glm::rotate(mat4(1.0), oz, glm::vec3(0,1,0)) * glm::rotate(mat4(1.0), ox, glm::vec3(1,0,0)) * glm::rotate(mat4(1.0), oy, glm::vec3(0,0,1)) * glm::translate( mat4(1.0), vec3(-x*(1-ball), -y*(1-ball), z*(1-ball))); glUniformMatrix4fv(MatrixIDs[ball], 1, GL_FALSE, &Vw[0][0]); glUniform1i(HeightIDs[ball], 0); glUniform1f(TimeIDs[ball], glfwGetTime()); glUniform1f(AlphaIDs[ball], (float)alpha*0.1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex_2d); glUniform1i(TextureIDs[ball], /*GL_TEXTURE0+*/0); indexBufferObject=iBOs[iBOindex]; numberOfIndices=nOIs[iBOindex]; // std::cout << ex << " " << ey << std::endl; if(ball==0) { glCullFace(GL_FRONT); for(int i = max(ex-3,0); i<= min(ex+3,360) ; i++) for(int j=max(ey-3,0); j<= min(ey+3,180); j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; if(piece_map[i][j]==-1) { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } else { point = piece_map[i][j]; draw(vaoObjects[point], vBOs[point], indexBufferObject, numberOfIndices); } // std::cout << "Drawing " << file_names[point] << "with mods " << i-180 << " " << j-90 << std::endl // << i << " " << ex << " " << j << " " << ey << std::endl; } } else { glCullFace(GL_FRONT); for(int i=/*edges[0].second+180+*/0; i</*edges[0].second+18*/360; i++) for(int j=/*edges[0].first+90+*/0; j<=/*edges[0].first+90*/180; j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; if(piece_map[i][j]==-1) { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } else { point = piece_map[i][j]; draw(vaoObjects[point], vBOs[point], indexBufferObject, numberOfIndices); } } } //CLOUDS /* Vw=MVP * glm::translate( mat4(1.0),vec3((-x + 6000)*ball,(-y - 6000)*ball,(z - 12000)*ball)) * glm::rotate(mat4(1.0), oz+(float)glfwGetTime(), glm::vec3(0,1,0)) * glm::rotate(mat4(1.0), ox, glm::vec3(1,0,0)) * glm::rotate(mat4(1.0), oy, glm::vec3(0,0,1)) * glm::translate( mat4(1.0), vec3(-x*(1-ball), -y*(1-ball), z*(1-ball))); glUniformMatrix4fv(MatrixIDs[ball], 1, GL_FALSE, &Vw[0][0]); glUniform1i(HeightIDs[ball], 100); glUniform1f(TimeIDs[ball], glfwGetTime()); glUniform1f(AlphaIDs[ball], 0.25); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex_cl); glUniform1i(TextureIDs[ball], 0); indexBufferObject=iBOs[iBOindex]; numberOfIndices=nOIs[iBOindex]; // std::cout << ex << " " << ey << std::endl; if(ball==0) { glCullFace(GL_FRONT); for(int i = max(ex-3,0); i<= min(ex+3,360) ;i++) for(int j=max(ey-3,0); j<= min(ey+3,180); j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } } } else { glCullFace(GL_FRONT); for(int i=0; i<360;i++) for(int j=0; j<=180;j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } } }*/ // Swap buffers glfwSwapBuffers(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && glfwGetWindowParam( GLFW_OPENED ) ); // Cleanup VBO and shader glDeleteProgram(programIDs[0]); glDeleteProgram(programIDs[1]); // CleanVBOs(vaoObjects, vBOs, vBOsize+1, iBOs, tex_2d); std::cout << "Cleaning done, terminating..\n"; // Close OpenGL window and terminate GLFW glfwTerminate(); return 0; }
void ConvexClipper<Real>::Postprocess (int fNew, Face& faceNew) { const int numEdges = (int)faceNew.Edges.size(); std::vector<EdgePlus> edges(numEdges); std::set<int>::iterator iter = faceNew.Edges.begin(); std::set<int>::iterator end = faceNew.Edges.end(); int i = 0; while (iter != end) { int e = *iter++; edges[i++] = EdgePlus(e, mEdges[e]); } std::sort(edges.begin(), edges.end()); // Process duplicate edges. for (int i0 = 0, i1 = 1; i1 < numEdges; i0 = i1++) { if (edges[i0] == edges[i1]) { // Found two equivalent edges (same vertex end points). #ifdef _DEBUG int i2 = i1 + 1; if (i2 < numEdges) { // Make sure an edge occurs at most twice. If not, then // algorithm needs to be modified to handle it. assertion(edges[i1] != edges[i2], "Unexpected condition.\n"); } #endif // Edge E0 has vertices V0, V1 and faces F0, NF. Edge E1 has // vertices V0, V1 and faces F1, NF. int e0 = edges[i0].E; int e1 = edges[i1].E; Edge& edge0 = mEdges[e0]; Edge& edge1 = mEdges[e1]; // Remove E0 and E1 from faceNew. faceNew.Edges.erase(e0); faceNew.Edges.erase(e1); // Remove faceNew from E0. if (edge0.Face[0] == fNew) { edge0.Face[0] = edge0.Face[1]; } else { assertion(edge0.Face[1] == fNew, "Unexpected condition.\n"); } edge0.Face[1] = -1; // Remove faceNew from E1. if (edge1.Face[0] == fNew) { edge1.Face[0] = edge1.Face[1]; } else { assertion(edge1.Face[1] == fNew, "Unexpected condition.\n"); } edge1.Face[1] = -1; // E2 is being booted from the system. Update the face F1 that // shares it. Update E1 to share F1. int f1 = edge1.Face[0]; Face& face1 = mFaces[f1]; face1.Edges.erase(e1); face1.Edges.insert(e0); edge0.Face[1] = f1; edge1.Visible = false; } } }
void OCC_Connect::Intersect(BRep_Builder &BB, TopoDS_Shape &target, TopoDS_Shape &shape, TopoDS_Shape &tool) { /*************************************************************************** We start by splitting edges at all the edge-edge intersections. This may generate new vertices and edges. ***************************************************************************/ MergeVertices(shape,tool); LocOpe_SplitShape splitter1(shape); LocOpe_SplitShape splitter2(tool); TopOpeBRep_ShapeIntersector intersector; for(intersector.InitIntersection(shape,tool); intersector.MoreIntersection(); intersector.NextIntersection() ) { if(verbose&Cutting) { cout << "++++++++++++++++++++++++++++++++++++++++" "++++++++++++++++++++++++++++++++++++++++\n"; intersector.DumpCurrent(1); cout << " --> "; intersector.DumpCurrent(2); cout << '\n'; } TopOpeBRep_EdgesIntersector &ee=intersector.ChangeEdgesIntersector(); if( intersector.CurrentGeomShape(1).ShapeType()==TopAbs_EDGE && intersector.CurrentGeomShape(2).ShapeType()==TopAbs_EDGE ) { for(ee.InitPoint(); ee.MorePoint(); ee.NextPoint()) { TopOpeBRep_Point2d const &p=ee.Point(); if(verbose&Cutting) cout << "point loop " << p.Parameter(1) << '\n'; TopoDS_Vertex vertex; if(p.IsVertex(1)) vertex=p.Vertex(1); else if(p.IsVertex(2)) vertex=p.Vertex(2); else vertex=BRepBuilderAPI_MakeVertex(p.Value()); if(!p.IsVertex(1)) { TopoDS_Edge edge=TopoDS::Edge(ee.Edge(1)); if(!splitter1.CanSplit(edge)) { if(verbose&Cutting) cout << "Cannot split 1\n";; } else { if(verbose&Cutting) cout << "splitting model 1\n"; try { splitter1.Add(vertex,p.Parameter(1),edge); } catch(Standard_ConstructionError c) { if(verbose&Cutting) cout << "Ooops \n"; } } } if(!p.IsVertex(2)) { TopoDS_Edge edge=TopoDS::Edge(ee.Edge(2)); if(!splitter2.CanSplit(edge)) { if(verbose&Cutting) cout << "Cannot split 2\n";; } else { if(verbose&Cutting) cout << "splitting model 2\n"; try { splitter2.Add(vertex,p.Parameter(2),edge); } catch(Standard_ConstructionError c) { if(verbose&Cutting) cout << "Ooops \n"; } } } } } } /*************************************************************************** Not all intersections seem to be caught, this is an attempt to catch some missing intersections. FIXME, this is almost certainly incomplete. ***************************************************************************/ TopTools_IndexedMapOfShape edges, faces, vertices; vertices.Clear(); TopExp::MapShapes(shape,TopAbs_VERTEX,vertices); TopExp::MapShapes(tool,TopAbs_VERTEX,vertices); edges.Clear(); TopExp::MapShapes(shape,TopAbs_EDGE,edges); for(int e=1; e<=edges.Extent(); e++) { TopoDS_Edge edge=TopoDS::Edge(edges(e)); TopoDS_Vertex o1, o2; TopExp::Vertices(edge,o1,o2); int skip1=vertices.FindIndex(o1); int skip2=vertices.FindIndex(o2); for(int v=1; v<=vertices.Extent(); v++) { if(v==skip1 || v==skip2) continue; TopoDS_Vertex vertex=TopoDS::Vertex(vertices(v)); BRepExtrema_ExtPC distance(vertex,edge); if(!distance.IsDone()) continue; double tolerance=std::max(BRep_Tool::Tolerance(edge), BRep_Tool::Tolerance(vertex)); for(int i=1;i<=distance.NbExt();i++) { #if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5) double value = distance.Value(i); #else double value = distance.SquareDistance(i); #endif if(value<tolerance) { try { // No idea why this can fail splitter1.Add(vertex,distance.Parameter(i),edge); } catch(Standard_ConstructionError c) { if(verbose&Cutting) { cout << "Adding vertex to edge failed\n"; TopoDS_Vertex v1, v2; TopExp::Vertices(edge,v1,v2); if(BRepTools::Compare(v1,vertex)) cout << "Merge v1\n"; if(BRepTools::Compare(v2,vertex)) cout << "Merge v2\n"; double d1=BRep_Tool::Pnt(v1).Distance( BRep_Tool::Pnt(vertex)); double d2=BRep_Tool::Pnt(v2).Distance( BRep_Tool::Pnt(vertex)); cout << "Adding " << i << " to edge " << e << " distance=" << value << " parameter=" << distance.Parameter(i) << " point=" << distance.Point(i) << " dv1=" << d1 << " dv2=" << d2 << endl; BRepTools::Dump(vertex,cout); BRepTools::Dump(edge,cout); } } } } } } edges.Clear(); TopExp::MapShapes(tool,TopAbs_EDGE,edges); for(int e=1; e<=edges.Extent(); e++) { TopoDS_Edge edge=TopoDS::Edge(edges(e)); TopoDS_Vertex o1, o2; TopExp::Vertices(edge,o1,o2); int skip1=vertices.FindIndex(o1); int skip2=vertices.FindIndex(o2); for(int v=1; v<=vertices.Extent(); v++) { if(v==skip1 || v==skip2) continue; TopoDS_Vertex vertex=TopoDS::Vertex(vertices(v)); BRepExtrema_ExtPC distance(vertex,edge); if(!distance.IsDone()) continue; double tolerance=std::max(BRep_Tool::Tolerance(edge), BRep_Tool::Tolerance(vertex)); for(int i=1;i<=distance.NbExt();i++) { #if (OCC_VERSION_MAJOR == 6) && (OCC_VERSION_MINOR < 5) double value = distance.Value(i); #else double value = distance.SquareDistance(i); #endif if(value<tolerance) { try { splitter2.Add(vertex,distance.Parameter(i),edge); } catch(Standard_ConstructionError c) { if(verbose&Cutting) { cout << "Adding vertex to edge failed\n"; TopoDS_Vertex v1, v2; TopExp::Vertices(edge,v1,v2); if(BRepTools::Compare(v1,vertex)) cout << "Merge v1\n"; if(BRepTools::Compare(v2,vertex)) cout << "Merge v2\n"; double d1=BRep_Tool::Pnt(v1).Distance( BRep_Tool::Pnt(vertex)); double d2=BRep_Tool::Pnt(v2).Distance( BRep_Tool::Pnt(vertex)); cout << "Adding " << i << " to edge " << e << " distance=" << value << " parameter=" << distance.Parameter(i) << " point=" << distance.Point(i) << " dv1=" << d1 << " dv2=" << d2 << endl; BRepTools::Dump(vertex,cout); BRepTools::Dump(edge,cout); } } } } } } /*************************************************************************** We need the shapes with all the edge-edge intersections to split all the faces. All vertices and edges which can be merged, will be merged. ***************************************************************************/ TopoDS_Compound intermediate1; BB.MakeCompound(intermediate1); for(TopTools_ListIteratorOfListOfShape p(splitter1.DescendantShapes(shape)); p.More(); p.Next() ) { BB.Add(intermediate1,p.Value()); } TopoDS_Compound intermediate2; BB.MakeCompound(intermediate2); for(TopTools_ListIteratorOfListOfShape p(splitter2.DescendantShapes(tool)); p.More(); p.Next() ) { BB.Add(intermediate2,p.Value()); } if(verbose&Cutting) { cout << "Before merging vertices and edges\n"; TopoDS_Compound t; BB.MakeCompound(t); BB.Add(t,intermediate1); BB.Add(t,intermediate2); PrintItemCount(t); } MergeVertices(intermediate1,intermediate2); MergeEdges(intermediate1,intermediate2); if(verbose&Cutting) { cout << "After merging vertices and edges\n"; TopoDS_Compound t; BB.MakeCompound(t); BB.Add(t,intermediate1); BB.Add(t,intermediate2); PrintItemCount(t); } // Create the result TopoDS_Compound result; BB.MakeCompound(result); BB.Add(result,intermediate1); BB.Add(result,intermediate2); // Add any missing PCurves for(TopExp_Explorer face(result,TopAbs_FACE); face.More(); face.Next()) { for(TopExp_Explorer edge(face.Current(),TopAbs_EDGE); edge.More(); edge.Next() ) { Standard_Real s, e; TopoDS_Edge c_edge=TopoDS::Edge(edge.Current()); TopoDS_Face c_face=TopoDS::Face(face.Current()); Handle_Geom2d_Curve c=BRep_Tool::CurveOnSurface(c_edge,c_face,s,e); if(c.IsNull()) { if(verbose&Cutting) cout << "Adding missing PCurve\n"; ShapeFix_Edge().FixAddPCurve(c_edge,c_face,false,1e-7); } } } /*************************************************************************** We determine which edges/wires are going to cut a face. To do this we create a map of FaceCutters which is indexed by the face number in the faces map. The FaceCutters generate the correct cutting wires. ***************************************************************************/ int retry; do { if(verbose&Cutting) std::cout << "STARTED CUTTING\n"; retry=0; edges.Clear(); TopExp::MapShapes(result,TopAbs_EDGE,edges); faces.Clear(); TopExp::MapShapes(result,TopAbs_FACE,faces); cutmap_t cutters=SelectCuttingEdges(edges,faces); /*************************************************************************** Apply all face splits stored in the map. ***************************************************************************/ int cut_count=0; LocOpe_SplitShape splitter(result); for(cutmap_t::iterator f=cutters.begin(); f!=cutters.end(); f++) { TopoDS_Face const &face=TopoDS::Face(faces(f->first)); FaceCutters &cutter=f->second; cut_count+=cutter.size(); if(verbose&Cutting) { cout << "Cutting face " << f->first << " *************************\n"; BRepTools::Dump(face,cout); } cutter.Build(face,result,verbose); for(FaceCutters::iterator p=cutter.begin(); p!=cutter.end(); p++) { TopTools_IndexedMapOfShape edges; TopExp::MapShapes(*p,TopAbs_EDGE,edges); if(edges.Extent()<3 && BRep_Tool::IsClosed(*p)) { // FIXME This doesn't work. cout << "IGNORED Closed wire with less than three edges\n"; continue; } //BRepTools::Dump(*p,cout); try { splitter.Add(*p,face); } catch(Standard_ConstructionError c) { cout << "splitting the face failed\n"; retry=1; } } } if(verbose&Cutting) cout << cut_count << " cuts in " << cutters.size() << " faces\n"; // Create the final shape with the cutted faces. TopoDS_Compound cutted; BB.MakeCompound(cutted); int count=0; for(TopTools_ListIteratorOfListOfShape p(splitter.DescendantShapes(result)); p.More(); p.Next() ) { if(++count==1) { if(verbose&Cutting) { cout << "--------- " << count << " ---------------------------\n"; BRepTools::Dump(p.Value(),cout); } BB.Add(cutted,p.Value()); } } MergeFaces(cutted); result=cutted; } while(0 && retry); target=result; }
AttachmentPrivate1(const Mesh &mesh, const Skeleton &skeleton, const vector<Vector3> &match, const VisibilityTester *tester, double initialHeatWeight) { int i, j; int nv = mesh.vertices.size(); //compute edges vector<vector<int> > edges(nv); for(i = 0; i < nv; ++i) { int cur, start; cur = start = mesh.vertices[i].edge; do { edges[i].push_back(mesh.edges[cur].vertex); cur = mesh.edges[mesh.edges[cur].prev].twin; } while(cur != start); } weights.resize(nv); int bones = skeleton.fGraph().verts.size() - 1; for(i = 0; i < nv; ++i) // initialize the weights vectors so they are big enough weights[i][bones - 1] = 0.; vector<vector<double> > boneDists(nv); vector<vector<bool> > boneVis(nv); for(i = 0; i < nv; ++i) { boneDists[i].resize(bones, -1); boneVis[i].resize(bones); Vector3 cPos = mesh.vertices[i].pos; vector<Vector3> normals; for(j = 0; j < (int)edges[i].size(); ++j) { int nj = (j + 1) % edges[i].size(); Vector3 v1 = mesh.vertices[edges[i][j]].pos - cPos; Vector3 v2 = mesh.vertices[edges[i][nj]].pos - cPos; normals.push_back((v1 % v2).normalize()); } double minDist = 1e37; for(j = 1; j <= bones; ++j) { const Vector3 &v1 = match[j], &v2 = match[skeleton.fPrev()[j]]; boneDists[i][j - 1] = sqrt(distsqToSeg(cPos, v1, v2)); minDist = min(boneDists[i][j - 1], minDist); } for(j = 1; j <= bones; ++j) { //the reason we don't just pick the closest bone is so that if two are //equally close, both are factored in. if(boneDists[i][j - 1] > minDist * 1.0001) continue; const Vector3 &v1 = match[j], &v2 = match[skeleton.fPrev()[j]]; Vector3 p = projToSeg(cPos, v1, v2); boneVis[i][j - 1] = tester->canSee(cPos, p) && vectorInCone(cPos - p, normals); } } //We have -Lw+Hw=HI, same as (H-L)w=HI, with (H-L)=DA (with D=diag(1./area)) //so w = A^-1 (HI/D) vector<vector<pair<int, double> > > A(nv); vector<double> D(nv, 0.), H(nv, 0.); vector<int> closest(nv, -1); for(i = 0; i < nv; ++i) { //get areas for(j = 0; j < (int)edges[i].size(); ++j) { int nj = (j + 1) % edges[i].size(); D[i] += ((mesh.vertices[edges[i][j]].pos - mesh.vertices[i].pos) % (mesh.vertices[edges[i][nj]].pos - mesh.vertices[i].pos)).length(); } D[i] = 1. / (1e-10 + D[i]); //get bones double minDist = 1e37; for(j = 0; j < bones; ++j) { if(boneDists[i][j] < minDist && boneVis[i][j]) { closest[i] = j; minDist = boneDists[i][j]; } } for(j = 0; j < bones; ++j) if(boneVis[i][j] && boneDists[i][j] <= minDist * 1.00001) H[i] += initialHeatWeight / SQR(1e-8 + boneDists[i][closest[i]]); //get laplacian double sum = 0.; for(j = 0; j < (int)edges[i].size(); ++j) { int nj = (j + 1) % edges[i].size(); int pj = (j + edges[i].size() - 1) % edges[i].size(); Vector3 v1 = mesh.vertices[i].pos - mesh.vertices[edges[i][pj]].pos; Vector3 v2 = mesh.vertices[edges[i][j]].pos - mesh.vertices[edges[i][pj]].pos; Vector3 v3 = mesh.vertices[i].pos - mesh.vertices[edges[i][nj]].pos; Vector3 v4 = mesh.vertices[edges[i][j]].pos - mesh.vertices[edges[i][nj]].pos; double cot1 = (v1 * v2) / (1e-6 + (v1 % v2).length()); double cot2 = (v3 * v4) / (1e-6 + (v3 % v4).length()); sum += (cot1 + cot2); if(edges[i][j] > i) //check for triangular here because sum should be computed regardless continue; A[i].push_back(make_pair(edges[i][j], -cot1 - cot2)); } A[i].push_back(make_pair(i, sum + H[i] / D[i])); sort(A[i].begin(), A[i].end()); } nzweights.resize(nv); SPDMatrix Am(A); LLTMatrix *Ainv = Am.factor(); if(Ainv == NULL) return; for(j = 0; j < bones; ++j) { vector<double> rhs(nv, 0.); for(i = 0; i < nv; ++i) { if(boneVis[i][j] && boneDists[i][j] <= boneDists[i][closest[i]] * 1.00001) rhs[i] = H[i] / D[i]; } Ainv->solve(rhs); for(i = 0; i < nv; ++i) { if(rhs[i] > 1.) rhs[i] = 1.; //clip just in case if(rhs[i] > 1e-8) nzweights[i].push_back(make_pair(j, rhs[i])); } } for(i = 0; i < nv; ++i) { double sum = 0.; for(j = 0; j < (int)nzweights[i].size(); ++j) sum += nzweights[i][j].second; for(j = 0; j < (int)nzweights[i].size(); ++j) { nzweights[i][j].second /= sum; weights[i][nzweights[i][j].first] = nzweights[i][j].second; } } delete Ainv; return; }
void SoftConstrFunction2D::Evaluate(const arma::vec &x) { // Vertex coordinates: First convert control points into vertices // verCoords has the form of [x1 x2, x3... y1 y2 y3... z1 z2 z3] // We will compute Jacobian w.r.t vertex variables first, then we compute // Jacobian w.r.t actual variables using composition rules vec vertCoords = this->P * x; vec CPx; CPx.set_size(this->refEdgeLens.n_elem); int nVertVars = this->P.n_rows; // Number of vertex variables = 3 * #vertices int nVerts = nVertVars / 3; // Number of vertices int nEdges = this->refEdgeLens.n_elem; // Number of edges (#constraints) // TODO: Make Jv to be attribute of class to avoid re-allocating each evaluation // Jacobian w.r.t all vertex coordinates. Then this->J = Jv * P since x = P*c mat Jv = zeros(nEdges, nVertVars); // Iterate through all edges to compute function value and derivatives for (int i = 0; i < nEdges; i++) { // An edge has two vertices int vertID1 = edges(0, i); int vertID2 = edges(1, i); // Indices of x,y,z coordinates in the vector vertCoords [x1 x2, x3... y1 y2 y3... z1 z2 z3] int x1Idx = vertID1; int y1Idx = x1Idx + nVerts; int z1Idx = y1Idx + nVerts; int x2Idx = vertID2; int y2Idx = x2Idx + nVerts; int z2Idx = y2Idx + nVerts; // Coordinates of two vertices (x1,y1,z1) & (x2,y2,z2) double x1 = vertCoords(x1Idx); double y1 = vertCoords(y1Idx); double z1 = vertCoords(z1Idx); double x2 = vertCoords(x2Idx); double y2 = vertCoords(y2Idx); double z2 = vertCoords(z2Idx); // Edge length double edgeLen = sqrt( pow(x2-x1, 2) + pow(y2-y1, 2) + pow(z2-z1, 2) ); // Compute function value = "edge length" - "reference edge length" // 有一些存在len大于refLen的边,这不符合实际情况,因此要做constrained optimization CPx(i) = edgeLen - refEdgeLens(i); // if (edgeLen > refEdgeLens(i)) // { // std::cout << "FOUND ONE" << std::endl; // } // Compute derivatives. Recall the derivative: sqrt'(x) = 1/(2*sqrt(x)) Jv(i, x1Idx) = (x1-x2) / edgeLen; Jv(i, y1Idx) = (y1-y2) / edgeLen; Jv(i, z1Idx) = (z1-z2) / edgeLen; Jv(i, x2Idx) = (x2-x1) / edgeLen; Jv(i, y2Idx) = (y2-y1) / edgeLen; Jv(i, z2Idx) = (z2-z1) / edgeLen; } this->F = BPwAP * x; this->C = CPx; // Jacobian w.r.t actual variables using composition chain rule // mat m1 = arma::join_cols(MPwAP, Jv * P); //mat m2 = arma::join_rows(2*trans(MPwAP*x), 2 * trans(CPx)); this->J = BPwAP; this->A = Jv * P; //cout << this->J << endl; vec CPxabs = arma::abs(CPx); #if 0 cout << "Constraint function mean: " << arma::mean(CPxabs) << endl; #endif }
void planarTriconnectedGraph(Graph &G, int n, int m) { if (n < 4) n = 4; if(n % 2) ++n; // need an even number // start with K_4 completeGraph(G,4); PlanarModule pm; pm.planarEmbed(G); // nodes[0],...,nodes[i-1] is array of all nodes Array<node> nodes(n); node v; int i = 0; forall_nodes(v,G) nodes[i++] = v; // create planar triconnected 3-graph for(; i < n; ) { // pick a random node v = nodes[randomNumber(0,i-1)]; adjEntry adj2 = v->firstAdj(); int r = randomNumber(0,2); switch(r) { case 2: adj2 = adj2->succ(); // fall through to next case case 1: adj2 = adj2->succ(); } adjEntry adj1 = adj2->cyclicSucc(); nodes[i++] = G.splitNode(adj1,adj2); r = randomNumber(0,1); if(r == 0) { adjEntry adj = adj1->twin(); G.newEdge(adj2,adj); nodes[i++] = G.splitNode(adj,adj->cyclicSucc()->cyclicSucc()); } else { adjEntry adj = adj1->cyclicSucc()->twin(); G.newEdge(adj2,adj,ogdf::before); nodes[i++] = G.splitNode(adj->cyclicPred(),adj->cyclicSucc()); } } nodes.init(); Array<edge> edges(m); CombinatorialEmbedding E(G); Array<face> faces(2*n); i = 0; face f; forall_faces(f,E) { if(f->size() >= 4) faces[i++] = f; } while(G.numberOfEdges() < m && i > 0) { int r = randomNumber(0,i-1); f = faces[r]; faces[r] = faces[--i]; int p = randomNumber(0,f->size()-1); int j = 0; adjEntry adj, adj2; for(adj = f->firstAdj(); j < p; adj = adj->faceCycleSucc(), ++j) ; p = randomNumber(2, f->size()-2); for(j = 0, adj2 = adj; j < p; adj2 = adj2->faceCycleSucc(), ++j) ; edge e = E.splitFace(adj,adj2); f = E.rightFace(e->adjSource()); if(f->size() >= 4) faces[i++] = f; f = E.rightFace(e->adjTarget()); if(f->size() >= 4) faces[i++] = f; } }
Real Hex::quality (const ElemQuality q) const { switch (q) { /** * Compue the min/max diagonal ratio. * Source: CUBIT User's Manual. */ case DIAGONAL: { // Diagonal between node 0 and node 6 const Real d06 = this->length(0,6); // Diagonal between node 3 and node 5 const Real d35 = this->length(3,5); // Diagonal between node 1 and node 7 const Real d17 = this->length(1,7); // Diagonal between node 2 and node 4 const Real d24 = this->length(2,4); // Find the biggest and smallest diagonals const Real min = std::min(d06, std::min(d35, std::min(d17, d24))); const Real max = std::max(d06, std::max(d35, std::max(d17, d24))); libmesh_assert_not_equal_to (max, 0.0); return min / max; break; } /** * Minimum ratio of lengths derived from opposite edges. * Source: CUBIT User's Manual. */ case TAPER: { /** * Compute the side lengths. */ const Real d01 = this->length(0,1); const Real d12 = this->length(1,2); const Real d23 = this->length(2,3); const Real d03 = this->length(0,3); const Real d45 = this->length(4,5); const Real d56 = this->length(5,6); const Real d67 = this->length(6,7); const Real d47 = this->length(4,7); const Real d04 = this->length(0,4); const Real d15 = this->length(1,5); const Real d37 = this->length(3,7); const Real d26 = this->length(2,6); std::vector<Real> edge_ratios(12); // Front edge_ratios[0] = std::min(d01, d45) / std::max(d01, d45); edge_ratios[1] = std::min(d04, d15) / std::max(d04, d15); // Right edge_ratios[2] = std::min(d15, d26) / std::max(d15, d26); edge_ratios[3] = std::min(d12, d56) / std::max(d12, d56); // Back edge_ratios[4] = std::min(d67, d23) / std::max(d67, d23); edge_ratios[5] = std::min(d26, d37) / std::max(d26, d37); // Left edge_ratios[6] = std::min(d04, d37) / std::max(d04, d37); edge_ratios[7] = std::min(d03, d47) / std::max(d03, d47); // Bottom edge_ratios[8] = std::min(d01, d23) / std::max(d01, d23); edge_ratios[9] = std::min(d03, d12) / std::max(d03, d12); // Top edge_ratios[10] = std::min(d45, d67) / std::max(d45, d67); edge_ratios[11] = std::min(d56, d47) / std::max(d56, d47); return *(std::min_element(edge_ratios.begin(), edge_ratios.end())) ; break; } /** * Minimum edge length divided by max diagonal length. * Source: CUBIT User's Manual. */ case STRETCH: { const Real sqrt3 = 1.73205080756888; /** * Compute the maximum diagonal. */ const Real d06 = this->length(0,6); const Real d17 = this->length(1,7); const Real d35 = this->length(3,5); const Real d24 = this->length(2,4); const Real max_diag = std::max(d06, std::max(d17, std::max(d35, d24))); libmesh_assert_not_equal_to ( max_diag, 0.0 ); /** * Compute the minimum edge length. */ std::vector<Real> edges(12); edges[0] = this->length(0,1); edges[1] = this->length(1,2); edges[2] = this->length(2,3); edges[3] = this->length(0,3); edges[4] = this->length(4,5); edges[5] = this->length(5,6); edges[6] = this->length(6,7); edges[7] = this->length(4,7); edges[8] = this->length(0,4); edges[9] = this->length(1,5); edges[10] = this->length(2,6); edges[11] = this->length(3,7); const Real min_edge = *(std::min_element(edges.begin(), edges.end())); return sqrt3 * min_edge / max_diag ; break; } /** * I don't know what to do for this metric. * Maybe the base class knows... */ default: { return Elem::quality(q); } } // Will never get here... libmesh_error(); return 0.; }
void Foam::PrimitivePatch<Face, FaceList, PointField, PointType>:: calcEdgeLoops() const { if (debug) { Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::" << "calcEdgeLoops() : " << "calculating boundary edge loops" << endl; } if (edgeLoopsPtr_) { // it is considered an error to attempt to recalculate // if already allocated FatalErrorIn ( "PrimitivePatch<Face, FaceList, PointField, PointType>::" "calcEdgeLoops()" ) << "edge loops already calculated" << abort(FatalError); } const edgeList& patchEdges = edges(); label nIntEdges = nInternalEdges(); label nBdryEdges = patchEdges.size() - nIntEdges; if (nBdryEdges == 0) { edgeLoopsPtr_ = new labelListList(0); return; } const labelListList& patchPointEdges = pointEdges(); // // Walk point-edge-point and assign loop number // // Loop per (boundary) edge. labelList loopNumber(nBdryEdges, -1); // Size return list plenty big edgeLoopsPtr_ = new labelListList(nBdryEdges); labelListList& edgeLoops = *edgeLoopsPtr_; // Current loop number. label loopI = 0; while (true) { // Find edge not yet given a loop number. label currentEdgeI = -1; for (label edgeI = nIntEdges; edgeI < patchEdges.size(); edgeI++) { if (loopNumber[edgeI-nIntEdges] == -1) { currentEdgeI = edgeI; break; } } if (currentEdgeI == -1) { // Did not find edge not yet assigned a loop number so done all. break; } // Temporary storage for vertices of current loop dynamicLabelList loop(nBdryEdges); // Walk from first all the way round, assigning loops label currentVertI = patchEdges[currentEdgeI].start(); do { loop.append(currentVertI); loopNumber[currentEdgeI - nIntEdges] = loopI; // Step to next vertex currentVertI = patchEdges[currentEdgeI].otherVertex(currentVertI); // Step to next (unmarked, boundary) edge. const labelList& curEdges = patchPointEdges[currentVertI]; currentEdgeI = -1; forAll(curEdges, pI) { label edgeI = curEdges[pI]; if (edgeI >= nIntEdges && (loopNumber[edgeI - nIntEdges] == -1)) { // Unassigned boundary edge. currentEdgeI = edgeI; break; } } } while (currentEdgeI != -1); // Done all for current loop. Transfer to edgeLoops. edgeLoops[loopI].transfer(loop); loopI++; } edgeLoops.setSize(loopI); if (debug) { Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::" << "calcEdgeLoops() : " << "finished calculating boundary edge loops" << endl; } }
IfcSchema::IfcProductDefinitionShape* IfcGeom::serialise(const TopoDS_Shape& shape, bool advanced) { #ifndef USE_IFC4 advanced = false; #endif for (TopExp_Explorer exp(shape, TopAbs_COMPSOLID); exp.More();) { /// @todo CompSolids are not supported return 0; } IfcSchema::IfcRepresentation* rep = 0; IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list); // First check if there is a solid with one or more shells for (TopExp_Explorer exp(shape, TopAbs_SOLID); exp.More(); exp.Next()) { IfcSchema::IfcClosedShell* outer = 0; IfcSchema::IfcClosedShell::list::ptr inner(new IfcSchema::IfcClosedShell::list); for (TopExp_Explorer exp2(exp.Current(), TopAbs_SHELL); exp2.More(); exp2.Next()) { IfcSchema::IfcClosedShell* shell; if (!convert_to_ifc(exp2.Current(), shell, advanced)) { return 0; } /// @todo Are shells always in this order or does Orientation() needs to be checked? if (outer) { inner->push(shell); } else { outer = shell; } } #ifdef USE_IFC4 if (advanced) { if (inner->size()) { items->push(new IfcSchema::IfcAdvancedBrepWithVoids(outer, inner)); } else { items->push(new IfcSchema::IfcAdvancedBrep(outer)); } } else #endif /// @todo this is not necessarily correct as the shell is not necessarily facetted. if (inner->size()) { items->push(new IfcSchema::IfcFacetedBrepWithVoids(outer, inner)); } else { items->push(new IfcSchema::IfcFacetedBrep(outer)); } } if (items->size() > 0) { rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Body"), std::string("Brep"), items); } else { // If not, see if there is a shell IfcSchema::IfcOpenShell::list::ptr shells(new IfcSchema::IfcOpenShell::list); for (TopExp_Explorer exp(shape, TopAbs_SHELL); exp.More(); exp.Next()) { IfcSchema::IfcOpenShell* shell; if (!convert_to_ifc(exp.Current(), shell, advanced)) { return 0; } shells->push(shell); } if (shells->size() > 0) { items->push(new IfcSchema::IfcShellBasedSurfaceModel(shells->generalize())); rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Body"), std::string("Brep"), items); } else { // If not, see if there is are one of more faces. Note that they will be grouped into a shell. IfcSchema::IfcOpenShell* shell; int face_count = convert_to_ifc(shape, shell, advanced); if (face_count > 0) { items->push(shell); rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Body"), std::string("Brep"), items); } else { // If not, see if there are any edges. Note that wires are skipped as // they are not commonly top-level geometrical descriptions in IFC. // Also note that edges are written as trimmed curves rather than edges. IfcEntityList::ptr edges(new IfcEntityList); for (TopExp_Explorer exp(shape, TopAbs_EDGE); exp.More(); exp.Next()) { IfcSchema::IfcCurve* c; if (!convert_to_ifc(TopoDS::Edge(exp.Current()), c, advanced)) { return 0; } edges->push(c); } if (edges->size() == 0) { return 0; } else if (edges->size() == 1) { rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Axis"), std::string("Curve2D"), edges->as<IfcSchema::IfcRepresentationItem>()); } else { // A geometric set is created as that probably (?) makes more sense in IFC IfcSchema::IfcGeometricCurveSet* curves = new IfcSchema::IfcGeometricCurveSet(edges); items->push(curves); rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Axis"), std::string("GeometricCurveSet"), items->as<IfcSchema::IfcRepresentationItem>()); } } } } IfcSchema::IfcRepresentation::list::ptr reps(new IfcSchema::IfcRepresentation::list); reps->push(rep); return new IfcSchema::IfcProductDefinitionShape(boost::none, boost::none, reps); }
bool is_straight_line_drawing(const Graph& g, GridPositionMap drawing, VertexIndexMap ) { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t; typedef typename graph_traits<Graph>::edge_descriptor edge_t; typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t; typedef typename graph_traits<Graph>::edges_size_type e_size_t; typedef typename graph_traits<Graph>::vertices_size_type v_size_t; typedef std::size_t x_coord_t; typedef std::size_t y_coord_t; typedef boost::tuple<edge_t, x_coord_t, y_coord_t> edge_event_t; typedef typename std::vector< edge_event_t > edge_event_queue_t; typedef tuple<y_coord_t, y_coord_t, x_coord_t, x_coord_t> active_map_key_t; typedef edge_t active_map_value_t; typedef std::map< active_map_key_t, active_map_value_t > active_map_t; typedef typename active_map_t::iterator active_map_iterator_t; edge_event_queue_t edge_event_queue; active_map_t active_edges; edge_iterator_t ei, ei_end; for(tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) { edge_t e(*ei); vertex_t s(source(e,g)); vertex_t t(target(e,g)); edge_event_queue.push_back (make_tuple(e, static_cast<std::size_t>(drawing[s].x), static_cast<std::size_t>(drawing[s].y) ) ); edge_event_queue.push_back (make_tuple(e, static_cast<std::size_t>(drawing[t].x), static_cast<std::size_t>(drawing[t].y) ) ); } // Order by edge_event_queue by first, then second coordinate // (bucket_sort is a stable sort.) bucket_sort(edge_event_queue.begin(), edge_event_queue.end(), property_map_tuple_adaptor<edge_event_t, 2>() ); bucket_sort(edge_event_queue.begin(), edge_event_queue.end(), property_map_tuple_adaptor<edge_event_t, 1>() ); typedef typename edge_event_queue_t::iterator event_queue_iterator_t; event_queue_iterator_t itr_end = edge_event_queue.end(); for(event_queue_iterator_t itr = edge_event_queue.begin(); itr != itr_end; ++itr ) { edge_t e(get<0>(*itr)); vertex_t source_v(source(e,g)); vertex_t target_v(target(e,g)); if (drawing[source_v].y > drawing[target_v].y) std::swap(source_v, target_v); active_map_key_t key(get(drawing, source_v).y, get(drawing, target_v).y, get(drawing, source_v).x, get(drawing, target_v).x ); active_map_iterator_t a_itr = active_edges.find(key); if (a_itr == active_edges.end()) { active_edges[key] = e; } else { active_map_iterator_t before, after; if (a_itr == active_edges.begin()) before = active_edges.end(); else before = prior(a_itr); after = boost::next(a_itr); if (before != active_edges.end()) { edge_t f = before->second; vertex_t e_source(source(e,g)); vertex_t e_target(target(e,g)); vertex_t f_source(source(f,g)); vertex_t f_target(target(f,g)); if (intersects(drawing[e_source].x, drawing[e_source].y, drawing[e_target].x, drawing[e_target].y, drawing[f_source].x, drawing[f_source].y, drawing[f_target].x, drawing[f_target].y ) ) return false; } if (after != active_edges.end()) { edge_t f = after->second; vertex_t e_source(source(e,g)); vertex_t e_target(target(e,g)); vertex_t f_source(source(f,g)); vertex_t f_target(target(f,g)); if (intersects(drawing[e_source].x, drawing[e_source].y, drawing[e_target].x, drawing[e_target].y, drawing[f_source].x, drawing[f_source].y, drawing[f_target].x, drawing[f_target].y ) ) return false; } active_edges.erase(a_itr); } } return true; }
ribi::cmap::Edge ribi::cmap::GetFirstEdge(const ConceptMap& c) { assert(boost::num_edges(c) > 0); return GetEdge(*edges(c).first, c); }
Foam::labelList Foam::PrimitivePatch<Face, FaceList, PointField, PointType>:: meshEdges ( const edgeList& allEdges, const labelListList& cellEdges, const labelList& faceCells ) const { if (debug) { Info<< "labelList PrimitivePatch<Face, FaceList, PointField, PointType>" << "::meshEdges() : " << "calculating labels of patch edges in mesh edge list" << endl; } // get reference to the list of edges on the patch const edgeList& PatchEdges = edges(); const labelListList& EdgeFaces = edgeFaces(); // create the storage labelList meshEdges(PatchEdges.size()); register bool found = false; // get reference to the points on the patch const labelList& pp = meshPoints(); // WARNING: Remember that local edges address into local point list; // local-to-global point label translation is necessary forAll (PatchEdges, edgeI) { const edge curEdge (pp[PatchEdges[edgeI].start()], pp[PatchEdges[edgeI].end()]); found = false; // get the patch faces sharing the edge const labelList& curFaces = EdgeFaces[edgeI]; forAll (curFaces, faceI) { // get the cell next to the face label curCell = faceCells[curFaces[faceI]]; // get reference to edges on the cell const labelList& ce = cellEdges[curCell]; forAll (ce, cellEdgeI) { if (allEdges[ce[cellEdgeI]] == curEdge) { found = true; meshEdges[edgeI] = ce[cellEdgeI]; break; } } if (found) break; } }
void planarBiconnectedGraph(Graph &G, int n, int m, bool multiEdges) { if (n < 3) n = 3; if (m < n) m = n; if (m > 3*n-6) m = 3*n-6; int ke = n-3, kf = m-n; G.clear(); Array<edge> edges(m); Array<face> bigFaces(m); //random_source S; // we start with a triangle node v1 = G.newNode(), v2 = G.newNode(), v3 = G.newNode(); edges[0] = G.newEdge(v1,v2); edges[1] = G.newEdge(v2,v3); edges[2] = G.newEdge(v3,v1); CombinatorialEmbedding E(G); FaceArray<int> posBigFaces(E); int nBigFaces = 0, nEdges = 3; while(ke+kf > 0) { int p = randomNumber(1,ke+kf); if (nBigFaces == 0 || p <= ke) { edge e = edges[randomNumber(0,nEdges-1)]; face f = E.rightFace(e->adjSource()); face fr = E.rightFace(e->adjTarget()); edges[nEdges++] = E.split(e); if (f->size() == 4) { posBigFaces[f] = nBigFaces; bigFaces[nBigFaces++] = f; } if (fr->size() == 4) { posBigFaces[fr] = nBigFaces; bigFaces[nBigFaces++] = fr; } ke--; } else { int pos = randomNumber(0,nBigFaces-1); face f = bigFaces[pos]; int df = f->size(); int i = randomNumber(0,df-1), j = randomNumber(2,df-2); adjEntry adj1; for (adj1 = f->firstAdj(); i > 0; adj1 = adj1->faceCycleSucc()) i--; adjEntry adj2; for (adj2 = adj1; j > 0; adj2 = adj2->faceCycleSucc()) j--; edge e = E.splitFace(adj1,adj2); edges[nEdges++] = e; face f1 = E.rightFace(e->adjSource()); face f2 = E.rightFace(e->adjTarget()); bigFaces[pos] = f1; posBigFaces[f1] = pos; if (f2->size() >= 4) { posBigFaces[f2] = nBigFaces; bigFaces[nBigFaces++] = f2; } if (f1->size() == 3) { bigFaces[pos] = bigFaces[--nBigFaces]; } kf--; } } if (multiEdges == false) { SListPure<edge> allEdges; EdgeArray<int> minIndex(G), maxIndex(G); parallelFreeSortUndirected(G,allEdges,minIndex,maxIndex); SListConstIterator<edge> it = allEdges.begin(); edge ePrev = *it, e; for(it = ++it; it.valid(); ++it, ePrev = e) { e = *it; if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) { G.move(e, e->adjTarget()->faceCycleSucc()->twin(), ogdf::before, e->adjSource()->faceCycleSucc()->twin(), ogdf::before); } } } }
BOOST_AUTO_TEST_CASE_TEMPLATE( intint_bgl_mutable_graph_test, Graph, intint_graphtest_types ) { typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; typedef typename boost::graph_traits<Graph>::vertex_iterator VertexIter; typedef typename boost::graph_traits<Graph>::edge_descriptor Edge; typedef typename boost::graph_traits<Graph>::edge_iterator EdgeIter; typedef typename boost::graph_traits<Graph>::out_edge_iterator OutEdgeIter; typedef typename boost::graph_traits<Graph>::in_edge_iterator InEdgeIter; Graph g; Vertex v_root = Vertex(); BOOST_CHECK_NO_THROW( v_root = add_vertex(g) ); BOOST_CHECK_EQUAL( num_vertices(g), 1); BOOST_CHECK_NO_THROW( remove_vertex(v_root,g) ); BOOST_CHECK_EQUAL( num_vertices(g), 0); BOOST_CHECK_NO_THROW( v_root = add_vertex(1, g) ); g[v_root] = 1; BOOST_CHECK_EQUAL( g[v_root], 1 ); int vp_rc[] = {2,3,4,5}; int ep_rc[] = {1002,1003,1004,1005}; Vertex v_rc[4]; Edge e_rc[4]; for(int i = 0; i < 4; ++i) { BOOST_CHECK_NO_THROW( v_rc[i] = add_vertex(g) ); g[ v_rc[i] ] = vp_rc[i]; BOOST_CHECK_EQUAL( g[ v_rc[i] ], vp_rc[i] ); bool edge_added_success = false; BOOST_CHECK_NO_THROW( boost::tie(e_rc[i],edge_added_success) = add_edge(v_root, v_rc[i], g) ); BOOST_CHECK( edge_added_success ); g[ e_rc[i] ] = ep_rc[i]; BOOST_CHECK_EQUAL( g[ e_rc[i] ], ep_rc[i] ); }; BOOST_CHECK_EQUAL( num_vertices(g), 5 ); int vp_rc1c[] = {6,7,8,9}; int ep_rc1c[] = {2006,2007,2008,2009}; Vertex v_rc1c[4]; Edge e_rc1c[4]; for(std::size_t i = 0; i < 4; ++i) { BOOST_CHECK_NO_THROW( v_rc1c[i] = add_vertex(vp_rc1c[i], g) ); BOOST_CHECK_EQUAL( g[ v_rc1c[i] ], vp_rc1c[i] ); bool edge_added_success = false; BOOST_CHECK_NO_THROW( boost::tie(e_rc1c[i],edge_added_success) = add_edge(v_rc[0], v_rc1c[i], ep_rc1c[i], g) ); BOOST_CHECK( edge_added_success ); BOOST_CHECK_EQUAL( g[ e_rc1c[i] ], ep_rc1c[i] ); }; BOOST_CHECK_EQUAL( num_vertices(g), 9 ); BOOST_CHECK_EQUAL( g[v_root], 1 ); { OutEdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei,ei_end) = out_edges(v_root,g) ); std::vector<int> e_list; for(; ei != ei_end; ++ei) { if(is_edge_valid(*ei,g)) { BOOST_CHECK_EQUAL( g[*ei], (g[source(*ei,g)] * 1000 + g[target(*ei,g)]) ); e_list.push_back(g[*ei]); }; }; std::sort(e_list.begin(), e_list.end()); BOOST_CHECK_EQUAL( e_list[0], 1002); BOOST_CHECK_EQUAL( e_list[1], 1003); BOOST_CHECK_EQUAL( e_list[2], 1004); BOOST_CHECK_EQUAL( e_list[3], 1005); InEdgeIter iei, iei_end; BOOST_CHECK_NO_THROW( boost::tie(iei, iei_end) = in_edges(v_rc[0], g) ); BOOST_CHECK( iei != iei_end ); BOOST_CHECK_EQUAL( g[*iei], 1002); ++iei; BOOST_CHECK( iei == iei_end ); BOOST_CHECK_NO_THROW( boost::tie(ei,ei_end) = out_edges(v_rc[0],g) ); std::vector<int> e_list2; for(; ei != ei_end; ++ei) { if(is_edge_valid(*ei,g)) { BOOST_CHECK_EQUAL( g[*ei], (g[source(*ei,g)] * 1000 + g[target(*ei,g)]) ); e_list2.push_back(g[*ei]); }; }; std::sort(e_list2.begin(), e_list2.end()); BOOST_CHECK_EQUAL( e_list2[0], 2006); BOOST_CHECK_EQUAL( e_list2[1], 2007); BOOST_CHECK_EQUAL( e_list2[2], 2008); BOOST_CHECK_EQUAL( e_list2[3], 2009); }; int vp_rc2c[] = {10,11,12,13}; int ep_rc2c[] = {3010,3011,3012,3013}; Vertex v_rc2c[4]; Edge e_rc2c[4]; for(std::size_t i = 0; i < 4; ++i) { #ifdef RK_ENABLE_CXX0X_FEATURES BOOST_CHECK_NO_THROW( v_rc2c[i] = add_vertex(std::move(vp_rc2c[i]), g) ); #else BOOST_CHECK_NO_THROW( v_rc2c[i] = add_vertex(vp_rc2c[i], g) ); #endif bool edge_added_success = false; #ifdef RK_ENABLE_CXX0X_FEATURES BOOST_CHECK_NO_THROW( boost::tie(e_rc2c[i],edge_added_success) = add_edge(v_rc[1], v_rc2c[i], ep_rc2c[i], g) ); #else BOOST_CHECK_NO_THROW( boost::tie(e_rc2c[i],edge_added_success) = add_edge(v_rc[1], v_rc2c[i], ep_rc2c[i], g) ); #endif BOOST_CHECK( edge_added_success ); }; BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { OutEdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei,ei_end) = out_edges(v_rc[1],g) ); std::vector<int> e_list; std::vector<int> vp_list; for(; ei != ei_end; ++ei) { if(is_edge_valid(*ei,g)) { BOOST_CHECK_EQUAL( g[*ei], (g[source(*ei,g)] * 1000 + g[target(*ei,g)]) ); e_list.push_back(g[*ei]); vp_list.push_back(g[target(*ei,g)]); }; }; std::sort(e_list.begin(), e_list.end()); BOOST_CHECK_EQUAL( e_list[0], 3010); BOOST_CHECK_EQUAL( e_list[1], 3011); BOOST_CHECK_EQUAL( e_list[2], 3012); BOOST_CHECK_EQUAL( e_list[3], 3013); std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 10); BOOST_CHECK_EQUAL( vp_list[1], 11); BOOST_CHECK_EQUAL( vp_list[2], 12); BOOST_CHECK_EQUAL( vp_list[3], 13); }; BOOST_CHECK_NO_THROW( clear_vertex(v_rc[0],g) ); BOOST_CHECK_EQUAL( out_degree(v_rc[0], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc[0], g), 0 ); BOOST_CHECK_EQUAL( out_degree(v_root, g), 3 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[0], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[1], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[2], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[3], g), 0 ); BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) if( is_vertex_valid(*vi, g) ) vp_list.push_back( g[*vi] ); std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 10 ); BOOST_CHECK_EQUAL( vp_list[10], 11 ); BOOST_CHECK_EQUAL( vp_list[11], 12 ); BOOST_CHECK_EQUAL( vp_list[12], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 7 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) if( is_edge_valid(*ei, g) ) ep_list.push_back( g[*ei] ); std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3010 ); BOOST_CHECK_EQUAL( ep_list[4], 3011 ); BOOST_CHECK_EQUAL( ep_list[5], 3012 ); BOOST_CHECK_EQUAL( ep_list[6], 3013 ); }; BOOST_CHECK_NO_THROW( remove_edge(v_rc[1], v_rc2c[2], g) ); BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) { if( is_vertex_valid(*vi, g) ) { vp_list.push_back( g[*vi] ); }; }; std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 10 ); BOOST_CHECK_EQUAL( vp_list[10], 11 ); BOOST_CHECK_EQUAL( vp_list[11], 12 ); BOOST_CHECK_EQUAL( vp_list[12], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 6 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) { if( is_edge_valid(*ei, g) ) { ep_list.push_back( g[*ei] ); }; }; std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3010 ); BOOST_CHECK_EQUAL( ep_list[4], 3011 ); BOOST_CHECK_EQUAL( ep_list[5], 3013 ); }; BOOST_CHECK_NO_THROW( remove_edge(e_rc2c[3], g) ); BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) { if( is_vertex_valid(*vi, g) ) { vp_list.push_back( g[*vi] ); }; }; std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 10 ); BOOST_CHECK_EQUAL( vp_list[10], 11 ); BOOST_CHECK_EQUAL( vp_list[11], 12 ); BOOST_CHECK_EQUAL( vp_list[12], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 5 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) { if( is_edge_valid(*ei, g) ) { ep_list.push_back( g[*ei] ); }; }; std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3010 ); BOOST_CHECK_EQUAL( ep_list[4], 3011 ); }; BOOST_CHECK_NO_THROW( clear_vertex(v_rc2c[0], g) ); BOOST_CHECK_NO_THROW( remove_vertex(v_rc2c[0], g) ); BOOST_CHECK_EQUAL( num_vertices(g), 12 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) { if( is_vertex_valid(*vi, g) ) { vp_list.push_back( g[*vi] ); }; }; std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 11 ); BOOST_CHECK_EQUAL( vp_list[10], 12 ); BOOST_CHECK_EQUAL( vp_list[11], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 4 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) { if( is_edge_valid(*ei, g) ) { ep_list.push_back( g[*ei] ); }; }; std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3011 ); }; };
void planarCNBGraph(Graph &G, int n, int m, int b) { G.clear(); if (b <= 0) b = 1; if (n <= 0) n = 1; if ((m <= 0) || (m > 3*n-6)) m = 3*n-6; node cutv; G.newNode(); for (int nB=1; nB<=b; nB++){ cutv = G.chooseNode(); // set number of nodes for the current created block int actN = randomNumber(1, n); node v1 = G.newNode(); if (actN <= 1){ G.newEdge(v1, cutv); } else if (actN == 2){ node v2 = G.newNode(); G.newEdge(v1, v2); int rnd = randomNumber(1, 2); edge newE; int rnd2 = randomNumber(1, 2); if (rnd == 1){ newE = G.newEdge(v1, cutv); } else{ newE = G.newEdge(v2, cutv); } if (rnd2 == 1){ G.contract(newE); } } else{ // set number of edges for the current created block int actM; if (m > 3*actN-6) actM = randomNumber(1, 3*actN-6); else actM = randomNumber(1, m); if (actM < actN) actM = actN; int ke = actN-3, kf = actM-actN; Array<node> nodes(actN); Array<edge> edges(actM); Array<face> bigFaces(actM); // we start with a triangle node v2 = G.newNode(), v3 = G.newNode(); nodes[0] = v1; nodes[1] = v2; nodes[2] = v3; edges[0] = G.newEdge(v1,v2); edges[1] = G.newEdge(v2,v3); edges[2] = G.newEdge(v3,v1); int actInsertedNodes = 3; CombinatorialEmbedding E(G); FaceArray<int> posBigFaces(E); int nBigFaces = 0, nEdges = 3; while(ke+kf > 0) { int p = randomNumber(1,ke+kf); if (nBigFaces == 0 || p <= ke) { int eNr = randomNumber(0,nEdges-1); edge e = edges[eNr]; face f = E.rightFace(e->adjSource()); face fr = E.rightFace(e->adjTarget()); node u = e->source(); node v = e->target(); edges[nEdges++] = E.split(e); if (e->source() != v && e->source() != u) nodes[actInsertedNodes++] = e->source(); else nodes[actInsertedNodes++] = e->target(); if (f->size() == 4) { posBigFaces[f] = nBigFaces; bigFaces[nBigFaces++] = f; } if (fr->size() == 4) { posBigFaces[fr] = nBigFaces; bigFaces[nBigFaces++] = fr; } ke--; } else { int pos = randomNumber(0,nBigFaces-1); face f = bigFaces[pos]; int df = f->size(); int i = randomNumber(0,df-1), j = randomNumber(2,df-2); adjEntry adj1; for (adj1 = f->firstAdj(); i > 0; adj1 = adj1->faceCycleSucc()) i--; adjEntry adj2; for (adj2 = adj1; j > 0; adj2 = adj2->faceCycleSucc()) j--; edge e = E.splitFace(adj1,adj2); edges[nEdges++] = e; face f1 = E.rightFace(e->adjSource()); face f2 = E.rightFace(e->adjTarget()); bigFaces[pos] = f1; posBigFaces[f1] = pos; if (f2->size() >= 4) { posBigFaces[f2] = nBigFaces; bigFaces[nBigFaces++] = f2; } if (f1->size() == 3) { bigFaces[pos] = bigFaces[--nBigFaces]; } kf--; } } // delete multi edges SListPure<edge> allEdges; EdgeArray<int> minIndex(G), maxIndex(G); parallelFreeSortUndirected(G,allEdges,minIndex,maxIndex); SListConstIterator<edge> it = allEdges.begin(); edge ePrev = *it, e; for(it = ++it; it.valid(); ++it, ePrev = e) { e = *it; if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) { G.move(e, e->adjTarget()->faceCycleSucc()->twin(), ogdf::before, e->adjSource()->faceCycleSucc()->twin(), ogdf::before); } } node cutv2 = nodes[randomNumber(0,actN-1)]; int rnd = randomNumber(1,2); edge newE = G.newEdge(cutv2, cutv); if (rnd == 1){ G.contract(newE); } } } };
void OCC_Connect::MergeFaces(TopoDS_Shape &shape) const { /*************************************************************************** We must find faces which are the same. Since all edges are already merged, we know that faces which can be merged have identical edges. ***************************************************************************/ TopTools_IndexedMapOfShape faces, edges; TopExp::MapShapes(shape,TopAbs_FACE,faces); TopExp::MapShapes(shape,TopAbs_EDGE,edges); mapping_t mapping; for(int i=0;i<faces.Extent();i++) { std::set<int> face_edges; for(TopExp_Explorer p(faces(i+1),TopAbs_EDGE); p.More(); p.Next()) { int edge=edges.FindIndex(p.Current()); if(BRep_Tool::Degenerated(TopoDS::Edge(edges(edge)))) { cout << "Degenerate edge " << edge << " inserted a 0\n"; face_edges.insert(0); } else face_edges.insert(edge); } mapping[face_edges].insert(i+1); } if(verbose&Cutting) { for(mapping_t::iterator p=mapping.begin(); p!=mapping.end(); p++) cout << "edges [ " << p->first << "] in face" << (p->second.size()<2? " ":"s ") << "[ " << p->second << "]\n"; } /*************************************************************************** If two faces have an identical set of edges, they can be merged when the planes are never seperated by more than the tolerance. ***************************************************************************/ BRepTools_ReShape replacer; for(mapping_t::iterator p=mapping.begin(); p!=mapping.end(); p++) { if(p->second.size()<2) continue; std::vector<int> uniq; for(std::set<int>::iterator q=p->second.begin(); q!=p->second.end(); q++ ) { for(std::vector<int>::iterator r=uniq.begin(); r!=uniq.end(); r++) { TopoDS_Face orig=TopoDS::Face(faces(*q)); TopoDS_Face repl=TopoDS::Face(faces(*r)); if(verbose&Cutting) cout << "Check face " << *q << " and " << *r << endl; if(CanMergeFace(orig,repl)) { if(verbose&Cutting) { cout << "replace face " << *q << " with " << *r << '\n'; } repl.Orientation(orig.Orientation()); replacer.Replace(orig,repl); // FIXME, tolerance should be updated goto skip; } } uniq.push_back(*q); skip:; } } TopoDS_Shape t=shape; shape=replacer.Apply(t); }
void write_graphviz_subgraph (std::ostream& out, const subgraph<Graph_>& g, RandomAccessIterator vertex_marker, RandomAccessIterator edge_marker) { typedef subgraph<Graph_> Graph; typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; typedef typename boost::graph_traits<Graph>::directed_category cat_type; typedef graphviz_io_traits<cat_type> Traits; typedef typename graph_property<Graph, graph_name_t>::type NameType; const NameType& g_name = get_property(g, graph_name); if ( g.is_root() ) out << Traits::name() ; else out << "subgraph"; out << " " << g_name << " {" << std::endl; typename Graph::const_children_iterator i_child, j_child; //print graph/node/edge attributes #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 typedef typename graph_property<Graph, graph_graph_attribute_t>::type GAttrMap; typedef typename graph_property<Graph, graph_vertex_attribute_t>::type NAttrMap; typedef typename graph_property<Graph, graph_edge_attribute_t>::type EAttrMap; GAttrMap gam = get_property(g, graph_graph_attribute); NAttrMap nam = get_property(g, graph_vertex_attribute); EAttrMap eam = get_property(g, graph_edge_attribute); graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam); writer(out); #else make_graph_attributes_writer(g)(out); #endif //print subgraph for ( boost::tie(i_child,j_child) = g.children(); i_child != j_child; ++i_child ) write_graphviz_subgraph(out, *i_child, vertex_marker, edge_marker); // Print out vertices and edges not in the subgraphs. typename boost::graph_traits<Graph>::vertex_iterator i, end; typename boost::graph_traits<Graph>::edge_iterator ei, edge_end; typename property_map<Graph, vertex_index_t>::const_type indexmap = get(vertex_index, g.root()); for(boost::tie(i,end) = boost::vertices(g); i != end; ++i) { Vertex v = g.local_to_global(*i); int pos = get(indexmap, v); if ( vertex_marker[pos] ) { vertex_marker[pos] = false; out << v; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 typedef typename property_map<Graph, vertex_attribute_t>::const_type VertexAttributeMap; attributes_writer<VertexAttributeMap> vawriter(get(vertex_attribute, g.root())); vawriter(out, v); #else make_vertex_attributes_writer(g.root())(out, v); #endif out << ";" << std::endl; } } for (boost::tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) { Vertex u = g.local_to_global(source(*ei,g)), v = g.local_to_global(target(*ei, g)); int pos = get(get(edge_index, g.root()), g.local_to_global(*ei)); if ( edge_marker[pos] ) { edge_marker[pos] = false; out << u << " " << Traits::delimiter() << " " << v; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 typedef typename property_map<Graph, edge_attribute_t>::const_type EdgeAttributeMap; attributes_writer<EdgeAttributeMap> eawriter(get(edge_attribute, g)); eawriter(out, *ei); #else make_edge_attributes_writer(g)(out, *ei); //print edge properties #endif out << ";" << std::endl; } } out << "}" << std::endl; }
void Cone_spanners_ipelet::protected_run(int fn) { std::vector<Point_2> lst; int number_of_cones; switch (fn){ case 0: case 1: case 2: case 3: case 4: case 5: case 6: { std::vector<Point_2> points_read; read_active_objects( CGAL::dispatch_or_drop_output<Point_2>(std::back_inserter(points_read)) ); if (points_read.empty()) { print_error_message("No mark selected"); return; } for(std::vector<Point_2>::iterator it = points_read.begin(); it != points_read.end(); it++) { if(std::find(points_read.begin(), it, *it) == it) { lst.push_back(*it); } } int ret_val; boost::tie(ret_val,number_of_cones)=request_value_from_user<int>("Enter the number of cones"); if (ret_val < 0) { print_error_message("Incorrect value"); return; } if(number_of_cones < 2) { print_error_message("The number of cones must be larger than 1!"); return; } break; } case 7: show_help(); return; } if(fn >= 0 && fn <= 5) { CGAL::Cones_selected cones_selected = CGAL::ALL_CONES; if(fn == 2 || fn == 3) cones_selected = CGAL::EVEN_CONES; else if(fn == 4 || fn == 5) cones_selected = CGAL::ODD_CONES; Graph g; switch (fn){ case 0: case 2: case 4: { CGAL::Construct_theta_graph_2<Kernel, Graph> theta(number_of_cones, Direction_2(1,0), cones_selected); theta(lst.begin(), lst.end(), g); break; } case 1: case 3: case 5: { CGAL::Construct_yao_graph_2<Kernel, Graph> yao(number_of_cones, Direction_2(1,0), cones_selected); yao(lst.begin(), lst.end(), g); break; } } boost::graph_traits<Graph>::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { boost::graph_traits<Graph>::edge_descriptor e = *ei; boost::graph_traits<Graph>::vertex_descriptor u = source(e, g); boost::graph_traits<Graph>::vertex_descriptor v = target(e, g); draw_in_ipe(Segment_2(g[u], g[v])); } group_selected_objects_(); } else if(fn == 6) { CGAL::Compute_cone_boundaries_2<Kernel> cones; std::vector<Direction_2> directions(number_of_cones); cones(number_of_cones, Direction_2(1,0), directions.begin()); for(std::vector<Point_2>::iterator it = lst.begin(); it != lst.end(); it++) { for(std::vector<Direction_2>::iterator dir = directions.begin(); dir != directions.end(); dir++) { draw_in_ipe(Segment_2(*it,*it + 100*dir->to_vector())); } group_selected_objects_(); get_IpePage()->deselectAll(); } } }
bool rcBuildPolyMeshDetail(const rcPolyMesh& mesh, const rcCompactHeightfield& chf, const float sampleDist, const float sampleMaxError, rcPolyMeshDetail& dmesh) { rcTimeVal startTime = rcGetPerformanceTimer(); if (mesh.nverts == 0 || mesh.npolys == 0) return true; const int nvp = mesh.nvp; const float cs = mesh.cs; const float ch = mesh.ch; const float* orig = mesh.bmin; rcIntArray edges(64); rcIntArray tris(512); rcIntArray stack(512); rcIntArray samples(512); float verts[256*3]; rcHeightPatch hp; int nPolyVerts = 0; int maxhw = 0, maxhh = 0; rcScopedDelete<int> bounds = new int[mesh.npolys*4]; if (!bounds) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'bounds' (%d).", mesh.npolys*4); return false; } rcScopedDelete<float> poly = new float[nvp*3]; if (!poly) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'poly' (%d).", nvp*3); return false; } // Find max size for a polygon area. for (int i = 0; i < mesh.npolys; ++i) { const unsigned short* p = &mesh.polys[i*nvp*2]; int& xmin = bounds[i*4+0]; int& xmax = bounds[i*4+1]; int& ymin = bounds[i*4+2]; int& ymax = bounds[i*4+3]; xmin = chf.width; xmax = 0; ymin = chf.height; ymax = 0; for (int j = 0; j < nvp; ++j) { if (p[j] == RC_MESH_NULL_IDX) break; const unsigned short* v = &mesh.verts[p[j]*3]; xmin = rcMin(xmin, (int)v[0]); xmax = rcMax(xmax, (int)v[0]); ymin = rcMin(ymin, (int)v[2]); ymax = rcMax(ymax, (int)v[2]); nPolyVerts++; } xmin = rcMax(0,xmin-1); xmax = rcMin(chf.width,xmax+1); ymin = rcMax(0,ymin-1); ymax = rcMin(chf.height,ymax+1); if (xmin >= xmax || ymin >= ymax) continue; maxhw = rcMax(maxhw, xmax-xmin); maxhh = rcMax(maxhh, ymax-ymin); } hp.data = new unsigned short[maxhw*maxhh]; if (!hp.data) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'hp.data' (%d).", maxhw*maxhh); return false; } dmesh.nmeshes = mesh.npolys; dmesh.nverts = 0; dmesh.ntris = 0; dmesh.meshes = new unsigned short[dmesh.nmeshes*4]; if (!dmesh.meshes) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4); return false; } int vcap = nPolyVerts+nPolyVerts/2; int tcap = vcap*2; dmesh.nverts = 0; dmesh.verts = new float[vcap*3]; if (!dmesh.verts) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", vcap*3); return false; } dmesh.ntris = 0; dmesh.tris = new unsigned char[tcap*4]; if (!dmesh.tris) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4); return false; } for (int i = 0; i < mesh.npolys; ++i) { const unsigned short* p = &mesh.polys[i*nvp*2]; // Store polygon vertices for processing. int npoly = 0; for (int j = 0; j < nvp; ++j) { if (p[j] == RC_MESH_NULL_IDX) break; const unsigned short* v = &mesh.verts[p[j]*3]; poly[j*3+0] = v[0]*cs; poly[j*3+1] = v[1]*ch; poly[j*3+2] = v[2]*cs; npoly++; } // Get the height data from the area of the polygon. hp.xmin = bounds[i*4+0]; hp.ymin = bounds[i*4+2]; hp.width = bounds[i*4+1]-bounds[i*4+0]; hp.height = bounds[i*4+3]-bounds[i*4+2]; getHeightData(chf, p, npoly, mesh.verts, hp, stack); // Build detail mesh. int nverts = 0; if (!buildPolyDetail(poly, npoly, sampleDist, sampleMaxError, chf, hp, verts, nverts, tris, edges, samples)) { return false; } // Move detail verts to world space. for (int j = 0; j < nverts; ++j) { verts[j*3+0] += orig[0]; verts[j*3+1] += orig[1] + chf.ch; // Is this offset necessary? verts[j*3+2] += orig[2]; } // Offset poly too, will be used to flag checking. for (int j = 0; j < npoly; ++j) { poly[j*3+0] += orig[0]; poly[j*3+1] += orig[1]; poly[j*3+2] += orig[2]; } // Store detail submesh. const int ntris = tris.size()/4; dmesh.meshes[i*4+0] = dmesh.nverts; dmesh.meshes[i*4+1] = (unsigned short)nverts; dmesh.meshes[i*4+2] = dmesh.ntris; dmesh.meshes[i*4+3] = (unsigned short)ntris; // Store vertices, allocate more memory if necessary. if (dmesh.nverts+nverts > vcap) { while (dmesh.nverts+nverts > vcap) vcap += 256; float* newv = new float[vcap*3]; if (!newv) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newv' (%d).", vcap*3); return false; } if (dmesh.nverts) memcpy(newv, dmesh.verts, sizeof(float)*3*dmesh.nverts); delete [] dmesh.verts; dmesh.verts = newv; } for (int j = 0; j < nverts; ++j) { dmesh.verts[dmesh.nverts*3+0] = verts[j*3+0]; dmesh.verts[dmesh.nverts*3+1] = verts[j*3+1]; dmesh.verts[dmesh.nverts*3+2] = verts[j*3+2]; dmesh.nverts++; } // Store triangles, allocate more memory if necessary. if (dmesh.ntris+ntris > tcap) { while (dmesh.ntris+ntris > tcap) tcap += 256; unsigned char* newt = new unsigned char[tcap*4]; if (!newt) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newt' (%d).", tcap*4); return false; } if (dmesh.ntris) memcpy(newt, dmesh.tris, sizeof(unsigned char)*4*dmesh.ntris); delete [] dmesh.tris; dmesh.tris = newt; } for (int j = 0; j < ntris; ++j) { const int* t = &tris[j*4]; dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0]; dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[1]; dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[2]; dmesh.tris[dmesh.ntris*4+3] = getTriFlags(&verts[t[0]*3], &verts[t[1]*3], &verts[t[2]*3], poly, npoly); dmesh.ntris++; } } rcTimeVal endTime = rcGetPerformanceTimer(); if (rcGetBuildTimes()) rcGetBuildTimes()->buildDetailMesh += rcGetDeltaTimeUsec(startTime, endTime); return true; }
// Main execute funcion--------------------------------------------------------------------------------- vector<FP> QrDetectorMod::find() { Mat gray = Mat(image.rows, image.cols, CV_8UC1); Mat edges(image.size(), CV_MAKETYPE(image.depth(), 1)); cvtColor(image, gray, CV_BGR2GRAY); Canny(gray, edges, 100, 200, 3); //imshow("edges", edges); vector<vector<Point>> contours; vector<Point> approx; //findContours(edges, contours, RETR_LIST, CHAIN_APPROX_NONE); uchar** arr = matToArr(edges); /* trik use pointers for images*/ findContours_(arr, &contours); /*for (int i = 0; i < contours.size() - 1; i++){ vector<Point> fst = contours[i]; for (int j = i + 1; j < contours.size() - 1; j++){ vector<Point> scd = contours[j]; double endbeg = dist(fst[fst.size() - 1], scd[0]); double endend = dist(fst[fst.size() - 1], scd[scd.size() - 1]); double begbeg = dist(fst[0], scd[0]); double begend = dist(fst[0], scd[scd.size() - 1]); if (endbeg < 2){ fst.insert(fst.end(), scd.begin(), scd.end()); contours[i] = fst; contours.erase(contours.begin() + j); } if (begbeg < 2){ reverse(fst.begin(), fst.end()); fst.insert(fst.end(), scd.begin(), scd.end()); contours[i] = fst; contours.erase(contours.begin() + j); } else if (endend < 2){ fst.insert(fst.end(), scd.begin(), scd.end()); contours[i] = fst; contours.erase(contours.begin() + j); } else if (begend < 2){ scd.insert(scd.end(), fst.begin(), fst.end()); contours[j] = scd; contours.erase(contours.begin() + i); } } }*/ /*RNG rng(12345); for each (vector<Point> c in contours){ Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); for each(Point p in c) circle(image, p, 1, color, -1); }*/ for (int i = 0; i < contours.size(); i++) { approx = approximate(contours[i]); //for each (Point p in approx) circle(image, Point(p.x, p.y), 1, Scalar(0, 0, 255), -1); // for degug if (approx.size() == 4){ //drawContours(image, contours, i, Scalar(255, 0, 0), CV_FILLED); //for debug if (isQuad(&approx) && abs(area(approx)) > 10){ if (!inOtherContour(&approx)){ quadList.push_back(vector<Point>(approx)); } } } } if (quadList.size() < 2){ return vector<FP>(); } vector<FP> fps; for each(vector<Point> quad in quadList){ Point min = minCoord(quad); Point max = maxCoord(quad); int x = min.x - 0.7*(max.x - min.x), y = min.y - 0.7*(max.y - min.y); if (x < 0) x = 0; if (y < 0) y = 0; int w = 2.8 * (max.x - min.x), h = 2.8 * (max.y - min.y); if (h > 0.7*image.rows || w > 0.7*image.cols) continue; if (x + w > gray.cols) w = gray.cols - x - 1; if (h + y > gray.rows) h = gray.rows - y - 1; Mat partImg = gray(Rect(x, y, w, h)); threshold(partImg, partImg, 128, 255, THRESH_OTSU); int dif = quad[4].y - y; if (dif >= h || dif <= 0) continue; if (singleHorizontalCheck(partImg, dif)) { fps.push_back(FP(quad[4].x, quad[4].y, module)); } else { if (fullHorizontalCheck(partImg)) { fps.push_back(FP(quad[4].x, quad[4].y, module)); } } //imshow("Parts", partImg);//for debug //waitKey(1200);//for debug }
typename graph_traits<VertexListGraph>::degree_size_type edge_connectivity(VertexListGraph& g, OutputIterator disconnecting_set) { //------------------------------------------------------------------------- // Type Definitions typedef graph_traits<VertexListGraph> Traits; typedef typename Traits::vertex_iterator vertex_iterator; typedef typename Traits::edge_iterator edge_iterator; typedef typename Traits::out_edge_iterator out_edge_iterator; typedef typename Traits::vertex_descriptor vertex_descriptor; typedef typename Traits::degree_size_type degree_size_type; typedef color_traits<default_color_type> Color; typedef adjacency_list_traits<vecS, vecS, directedS> Tr; typedef typename Tr::edge_descriptor Tr_edge_desc; typedef adjacency_list<vecS, vecS, directedS, no_property, property<edge_capacity_t, degree_size_type, property<edge_residual_capacity_t, degree_size_type, property<edge_reverse_t, Tr_edge_desc> > > > FlowGraph; typedef typename graph_traits<FlowGraph>::edge_descriptor edge_descriptor; //------------------------------------------------------------------------- // Variable Declarations vertex_descriptor u, v, p, k; edge_descriptor e1, e2; bool inserted; vertex_iterator vi, vi_end; edge_iterator ei, ei_end; degree_size_type delta, alpha_star, alpha_S_k; std::set<vertex_descriptor> S, neighbor_S; std::vector<vertex_descriptor> S_star, non_neighbor_S; std::vector<default_color_type> color(num_vertices(g)); std::vector<edge_descriptor> pred(num_vertices(g)); //------------------------------------------------------------------------- // Create a network flow graph out of the undirected graph FlowGraph flow_g(num_vertices(g)); typename property_map<FlowGraph, edge_capacity_t>::type cap = get(edge_capacity, flow_g); typename property_map<FlowGraph, edge_residual_capacity_t>::type res_cap = get(edge_residual_capacity, flow_g); typename property_map<FlowGraph, edge_reverse_t>::type rev_edge = get(edge_reverse, flow_g); for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { u = source(*ei, g), v = target(*ei, g); tie(e1, inserted) = add_edge(u, v, flow_g); cap[e1] = 1; tie(e2, inserted) = add_edge(v, u, flow_g); cap[e2] = 1; // not sure about this rev_edge[e1] = e2; rev_edge[e2] = e1; } //------------------------------------------------------------------------- // The Algorithm tie(p, delta) = detail::min_degree_vertex(g); S_star.push_back(p); alpha_star = delta; S.insert(p); neighbor_S.insert(p); detail::neighbors(g, S.begin(), S.end(), std::inserter(neighbor_S, neighbor_S.begin())); std::set_difference(vertices(g).first, vertices(g).second, neighbor_S.begin(), neighbor_S.end(), std::back_inserter(non_neighbor_S)); while (!non_neighbor_S.empty()) { // at most n - 1 times k = non_neighbor_S.front(); alpha_S_k = edmunds_karp_max_flow (flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); if (alpha_S_k < alpha_star) { alpha_star = alpha_S_k; S_star.clear(); for (tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) if (color[*vi] != Color::white()) S_star.push_back(*vi); } S.insert(k); neighbor_S.insert(k); detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); non_neighbor_S.clear(); std::set_difference(vertices(g).first, vertices(g).second, neighbor_S.begin(), neighbor_S.end(), std::back_inserter(non_neighbor_S)); } //------------------------------------------------------------------------- // Compute edges of the cut [S*, ~S*] std::vector<bool> in_S_star(num_vertices(g), false); typename std::vector<vertex_descriptor>::iterator si; for (si = S_star.begin(); si != S_star.end(); ++si) in_S_star[*si] = true; degree_size_type c = 0; for (si = S_star.begin(); si != S_star.end(); ++si) { out_edge_iterator ei, ei_end; for (tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) if (!in_S_star[target(*ei, g)]) { *disconnecting_set++ = *ei; ++c; } } return c; }
int main() { cv::Mat imCalibColor; cv::Mat imCalibGray; cv::vector<cv::vector<cv::Point> > contours; cv::vector<cv::Vec4i> hierarchy; cv::vector<cv::Point2f> pointQR; cv::Mat imCalibNext; cv::Mat imQR; cv::vector<cv::Mat> tabQR; /*cv::vector<cv::Point2f> corners1; cv::vector<cv::Point2f> corners2; cv::vector<cv::Point2f> corners3; cv::vector<cv::Point2f> corners4; cv::vector<cv::Point2f> corners5;*/ double qualityLevel = 0.01; double minDistance = 10; int blockSize = 3; bool useHarrisDetector = false; double k = 0.04; int maxCorners = 600; int A = 0, B= 0, C= 0; char key; int mark; bool patternFound = false; cv::VideoCapture vcap("../rsc/capture2.avi"); for (int i = 1; i < 5; i++) { std::ostringstream oss; oss << "../rsc/QrCodes/QR" << i << ".jpg"; imQR = cv::imread(oss.str()); cv::cvtColor(imQR, imQR, CV_BGR2GRAY); std::cout<< "Bouh!!!!!!" << std::endl; tabQR.push_back(imQR); } do { while(imCalibColor.empty()) { vcap >> imCalibColor; } vcap >> imCalibColor; cv::Mat edges(imCalibColor.size(),CV_MAKETYPE(imCalibColor.depth(), 1)); cv::cvtColor(imCalibColor, imCalibGray, CV_BGR2GRAY); Canny(imCalibGray, edges, 100 , 200, 3); cv::findContours( edges, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); cv::imshow("pointInteret", imCalibColor); mark = 0; cv::vector<cv::Moments> mu(contours.size()); cv::vector<cv::Point2f> mc(contours.size()); for( int i = 0; i < contours.size(); i++ ) { mu[i] = moments( contours[i], false ); mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); } for( int i = 0; i < contours.size(); i++ ) { int k=i; int c=0; while(hierarchy[k][2] != -1) { k = hierarchy[k][2] ; c = c+1; } if(hierarchy[k][2] != -1) c = c+1; if (c >= 5) { if (mark == 0) A = i; else if (mark == 1) B = i; // i.e., A is already found, assign current contour to B else if (mark == 2) C = i; // i.e., A and B are already found, assign current contour to C mark = mark + 1 ; } } if (A !=0 && B !=0 && C!=0) { cv::Mat imagecropped = imCalibColor; cv::Rect ROI(280/*pointQR[0].x*/, 260/*pointQR[0].y*/, 253, 218); cv::Mat croppedRef(imagecropped, ROI); cv::cvtColor(croppedRef, imagecropped, CV_BGR2GRAY); cv::threshold(imagecropped, imagecropped, 180, 255, CV_THRESH_BINARY); pointQR.push_back(mc[A]); cv::circle(imCalibColor, cv::Point(pointQR[0].x, pointQR[0].y), 3, cv::Scalar(0, 0, 255), 1, 8, 0); pointQR.push_back(mc[B]); cv::circle(imCalibColor, cv::Point(pointQR[1].x, pointQR[1].y), 3, cv::Scalar(0, 0, 255), 1, 8, 0); pointQR.push_back(mc[C]); cv::circle(imCalibColor, cv::Point(pointQR[2].x, pointQR[2].y), 3, cv::Scalar(0, 0, 255), 1, 8, 0); cv::Point2f D(0.0f,0.0f); cv::Point2f E(0.0f,0.0f); cv::Point2f F(0.0f,0.0f); D.x = (mc[A].x + mc[B].x)/2; E.x = (mc[B].x + mc[C].x)/2; F.x = (mc[C].x + mc[A].x)/2; D.y = (mc[A].y + mc[B].y)/2; E.y = (mc[B].y + mc[C].y)/2; F.y = (mc[C].y + mc[A].y)/2; pointQR.push_back(D); cv::circle(imCalibColor, cv::Point(pointQR[3].x, pointQR[3].y), 3, cv::Scalar(0, 0, 255), 1, 8, 0); pointQR.push_back(E); cv::circle(imCalibColor, cv::Point(pointQR[4].x, pointQR[4].y), 3, cv::Scalar(0, 0, 255), 1, 8, 0); pointQR.push_back(F); cv::circle(imCalibColor, cv::Point(pointQR[5].x, pointQR[5].y), 3, cv::Scalar(0, 0, 255), 1, 8, 0); patternFound = true; std::cout << "patternfound" << std::endl; cv::SiftFeatureDetector detector; cv::vector<cv::KeyPoint> keypoints1, keypoints2; detector.detect(tabQR[3], keypoints1); detector.detect(imagecropped, keypoints2); cv::Ptr<cv::DescriptorExtractor> descriptor = cv::DescriptorExtractor::create("SIFT"); cv::Mat descriptors1, descriptors2; descriptor->compute(tabQR[3], keypoints1, descriptors1 ); descriptor->compute(imagecropped, keypoints2, descriptors2 ); cv::FlannBasedMatcher matcher; std::vector< cv::DMatch > matches; matcher.match( descriptors1, descriptors2, matches ); double max_dist = 0; double min_dist = 100; for( int i = 0; i < descriptors1.rows; i++ ) { double dist = matches[i].distance; if( dist < min_dist ) min_dist = dist; if( dist > max_dist ) max_dist = dist; } std::vector< cv::DMatch > good_matches; for( int i = 0; i < descriptors1.rows; i++ ) if( matches[i].distance <= 2*min_dist ) good_matches.push_back( matches[i]); cv::Mat imgout; drawMatches(tabQR[3], keypoints1, imagecropped, keypoints2, good_matches, imgout); std::vector<cv::Point2f> pt_img1; std::vector<cv::Point2f> pt_img2; for( int i = 0; i < (int)good_matches.size(); i++ ) { pt_img1.push_back(keypoints1[ good_matches[i].queryIdx ].pt ); pt_img2.push_back(keypoints2[ good_matches[i].trainIdx ].pt ); } cv::Mat H = findHomography( pt_img1, pt_img2, CV_RANSAC ); cv::Mat result; warpPerspective(tabQR[3],result,H,cv::Size(tabQR[3].cols+imagecropped.cols,tabQR[3].rows)); cv::Mat half(result,cv::Rect(0,0,imagecropped.cols,imagecropped.rows)); imagecropped.copyTo(half); imshow( "Result", result ); break; } key = (char)cv::waitKey(67); }while(patternFound != true && key != 27); if(patternFound) imCalibNext = imCalibColor; return patternFound; }
void Foam::edgeMesh::writeStats(Ostream& os) const { os << "points : " << points().size() << nl; os << "edges : " << edges().size() << nl; os << "boundingBox : " << boundBox(this->points()) << endl; }
std::vector<comVec3> cycleSearch( std::vector<comVec3>& lines){ if (lines.size()==0){ return lines; } //2 pts in the lines vector gives an edge std::vector<comVec3>::iterator lit; std::vector<comVec3> cycles; std::set<comVec3> vertices; vertices.insert(lines.begin(), lines.end()); std::vector<comVec3> v_vertices; std::vector<comVec3>::iterator vit = v_vertices.begin(); vit = v_vertices.insert(vit, vertices.begin(), vertices.end()); std::vector<int> edges (lines.size(), 0); std::vector<comVec3> cycle; for (int j=0; j<(int)v_vertices.size(); j++){ for (int i=0; i<(int)lines.size(); i++){ if (lines[i]==v_vertices[j]){ edges[i]=j; //std::cout<<"hello"; } } } /*//cout edges for (int i=0; i<(int)lines.size(); i++){ std::cout<<edges[i]<<" "<<glm::to_string(lines[i].content)<<std::endl; }*/ std::stack<int> stacky; std::stack<int> history; std::stack<int> previouses; stacky.push(edges[0]); history.push(-1); history.push(edges[0]); //DFS std::vector<bool> visited(vertices.size(), false); int previous = -1; int current = -1; while(stacky.size()!=0){ previous = current; current = stacky.top(); stacky.pop(); /*//cout stacky and history std::cout<<"stacky: "; std::stack<int> temp; while (stacky.size()!=0){ std::cout<<stacky.top(); temp.push(stacky.top()); stacky.pop(); } while (temp.size()!=0){ stacky.push(temp.top()); temp.pop(); } std::cout<<std::endl; std::cout<<"history: "; while (history.size()!=0){ std::cout<<history.top(); temp.push(history.top()); history.pop(); } while (temp.size()!=0){ history.push(temp.top()); temp.pop(); } std::cout<<std::endl;*/ if (visited[current]){ std::vector<int> cyc= cyc_found(history, current, previous); std::vector<int>::iterator cit; int i = history.top(); history.pop(); while (i!= -1){ visited[i] = false; i = history.top(); history.pop(); previouses.pop(); } for (cit=cyc.begin(); cit!=cyc.end(); cit++){ cycle.push_back(v_vertices[*cit]); } } else{ visited[current] = true; if (!adjacent(edges, stacky, history, previouses, current, previous)){ int i = history.top(); history.pop(); while (i!= -1){ visited[i] = false; i = history.top(); history.pop(); previouses.pop(); } } } } return cycle; }
const std::vector<AlnNode> AlnGraphBoost::bestPath() { EdgeIter ei, ee; for (boost::tie(ei, ee) = edges(_g); ei != ee; ++ei) _g[*ei].visited = false; std::map<VtxDesc, EdgeDesc> bestNodeScoreEdge; std::map<VtxDesc, float> nodeScore; std::queue<VtxDesc> seedNodes; // start at the end and make our way backwards seedNodes.push(_exitVtx); nodeScore[_exitVtx] = 0.0f; while (true) { if (seedNodes.size() == 0) break; VtxDesc n = seedNodes.front(); seedNodes.pop(); bool bestEdgeFound = false; float bestScore = -FLT_MAX; EdgeDesc bestEdgeD = boost::initialized_value; OutEdgeIter oi, oe; for(boost::tie(oi, oe) = boost::out_edges(n, _g); oi != oe; ++oi) { EdgeDesc outEdgeD = *oi; VtxDesc outNodeD = boost::target(outEdgeD, _g); AlnNode outNode = _g[outNodeD]; float newScore, score = nodeScore[outNodeD]; if (outNode.backbone && outNode.weight == 1) { newScore = score - 10.0f; } else { AlnNode bbNode = _g[_bbMap[outNodeD]]; newScore = _g[outEdgeD].count - bbNode.coverage*0.5f + score; } if (newScore > bestScore) { bestScore = newScore; bestEdgeD = outEdgeD; bestEdgeFound = true; } } if (bestEdgeFound) { nodeScore[n]= bestScore; bestNodeScoreEdge[n] = bestEdgeD; } InEdgeIter ii, ie; for (boost::tie(ii, ie) = boost::in_edges(n, _g); ii != ie; ++ii) { EdgeDesc inEdge = *ii; _g[inEdge].visited = true; VtxDesc inNode = boost::source(inEdge, _g); int notVisited = 0; OutEdgeIter oi, oe; for (boost::tie(oi, oe) = boost::out_edges(inNode, _g); oi != oe; ++oi) { if (_g[*oi].visited == false) notVisited++; } // move onto the target node after we visit all incoming edges for // the target node if (notVisited == 0) seedNodes.push(inNode); } } // construct the final best path VtxDesc prev = _enterVtx, next; std::vector<AlnNode> bpath; while (true) { bpath.push_back(_g[prev]); if (bestNodeScoreEdge.count(prev) == 0) { break; } else { EdgeDesc bestOutEdge = bestNodeScoreEdge[prev]; _g[prev].bestOutEdge = bestOutEdge; next = boost::target(bestOutEdge, _g); _g[next].bestInEdge = bestOutEdge; prev = next; } } return bpath; }
/// @par /// /// See the #rcConfig documentation for more information on the configuration parameters. /// /// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf, const float sampleDist, const float sampleMaxError, rcPolyMeshDetail& dmesh) { rcAssert(ctx); ctx->startTimer(RC_TIMER_BUILD_POLYMESHDETAIL); if (mesh.nverts == 0 || mesh.npolys == 0) return true; const int nvp = mesh.nvp; const float cs = mesh.cs; const float ch = mesh.ch; const dtCoordinates orig( mesh.bmin ); const int borderSize = mesh.borderSize; rcIntArray edges(64); rcIntArray tris(512); rcIntArray stack(512); rcIntArray samples(512); dtCoordinates verts[256]; rcHeightPatch hp; int nPolyVerts = 0; int maxhw = 0, maxhh = 0; rcScopedDelete<int> bounds = (int*)rcAlloc(sizeof(int)*mesh.npolys*4, RC_ALLOC_TEMP); if (!bounds) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'bounds' (%d).", mesh.npolys*4); return false; } rcScopedDelete<dtCoordinates> poly = (dtCoordinates*)rcAlloc(sizeof(dtCoordinates)*nvp, RC_ALLOC_TEMP); if (!poly) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'poly' (%d).", nvp*3); return false; } // Find max size for a polygon area. for (int i = 0; i < mesh.npolys; ++i) { const unsigned short* p = &mesh.polys[i*nvp*2]; int& xmin = bounds[i*4+0]; int& xmax = bounds[i*4+1]; int& ymin = bounds[i*4+2]; int& ymax = bounds[i*4+3]; xmin = chf.width; xmax = 0; ymin = chf.height; ymax = 0; for (int j = 0; j < nvp; ++j) { if(p[j] == RC_MESH_NULL_IDX) break; const unsigned short* v = &mesh.verts[p[j]*3]; xmin = rcMin(xmin, (int)v[0]); xmax = rcMax(xmax, (int)v[0]); ymin = rcMin(ymin, (int)v[2]); ymax = rcMax(ymax, (int)v[2]); nPolyVerts++; } xmin = rcMax(0,xmin-1); xmax = rcMin(chf.width,xmax+1); ymin = rcMax(0,ymin-1); ymax = rcMin(chf.height,ymax+1); if (xmin >= xmax || ymin >= ymax) continue; maxhw = rcMax(maxhw, xmax-xmin); maxhh = rcMax(maxhh, ymax-ymin); } hp.data = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxhw*maxhh, RC_ALLOC_TEMP); if (!hp.data) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'hp.data' (%d).", maxhw*maxhh); return false; } dmesh.nmeshes = mesh.npolys; dmesh.nverts = 0; dmesh.ntris = 0; dmesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*dmesh.nmeshes*4, RC_ALLOC_PERM); if (!dmesh.meshes) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4); return false; } int vcap = nPolyVerts+nPolyVerts/2; int tcap = vcap*2; dmesh.nverts = 0; dmesh.verts = (dtCoordinates*)rcAlloc(sizeof(dtCoordinates)*vcap, RC_ALLOC_PERM); if (!dmesh.verts) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", vcap*3); return false; } dmesh.ntris = 0; dmesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char*)*tcap*4, RC_ALLOC_PERM); if (!dmesh.tris) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4); return false; } for (int i = 0; i < mesh.npolys; ++i) { const unsigned short* p = &mesh.polys[i*nvp*2]; // Store polygon vertices for processing. int npoly = 0; for (int j = 0; j < nvp; ++j) { if(p[j] == RC_MESH_NULL_IDX) break; const unsigned short* v = &mesh.verts[p[j]*3]; poly[j].SetX( v[0]*cs ); poly[j].SetY( v[1]*ch ); poly[j].SetZ( v[2]*cs ); npoly++; } // Get the height data from the area of the polygon. hp.xmin = bounds[i*4+0]; hp.ymin = bounds[i*4+2]; hp.width = bounds[i*4+1]-bounds[i*4+0]; hp.height = bounds[i*4+3]-bounds[i*4+2]; getHeightData(chf, p, npoly, mesh.verts, borderSize, hp, stack, mesh.regs[i]); // Build detail mesh. int nverts = 0; #ifdef MODIFY_VOXEL_FLAG const unsigned char area = mesh.areas[i]; if( !buildPolyDetail( ctx, poly, npoly, sampleDist, sampleMaxError, chf, hp, verts, nverts, tris, edges, samples, area ) ) #else // MODIFY_VOXEL_FLAG if (!buildPolyDetail(ctx, poly, npoly, sampleDist, sampleMaxError, chf, hp, verts, nverts, tris, edges, samples)) #endif // MODIFY_VOXEL_FLAG { return false; } // Move detail verts to world space. for (int j = 0; j < nverts; ++j) { verts[j].SetX( verts[j].X() + orig.X() ); verts[j].SetY( verts[j].Y() + orig.Y() + chf.ch ); // Is this offset necessary? verts[j].SetZ( verts[j].Z() + orig.Z() ); } // Offset poly too, will be used to flag checking. for (int j = 0; j < npoly; ++j) { poly[j].SetX( poly[j].X() + orig.X() ); poly[j].SetY( poly[j].Y() + orig.Y() ); poly[j].SetZ( poly[j].Z() + orig.Z() ); } // Store detail submesh. const int ntris = tris.size()/4; dmesh.meshes[i*4+0] = (unsigned int)dmesh.nverts; dmesh.meshes[i*4+1] = (unsigned int)nverts; dmesh.meshes[i*4+2] = (unsigned int)dmesh.ntris; dmesh.meshes[i*4+3] = (unsigned int)ntris; // Store vertices, allocate more memory if necessary. if (dmesh.nverts+nverts > vcap) { while (dmesh.nverts+nverts > vcap) vcap += 256; dtCoordinates* newv = (dtCoordinates*)rcAlloc(sizeof(dtCoordinates)*vcap, RC_ALLOC_PERM); if (!newv) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newv' (%d).", vcap*3); return false; } if (dmesh.nverts) memcpy(newv, dmesh.verts, sizeof(dtCoordinates)*dmesh.nverts); rcFree(dmesh.verts); dmesh.verts = newv; } for (int j = 0; j < nverts; ++j) { dmesh.verts[dmesh.nverts].SetX( verts[j].X() ); dmesh.verts[dmesh.nverts].SetY( verts[j].Y() ); dmesh.verts[dmesh.nverts].SetZ( verts[j].Z() ); dmesh.nverts++; } // Store triangles, allocate more memory if necessary. if (dmesh.ntris+ntris > tcap) { while (dmesh.ntris+ntris > tcap) tcap += 256; unsigned char* newt = (unsigned char*)rcAlloc(sizeof(unsigned char)*tcap*4, RC_ALLOC_PERM); if (!newt) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newt' (%d).", tcap*4); return false; } if (dmesh.ntris) memcpy(newt, dmesh.tris, sizeof(unsigned char)*4*dmesh.ntris); rcFree(dmesh.tris); dmesh.tris = newt; } for (int j = 0; j < ntris; ++j) { const int* t = &tris[j*4]; dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0]; dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[1]; dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[2]; dmesh.tris[dmesh.ntris*4+3] = getTriFlags(verts[t[0]], verts[t[1]], verts[t[2]], poly, npoly); dmesh.ntris++; } } ctx->stopTimer(RC_TIMER_BUILD_POLYMESHDETAIL); return true; }
const edge_range_t getEdges() const { return edges( _graph ); }