Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
		/**
		 * 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;
		}
Exemplo n.º 3
0
    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]);
            }
        }
*/
    }
Exemplo n.º 4
0
		/**
		 * 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]);
						}
					}
				}
			}
		}
Exemplo n.º 5
0
 PoseGraph::VertexSet PoseGraph::allVertices () const
 {
     VertexSet nodes;
     BOOST_FOREACH (const VertexMap::value_type& e, _vertexMap) 
         nodes.insert(e.first);
     return nodes;
 }
Exemplo n.º 6
0
Arquivo: Mesh.cpp Projeto: liy3/GPGPU
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;
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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));
    }
  }
}
Exemplo n.º 9
0
 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());
 }
Exemplo n.º 10
0
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; 
} 
Exemplo n.º 11
0
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);
  }
}
Exemplo n.º 12
0
    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));
      }
    }
Exemplo n.º 13
0
	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_);
		
	}
Exemplo n.º 14
0
    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;
    }
Exemplo n.º 15
0
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);
			}
		}
	}
Exemplo n.º 17
0
/**
 * 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;
    }
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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;
}