static Nested<CircleArc> circle_arc_quantize_test(Nested<const CircleArc> arcs) { IntervalScope scope; const auto quant = make_arc_quantizer(approximate_bounding_box(arcs)); VertexSet<Pb::Implicit> verts; const auto contours = verts.quantize_circle_arcs(quant, arcs); return verts.unquantize_circle_arcs(quant, contours); }
/** * Method is used to compose result solid. * @param faceStatus1 is face status. * @param faceStatus2 is face status. * @param faceStatus3 is face status. * @return pointer to result solid. */ Solid* GeoModifier::composeSolid(int faceStatus1, int faceStatus2, int faceStatus3) { VertexSet* vertices = new VertexSet(); IntSet* indices = new IntSet(); groupObjectComponents(*firstObject, *vertices, *indices, faceStatus1, faceStatus2); groupObjectComponents(*secondObject, *vertices, *indices, faceStatus3, faceStatus3); VectorSet * vectors = new VectorSet(); for(int i = 0; i < vertices->GetNumVertices(); i++) { Vertex * pVertex = vertices->GetVertex(i); vectors->push_back(pVertex->getPosition()); } Solid* result = new Solid(); result->indices = *indices; result->vertices = *vectors; delete indices; delete vertices; delete vectors; return result; }
void PrintMatchKeys(string key, const VertexSet& s) { vector<string> tokens; split((char*)key.c_str(), "_", tokens); if (tokens.size() == 0) { return; } cout << "MATCH,"; vector<int> pivots; for (int i = 0; i < tokens.size(); i++) { if (tokens[i].size() > 0) { int u = atoi(tokens[i].c_str()); cout << GetLabel(gSearch__, u) << ", "; pivots.push_back(u); } } for (unordered_set<uint64_t>::const_iterator s_it = s.begin(); s_it != s.end(); s_it++) { cout << GetLabel(gSearch__, *s_it) << ", "; } cout << endl; /* for (unordered_set<uint64_t>::const_iterator s_it = s.begin(); s_it != s.end(); s_it++) { for (int j = 0; j < pivots.size(); j++) { GephiStreamingClient::GetInstance().PostEdge(*s_it, pivots[j]); } } */ }
/** * Method is used to group object components. * @param object is source object. * @param vertices is other object vertices. * @pram indices is other object indices. * @param faceStatus1 is face status. * @param faceStatus2 is face status. */ void GeoModifier::groupObjectComponents(Object3D& object, VertexSet& vertices, IntSet& indices, int faceStatus1, int faceStatus2) { //for each face.. for(int i = 0; i < object.getNumFaces(); ++i) { Face& face = *(object.getFace(i)); if(face.getStatus()==faceStatus1 || face.getStatus()==faceStatus2) { VertexPointerSet faceVerts; faceVerts.add(face.v1); faceVerts.add(face.v2); faceVerts.add(face.v3); for(int j=0;j<faceVerts.length();j++) { if(vertices.contains(faceVerts[j])) indices.push_back(vertices.indexOf(faceVerts[j])); else { indices.push_back(vertices.length()); vertices.AddVertex(*faceVerts[j]); } } } } }
PoseGraph::VertexSet PoseGraph::allVertices () const { VertexSet nodes; BOOST_FOREACH (const VertexMap::value_type& e, _vertexMap) nodes.insert(e.first); return nodes; }
bool Decompress( const std::vector<unsigned int>& indices, const std::vector<unsigned int>& normalIndices, const std::vector<unsigned int>& textureIndices, const std::vector<Vector3f>& vertices, const std::vector<Vector3f>& normals, const std::vector<Vector3f>& textureCoords, const std::vector<Vector4f>& tangents, std::vector<Vertex>& outVertices, std::vector<TriangleFace>& outFaces ) { VertexSet vertexSet; unsigned int triangleCount = static_cast<unsigned int>(indices.size()) / TRIANGLE_EDGE_COUNT; unsigned int index = 0; unsigned int freeIndex = 0; Vector3f v1, v2, v3; Vector3f n1, n2, n3; Vector3f t1, t2, t3; TriangleFace face; Vertex v; for ( unsigned int i = 0; i < triangleCount; i++ ) { unsigned int vIndex, nIndex, tIndex; for ( unsigned int j = 0; j < TRIANGLE_EDGE_COUNT; j++ ) { vIndex = indices[index + j]; nIndex = normalIndices[index + j]; tIndex = textureIndices[index + j]; v.position = vertices[vIndex]; v.normal = normals[nIndex]; v.textureCoord = textureCoords[tIndex]; VertexSet::const_iterator it = vertexSet.find(v); if ( it != vertexSet.end() ) { face.indices[j] = vertexSet.find(v)->second; } else { vertexSet.insert(std::make_pair(v, freeIndex)); face.indices[j] = freeIndex; outVertices.push_back(v); freeIndex++; } } outFaces.push_back(face); index += TRIANGLE_EDGE_COUNT; } return true; }
void Geometry::Face2Polygon(const TopoDS_Face &f, pcl::PlanarPolygon<PointT>& poly) { VertexSet vertices; GetVertices(f,vertices); PointCloud cloud; for (VertexSet::iterator it=vertices.begin();it!=vertices.end();++it ){ PointT p; Vertex2Point(*it,p); cloud.push_back(p); } poly.setContour(cloud); }
void ShGraph<G>::vertexHeight(const VertexSet &roots, HeightMap &heights) { heights.clear(); VertexPairMap<int> dist; NegativeWeigher<G> weigher; typename VertexSet::const_iterator U, V; floydWarshall(weigher, dist); for(U = verts.begin(); U != verts.end(); ++U) { for(V = roots.begin(); V != roots.end(); ++V) { heights[*U] = std::max(heights[*U], -dist(*V, *U)); } } }
void verifyMatching(BipartiteGraph g, unsigned expectedSize) { Matching matching = findMaximumMatching(g); typedef boost::unordered_set<unsigned> VertexSet; VertexSet first; VertexSet second; for (auto elem : matching) { ASSERT_TRUE(first.insert(elem.first).second); ASSERT_TRUE(second.insert(elem.second).second); ASSERT_TRUE(g.edgeExists(elem)); } ASSERT_EQ(expectedSize, matching.size()); }
size_t load_transactions_from_binary(string& data, VertexTransactions& transactions, VertexSet& bad_vertices) { char* bytearray = (char*) data.c_str(); size_t byte_pos = 0; // get number of transactions uint64* num_transactions = (uint64 *)(bytearray); byte_pos += 8; // get vertex / transaction list for (int i = 0; i < int(*num_transactions); ++i) { VertexID* vertex_id = (VertexID *)(bytearray+byte_pos); byte_pos += 8; TransactionID* transaction_id = (TransactionID *)(bytearray+byte_pos); byte_pos += 8; transactions[*vertex_id] = *transaction_id; } // find failed transactions uint64* num_failed_transactions = (uint64*)(bytearray+byte_pos); byte_pos += 8; for (int i = 0; i < int(*num_failed_transactions); ++i) { VertexID* vertex_id = (VertexID *)(bytearray+byte_pos); byte_pos += 8; bad_vertices.insert(*vertex_id); } // byte position indicates the location of the rest of the binary payload return byte_pos; }
void ShGraph<G>::rootSet(VertexSet &roots) { roots = verts; typename EdgeSet::const_iterator E; for(E = edges.begin(); E != edges.end(); ++E) { roots.erase((*E)->end); } }
void used_vertices(const Graph& graph, VertexSet& vertex_set) { typedef boost::graph_traits <Graph> traits; typename traits::edge_iterator edge_iter, edge_end; for (boost::tie(edge_iter, edge_end) = boost::edges(graph); edge_iter != edge_end; ++edge_iter) { vertex_set.insert(boost::source(*edge_iter, graph)); vertex_set.insert(boost::target(*edge_iter, graph)); } }
void copy(const VertexSet &other) { set_tracker_config(other.T()); this->curr_projection_ = other.curr_projection_; if (this->num_projections_==0 && other.num_projections_>0) { projections_ = (vec_mp *) br_malloc(other.num_projections_*sizeof(vec_mp)); } else if(this->num_projections_>0 && other.num_projections_>0) { projections_ = (vec_mp *) br_realloc(projections_,other.num_projections_*sizeof(vec_mp)); } else if (this->num_projections_>0 && other.num_projections_==0){ for (int ii=0; ii<this->num_projections_; ii++) { clear_vec_mp(projections_[ii]); } free(projections_); } for (int ii=0; ii<other.num_projections_; ii++) { if (ii>=this->num_projections_){ init_vec_mp2(projections_[ii],1,1024); projections_[ii]->size = 1; } vec_cp_mp(projections_[ii],other.projections_[ii]); } this->num_projections_ = other.num_projections_; curr_input_index_ = other.curr_input_index_; filenames_ = other.filenames_; this->num_vertices_ = other.num_vertices_; this->num_natural_variables_ = other.num_natural_variables_; this->vertices_ = other.vertices_; vec_cp_mp(this->checker_1_,other.checker_1_); vec_cp_mp(this->checker_2_,other.checker_2_); }
void Map(const MatchSet* match, string& key, string& match_signature, VertexSet& vertex_set) { stringstream strm; for (vector<uint64_t>::iterator it = group_by_vertices__.begin(); it != group_by_vertices__.end(); it++) { strm << "_" << match->GetMatch(*it); } key = strm.str(); stringstream strm1; for (int i = 0, N = match->NumVertices(); i < N; i++) { int i_match = match->vertex_map[i].second; vertex_set.insert(i_match); strm1 << "_" << i_match; } match_signature = strm1.str(); return; }
void UbermasterProcess::bertini_real(WitnessSet & W, vec_mp *pi, VertexSet & V) { W.set_incidence_number(get_incidence_number( W.point(0), program_options, program_options.input_filename())); boost::filesystem::path temp_name = program_options.output_dir(); std::stringstream converter; converter << "_dim_" << W.dimension() << "_comp_" << W.component_number(); temp_name += converter.str(); program_options.output_dir(temp_name); switch (W.dimension()) { case 1: { Curve C; // curve C.main(V, W, pi, program_options, solve_options); if (program_options.verbose_level()>=2) printf("outputting data\n"); C.output_main(program_options.output_dir()); V.print(program_options.output_dir()/ "V.vertex"); } break; case 2: { Surface S; // surface S.main(V, W, pi, program_options, solve_options); S.output_main(program_options.output_dir()); V.print(program_options.output_dir()/ "V.vertex"); } break; default: { std::cout << "bertini_real not programmed for components of dimension " << W.dimension() << std::endl; } break; } }
void Delaunay::Triangulate(const VertexSet& vertices, TriangleSet& output) { if (vertices.size() < 3) { return; } cVertexIterator iterVertex = vertices.begin(); double xMin = iterVertex->GetX(); double yMin = iterVertex->GetY(); double xMax = xMin; double yMax = yMin; ++iterVertex; for (; iterVertex != vertices.end(); ++iterVertex) { xMax = iterVertex->GetX(); double y = iterVertex->GetY(); if (y < yMin) { yMin = y; } if (y > yMax) { yMax = y; } } double dx = xMax - xMin; double dy = yMax - yMin; double ddx = dx * 0.01; double ddy = dy * 0.01; xMin -= ddx; xMax += ddx; dx += 2 * ddx; yMin -= ddy; yMax += ddy; dy += 2 * ddy; Vertex vSuper[3]; vSuper[0] = Vertex(xMin - dy * sqrt3 / 3.0, yMin); vSuper[1] = Vertex(xMax + dy * sqrt3 / 3.0, yMin); vSuper[2] = Vertex((xMin + xMax) * 0.5, yMax + dx * sqrt3 * 0.5); TriangleSet workset; workset.insert(Triangle(vSuper)); for (iterVertex = vertices.begin(); iterVertex != vertices.end(); ++iterVertex) { TriangleIsCompleted pred1(iterVertex, output, vSuper); TriangleSet::iterator iter = workset.begin(); while (iter != workset.end()) { if (pred1(*iter)) { iter = workset.erase(iter); } else { ++iter; } } EdgeSet edges; VertexIsInCircumstanceCircle pred2(iterVertex, edges); iter = workset.begin(); while (iter != workset.end()) { if (pred2(*iter)) { iter = workset.erase(iter); } else { ++iter; } } for (EdgeIterator edgeIter = edges.begin(); edgeIter != edges.end(); ++edgeIter) { workset.insert(Triangle(edgeIter->m_pv0, edgeIter->m_pv1, &(*iterVertex))); } } TriangleIterator where = output.begin(); TriangleHasVertex pred(vSuper); for (auto t : workset) { if (!pred(t)) { output.insert(output.begin(), t); } } }
/** * Main function. * * Usage: VtkToFld session.xml input.vtk output.fld [options] */ int main(int argc, char* argv[]) { // Set up available options po::options_description desc("Available options"); desc.add_options() ("help,h", "Produce this help message.") ("name,n", po::value<string>()->default_value("Intensity"), "Name of field in VTK file to use for intensity.") ("outname,m", po::value<string>()->default_value("intensity"), "Name of field in output FLD file.") ("precision,p", po::value<double>()->default_value(1), "Precision of vertex matching."); po::options_description hidden("Hidden options"); hidden.add_options() ("file", po::value<vector<string> >(), "Input filename"); po::options_description cmdline_options; cmdline_options.add(desc).add(hidden); po::positional_options_description p; p.add("file", -1); po::variables_map vm; // Parse command-line options try { po::store(po::command_line_parser(argc, argv). options(cmdline_options).positional(p).run(), vm); po::notify(vm); } catch (const std::exception& e) { cerr << e.what() << endl; cerr << desc; return 1; } if ( vm.count("help") || vm.count("file") == 0 || vm["file"].as<vector<string> >().size() != 3) { cerr << "Usage: VtkToFld session.xml intensity.vtk output.fld [options]" << endl; cerr << desc; return 1; } // Extract command-line argument values std::vector<std::string> vFiles = vm["file"].as<vector<string> >(); const string infile = vFiles[1]; const string outfile = vFiles[2]; const double factor = vm["precision"].as<double>(); const string name = vm["name"].as<string>(); const string outname = vm["outname"].as<string>(); std::vector<std::string> vFilenames; LibUtilities::SessionReaderSharedPtr vSession; SpatialDomains::MeshGraphSharedPtr graph2D; MultiRegions::ExpList2DSharedPtr Exp; vFilenames.push_back(vFiles[0]); vSession = LibUtilities::SessionReader::CreateInstance(2, argv, vFilenames); try { //---------------------------------------------- // Read in mesh from input file graph2D = MemoryManager<SpatialDomains::MeshGraph2D>:: AllocateSharedPtr(vSession); //---------------------------------------------- //---------------------------------------------- // Define Expansion Exp = MemoryManager<MultiRegions::ExpList2D>:: AllocateSharedPtr(vSession,graph2D); //---------------------------------------------- //---------------------------------------------- // Set up coordinates of mesh int coordim = Exp->GetCoordim(0); int nq = Exp->GetNpoints(); Array<OneD, NekDouble> xc0(nq,0.0); Array<OneD, NekDouble> xc1(nq,0.0); Array<OneD, NekDouble> xc2(nq,0.0); switch(coordim) { case 2: Exp->GetCoords(xc0,xc1); break; case 3: Exp->GetCoords(xc0,xc1,xc2); break; default: ASSERTL0(false,"Coordim not valid"); break; } //---------------------------------------------- vtkPolyDataReader *vtkMeshReader = vtkPolyDataReader::New(); vtkMeshReader->SetFileName(infile.c_str()); vtkMeshReader->Update(); vtkPolyData *vtkMesh = vtkMeshReader->GetOutput(); vtkCellDataToPointData* c2p = vtkCellDataToPointData::New(); #if VTK_MAJOR_VERSION <= 5 c2p->SetInput(vtkMesh); #else c2p->SetInputData(vtkMesh); #endif c2p->PassCellDataOn(); c2p->Update(); vtkPolyData *vtkDataAtPoints = c2p->GetPolyDataOutput(); vtkPoints *vtkPoints = vtkMesh->GetPoints(); ASSERTL0(vtkPoints, "ERROR: cannot get points from mesh."); vtkCellArray *vtkPolys = vtkMesh->GetPolys(); ASSERTL0(vtkPolys, "ERROR: cannot get polygons from mesh."); vtkPointData *vtkPData = vtkDataAtPoints->GetPointData(); ASSERTL0(vtkPolys, "ERROR: cannot get point data from file."); VertexSet points; VertexSet::iterator vIter; double p[3]; double val; double x, y, z; int coeff_idx; int i,j,n; if (!vtkDataAtPoints->GetPointData()->HasArray(name.c_str())) { n = vtkDataAtPoints->GetPointData()->GetNumberOfArrays(); cerr << "Input file '" << infile << "' does not have a field named '" << name << "'" << endl; cerr << "There are " << n << " arrays in this file." << endl; for (int i = 0; i < n; ++i) { cerr << " " << vtkDataAtPoints->GetPointData()->GetArray(i)->GetName() << endl; } return 1; } // Build up an unordered set of vertices from the VTK file. For each // vertex a hashed value of the coordinates is generated to within a // given tolerance. n = vtkPoints->GetNumberOfPoints(); for (i = 0; i < n; ++i) { vtkPoints->GetPoint(i,p); val = vtkPData->GetScalars(name.c_str())->GetTuple1(i); boost::shared_ptr<Vertex> v(new Vertex(p[0],p[1],p[2],val,factor)); points.insert(v); } // Now process each vertex of each element in the mesh SpatialDomains::PointGeomSharedPtr vert; for (i = 0; i < Exp->GetNumElmts(); ++i) { StdRegions::StdExpansionSharedPtr e = Exp->GetExp(i); for (j = 0; j < e->GetNverts(); ++j) { // Get the index of the coefficient corresponding to this vertex coeff_idx = Exp->GetCoeff_Offset(i) + e->GetVertexMap(j); // Get the coordinates of the vertex vert = e->as<LocalRegions::Expansion2D>()->GetGeom2D() ->GetVertex(j); vert->GetCoords(x,y,z); // Look up the vertex in the VertexSet boost::shared_ptr<Vertex> v(new Vertex(x,y,z,0.0,factor)); vIter = points.find(v); // If not found, maybe the tolerance should be reduced? // If found, record the scalar value from the VTK file in the // corresponding coefficient. if (vIter == points.end()) { cerr << "Vertex " << i << " not found. Looking for (" << x << ", " << y << ", " << z << ")" << endl; } else { Exp->UpdateCoeffs()[coeff_idx] = (*vIter)->scalar; } } } Exp->SetPhysState(false); //----------------------------------------------- // Write solution to file std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef = Exp->GetFieldDefinitions(); std::vector<std::vector<NekDouble> > FieldData(FieldDef.size()); for(i = 0; i < FieldDef.size(); ++i) { FieldDef[i]->m_fields.push_back(outname); Exp->AppendFieldData(FieldDef[i], FieldData[i]); } LibUtilities::FieldIO vFld(vSession->GetComm()); vFld.Write(outfile, FieldDef, FieldData); //----------------------------------------------- } catch (...) { cout << "An error occurred." << endl; } }
bool TerrainPatch::BuildDetailLevel(int level) { int i, j; int detail_size = 1 << level; int ds1 = detail_size+1; if (detail_size > PATCH_SIZE) return false; Model* model = new(__FILE__,__LINE__) Model; detail_levels[level] = model; model->SetLuminous(luminous); model->SetDynamic(true); const int NUM_STRIPS = 4; const int NUM_INDICES_TRI = 3; const int NUM_INDICES_QUAD = 6; int nverts = ds1*ds1 + ds1*2*NUM_STRIPS; int npolys = detail_size*detail_size*2; int strip_len = detail_size; int total = npolys + strip_len*NUM_STRIPS; if (water) { nverts = ds1*ds1; strip_len = 0; total = npolys; } Surface* s = new(__FILE__,__LINE__) Surface; VertexSet* vset = 0; if (s) { s->SetName("default"); s->CreateVerts(nverts); s->CreatePolys(total); s->AddIndices(npolys*NUM_INDICES_TRI + strip_len*NUM_STRIPS*NUM_INDICES_QUAD); vset = s->GetVertexSet(); if (!water) vset->CreateAdditionalTexCoords(); ZeroMemory(vset->loc, nverts * sizeof(Vec3)); ZeroMemory(vset->diffuse, nverts * sizeof(DWORD)); ZeroMemory(vset->specular, nverts * sizeof(DWORD)); ZeroMemory(vset->tu, nverts * sizeof(float)); ZeroMemory(vset->tv, nverts * sizeof(float)); if (!water) { ZeroMemory(vset->tu1, nverts * sizeof(float)); ZeroMemory(vset->tv1, nverts * sizeof(float)); } ZeroMemory(vset->rw, nverts * sizeof(float)); // initialize vertices Vec3* pVert = vset->loc; float* pTu = vset->tu; float* pTv = vset->tv; float* pTu1 = vset->tu1; float* pTv1 = vset->tv1; DWORD* pSpec = vset->specular; int dscale = (PATCH_SIZE-1)/detail_size; double dt = 0.0625 / (ds1-1); // terrain texture scale double dtt = 2.0000 / (ds1-1); // tile texture scale double tu0 = (double) rect.x / rect.w / 16.0 + 1.0/16.0; double tv0 = (double) rect.y / rect.h / 16.0; // surface verts for (i = 0; i < ds1; i++) { for (j = 0; j < ds1; j++) { *pVert = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)), (float) (heights[i*dscale*PATCH_SIZE + j*dscale]), (float) (i* scale * dscale - (HALF_PATCH_SIZE*scale))); if (level >= 2) { *pTu++ = (float) (-j*dtt); *pTv++ = (float) ( i*dtt); if (level >= 4 && !water) { *pTu1++ = (float) (-j*dtt*3); *pTv1++ = (float) ( i*dtt*3); } *pSpec++ = BlendValue(pVert->y); } else { *pTu++ = (float) (tu0 - j*dt); *pTv++ = (float) (tv0 + i*dt); } pVert++; } } if (!water) { // strip 1 & 2 verts for (i = 0; i < ds1; i += detail_size) { for (j = 0; j < ds1; j++) { Vec3 vl = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)), (float) (heights[i*dscale*PATCH_SIZE + j*dscale]), (float) (i* scale * dscale - (HALF_PATCH_SIZE*scale))); *pVert++ = vl; DWORD blend = 0; if (level >= 2) { blend = BlendValue(vl.y); *pSpec++ = blend; *pTu++ = (float) (-j*dtt); *pTv++ = (float) ( i*dtt); } else { *pTu++ = (float) (tu0 - j*dt); *pTv++ = (float) (tv0 + i*dt); } vl.y = -5000.0f; *pVert++ = vl; if (level >= 2) { *pSpec++ = blend; *pTu++ = (float) (-j*dtt); *pTv++ = (float) ( i*dtt); } else { *pTu++ = (float) (tu0 - j*dt); *pTv++ = (float) (tv0 + i*dt); } } } // strip 3 & 4 verts for (j = 0; j < ds1; j += detail_size) { for (i = 0; i < ds1; i++) { Vec3 vl = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)), (float) (heights[i*dscale*PATCH_SIZE + j*dscale]), (float) (i* scale * dscale - (HALF_PATCH_SIZE*scale))); *pVert++ = vl; DWORD blend = 0; if (level >= 2) { blend = BlendValue(vl.y); *pSpec++ = blend; *pTu++ = (float) (-j*dtt); *pTv++ = (float) ( i*dtt); } else { *pTu++ = (float) (tu0 - j*dt); *pTv++ = (float) (tv0 + i*dt); } vl.y = -5000.0f; *pVert++ = vl; if (level >= 2) { *pSpec++ = blend; *pTu++ = (float) (-j*dtt); *pTv++ = (float) ( i*dtt); } else { *pTu++ = (float) (tu0 - j*dt); *pTv++ = (float) (tv0 + i*dt); } } } } Material* m = materials.first(); // initialize the polys for (i = 0; i < npolys; i++) { Poly* p = s->GetPolys() + i; p->nverts = 3; p->vertex_set = vset; p->visible = 1; p->sortval = 0; p->material = m; if (level >= 2 && !water) { p->material = materials.at(1); p->sortval = 1; } } for (i = npolys; i < total; i++) { Poly* p = s->GetPolys() + i; p->nverts = 4; p->vertex_set = vset; p->visible = 1; p->sortval = 0; p->material = m; } int index = 0; // build main patch polys: for (i = 0; i < detail_size; i++) { for (j = 0; j < detail_size; j++) { int v[4] = { (ds1 * (i ) + (j )), (ds1 * (i ) + (j+1)), (ds1 * (i+1) + (j )), (ds1 * (i+1) + (j+1)) }; bisect(vset, v); // first triangle Poly* p = s->GetPolys() + index++; p->verts[0] = v[0]; p->verts[1] = v[1]; p->verts[2] = v[3]; if (level >= 2 && !water) { int layer = CalcLayer(p) + 1; p->material = materials.at(layer); p->sortval = layer; } // second triangle p = s->GetPolys() + index++; p->verts[0] = v[0]; p->verts[1] = v[3]; p->verts[2] = v[2]; if (level >= 2 && !water) { int layer = CalcLayer(p) + 1; p->material = materials.at(layer); p->sortval = layer; } } } // build vertical edge strip polys: if (!water) { for (i = 0; i < NUM_STRIPS; i++) { Poly* p = s->GetPolys() + npolys + i*strip_len; int base_index = ds1*ds1 + ds1*2*i; for (j = 0; j < strip_len; j++) { int v = base_index + j * 2; p->nverts = 4; if (i == 1 || i == 2) { p->verts[0] = v; p->verts[1] = v+2; p->verts[2] = v+3; p->verts[3] = v+1; } else { p->verts[0] = v; p->verts[1] = v+1; p->verts[2] = v+3; p->verts[3] = v+2; } if (level >= 2) { int layer = CalcLayer(p) + 1; p->material = materials.at(layer); p->sortval = layer; } p++; } } } // update the poly planes: for (i = 0; i < total; i++) { Poly* p = s->GetPolys() + i; Plane& plane = p->plane; WORD* v = p->verts; plane = Plane(vset->loc[v[0]] + loc, vset->loc[v[1]] + loc, vset->loc[v[2]] + loc); } s->Normalize(); // create continguous segments for each material: // sort the polys by material index: qsort((void*) s->GetPolys(), s->NumPolys(), sizeof(Poly), mcomp); // then assign them to cohesive segments: Segment* segment = 0; Poly* spolys = s->GetPolys(); for (int n = 0; n < s->NumPolys(); n++) { if (segment && segment->material == spolys[n].material) { segment->npolys++; } else { segment = 0; } if (!segment) { segment = new(__FILE__,__LINE__) Segment; segment->npolys = 1; segment->polys = &spolys[n]; segment->material = segment->polys->material; segment->model = model; s->GetSegments().append(segment); } } Solid::EnableCollision(false); model->AddSurface(s); Solid::EnableCollision(true); // copy vertex normals: const Vec3B* tnorms = terrain->Normals(); for (i = 0; i < ds1; i++) { for (j = 0; j < ds1; j++) { if (water) { vset->nrm[i*ds1+j] = Point(0,1,0); } // blend adjacent normals: else if (dscale > 1) { Point normal; // but don't blend more than 16 normals per vertex: int step = 1; if (dscale > 4) step = dscale / 4; for (int dy = -dscale/2; dy < dscale/2; dy += step) { for (int dx = -dscale/2; dx < dscale/2; dx += step) { int ix = rect.x + (ds1-1-j)*dscale + dx; int iy = rect.y + i*dscale + dy; if (ix < 0) ix = 0; if (ix > terrain_width-1) ix = terrain_width-1; if (iy < 0) iy = 0; if (iy > terrain_width-1) iy = terrain_width-1; Vec3B vbn = tnorms[iy*terrain_width + ix]; normal += Point((128-vbn.x)/127.0, (vbn.z-128)/127.0, (vbn.y-128)/127.0); } } normal.Normalize(); vset->nrm[i*ds1+j] = normal; } // just copy the one normal: else { Vec3B vbn = tnorms[(rect.y + i*dscale)*terrain_width + (rect.x + (ds1-1-j) * dscale)]; Point normal = Point((128-vbn.x)/127.0, (vbn.z-128)/127.0, (vbn.y-128)/127.0); vset->nrm[i*ds1+j] = normal; } } } if (!water) { pVert = &vset->nrm[ds1*ds1]; // strip 1 & 2 verts for (i = 0; i < ds1; i += detail_size) { for (j = 0; j < ds1; j++) { Vec3 vn = vset->nrm[i*ds1 + j]; *pVert++ = vn; *pVert++ = vn; } } // strip 3 & 4 verts for (j = 0; j < ds1; j += detail_size) { for (i = 0; i < ds1; i++) { Vec3 vn = vset->nrm[i*ds1 + j]; *pVert++ = vn; *pVert++ = vn; } } } } if (level > max_detail) max_detail = level; return true; }
void Atoms::ComputeAtoms() { // Get minimal triangulation EliminationOrder* eo = new EliminationOrder(G_); FillEdges* F = new FillEdges(G_); VertexList* minsep_generators = new VertexList(); MCSmPlus::Run(*G_, eo, F, minsep_generators); std::list< VertexSet* > vertices_of_atoms; SeparatorComponents cc(G_); Vertices deleted_vertices; // in paper, this is V(G_) - V(G_') std::vector< bool > is_deleted(G_->order(), false); // Examine minsep_generators, eo-earliest first for (int i : *minsep_generators) { // Check to see if minimal separator is a clique Vertex v = eo->VertexAt(i); Vertices S; for (Vertex u : G_->N(v)) { if (eo->Before(v, u) && !is_deleted[u]) { S.push_back(u); } } for (Vertex u : (*F)[v]) { if (eo->Before(v, u) && !is_deleted[u]) { S.push_back(u); } } if (G_->IsClique(S)) { clique_minimal_separators_.Insert(S); for (Vertex u : deleted_vertices) { S.push_back(u); } cc.Separate(S); Vertices C = cc.ConnectedComponent(v); VertexSet* atom = new VertexSet(); for (Vertex u : C) { if (!is_deleted[u]) { deleted_vertices.push_back(u); is_deleted[u] = true; atom->insert(u); } } for (Vertex u : S) { if (!is_deleted[u]) { atom->insert(u); } } vertices_of_atoms.push_back(atom); } } // Remaining vertices form an atom Vertices C; for (Vertex v : *G_) { if (!is_deleted[v]) { C.push_back(v); } } if (!C.empty()) { VertexSet* atom = new VertexSet(); for (Vertex v : C) { atom->insert(v); } vertices_of_atoms.push_back(atom); } for (VertexSet* U : vertices_of_atoms) { atom_subgraphs_.push_back(new InducedSubgraph(G_, *U)); delete U; } delete eo; delete F; delete minsep_generators; return; }