Example #1
0
/** Implementation based on Graphics Gems 2, p. 170: "IV.1. Area of Planar Polygons and Volume of Polyhedra." */
float Polygon::Area() const
{
    assume(IsPlanar());
    float3 area = float3::zero;

    int i = NumEdges()-1;
    for(int j = 0; j < NumEdges(); ++j)
    {
        area += Vertex(i).Cross(Vertex(j));
        i = j;
    }
    return 0.5f * Abs(NormalCCW().Dot(area));
}
Example #2
0
float Polygon::Perimeter() const
{
	float perimeter = 0.f;
	for(int i = 0; i < NumEdges(); ++i)
		perimeter += Edge(i).Length();
	return perimeter;
}
Example #3
0
//
// try to guess type of roof from looking at slopes of edges of
// this level
//
RoofType vtLevel::GuessRoofType()
{
	int sloped = 0, vert = 0, hori = 0;
	int i, edges = NumEdges();
	for (i = 0; i < edges; i++)
	{
		vtEdge *edge = GetEdge(i);
		if (edge->m_iSlope == 0)
			hori++;
		else if (edge->m_iSlope == 90)
			vert++;
		else
			sloped++;
	}
	if (hori)
		return ROOF_FLAT;

	if (sloped == 1 && vert == edges-1)
		return ROOF_SHED;

	if (sloped == edges)
		return ROOF_HIP;

	if (sloped > 0 && vert > 0)
		return ROOF_GABLE;

	return ROOF_UNKNOWN;
}
Example #4
0
void SetUp (void* gptr, int type)
{   int i,allocsize;
    Graph g=NULL;
    EuclidGraph xy=NULL;
    MatrixGraph matg=NULL;

    if (type==1) {
	g = (Graph) gptr;
	U = Degree(g,0);
	V = NumEdges(g);
	}
    else if (type==2) {
	xy = (EuclidGraph) gptr;
	U = xy[0][0];
	V = U*(U-1)/2;
	}
    else if (type==3) {
	matg = (MatrixGraph) gptr;
	U = matg[0];
	V = U*(U-1)/2;
	}

    allocsize = (U+2*V+2)*sizeof(int);
    A      = (int *) malloc(allocsize);
    END    = (int *) malloc(allocsize);
    WEIGHT = (int *) malloc(allocsize);
    for (i=0; i<U+2*V+2; i++)
	A[i]=END[i]=WEIGHT[i]=0;

    if (type == 1) SetStandard(g);
    else if (type == 2) SetEuclid(xy);
    else if (type == 3) SetMatrix(matg);
}
Example #5
0
bool vtLevel::IsEdgeConvex(int i)
{
	// get the 2 corner indices of this edge
	int edges = NumEdges();
	int c1 = i;
	int c2 = (i+1 == edges) ? 0 : i+1;

	return (IsCornerConvex(c1) && IsCornerConvex(c2));
}
Example #6
0
void vtLevel::SetEaveLength(float fMeters)
{
	int i, edges = NumEdges();

	for (i = 0; i < edges; i++)
	{
		vtEdge *edge = m_Edges[i];
		float rise = m_fStoryHeight;
		// sin(slope) = rise/length
		// length = rise/sin(slope)
		float length = rise / sinf(edge->m_iSlope / 180.0f * PIf);
		edge->m_Features[0].m_vf1 = -(fMeters / length);
	}
}
Example #7
0
//
// Look at the sloped edges to see if they meet at a particular point;
// if so, set that as the Level's story height.  Return true on success.
//
bool vtLevel::DetermineHeightFromSlopes()
{
	// In order to find a roof point, we need 3 adjacent edges whose
	// edges intersect.
	int i, edges = NumEdges();

	bool bFoundASolution = false;
	FPlane *planes = new FPlane[edges];
	float fMinHeight = 1E10;
	for (i = 0; i < edges; i++)
	{
		GetEdgePlane(i, planes[i]);
	}
	for (i = 0; i < edges; i++)
	{
		int i0 = i;
		int i1 = (i+1)%edges;
		int i2 = (i+2)%edges;
		vtEdge *edge0 = m_Edges[i0];
		vtEdge *edge1 = m_Edges[i1];
		vtEdge *edge2 = m_Edges[i2];
		if (edge0->m_iSlope == 90 &&
			edge1->m_iSlope == 90 &&
			edge2->m_iSlope == 90)
		{
			// skip this one; 3 vertical edges aren't useful
			continue;
		}
		FPoint3 point;
		bool valid = PlaneIntersection(planes[i0], planes[i1], planes[i2], point);
		if (valid)
		{
			// take this point as the height of the roof
			float fHeight = (point.y - m_LocalFootprint[0][0].y);

			if (fHeight < 0)	// shouldn't happen, but just a safety check
				continue;

			if (fHeight < fMinHeight)
				fMinHeight = fHeight;
			bFoundASolution = true;
		}
	}
	if (bFoundASolution)
		m_fStoryHeight = fMinHeight;
	delete [] planes;
	return bFoundASolution;
}
Example #8
0
//
// Look at the materials of this level's edges.  If they all use the
// same material, return it.  Otherwise, return BMAT_UNKNOWN.
//
bool vtLevel::GetOverallEdgeColor(RGBi &color)
{
	RGBi col1(-1, -1, -1);

	int edges = NumEdges();
	for (int i = 0; i < edges; i++)
	{
		vtEdge *pEdge = GetEdge(i);
		RGBi col2 = pEdge->m_Color;
		if (col1.r == -1)
			col1 = col2;
		else if (col1 != col2)
			return false;
	}
	color = col1;
	return true;
}
Example #9
0
//
// Look at the materials of this level's edges.  If they all use the
// same material, return it.  Otherwise, return "Multiple".
//
const vtString vtLevel::GetOverallEdgeMaterial()
{
	const vtString *most = NULL;

	int edges = NumEdges();
	for (int i = 0; i < edges; i++)
	{
		vtEdge *pEdge = GetEdge(i);
		const vtString *mat = pEdge->m_pMaterial;
		if (mat == NULL)
			continue;
		if (most == NULL)
			most = mat;
		else if (*most != *mat)
			return "Multiple";
	}
	if (most)
		return *most;
	else
		return "None";
}
Example #10
0
/**
 * Returns true if this level consists of edges with identical,
 * evenly spaced windows.
 */
bool vtLevel::IsUniform() const
{
	int i, edges = NumEdges();
	for (i = 0; i < edges; i++)
	{
		vtEdge *edge = m_Edges[i];
		int windows = edge->NumFeaturesOfCode(WFC_WINDOW);
		int doors = edge->NumFeaturesOfCode(WFC_DOOR);
		int walls = edge->NumFeaturesOfCode(WFC_WALL);
		if (doors > 0)
			return false;
		if (walls != (windows + 1))
			return false;
		if (edge->m_iSlope != 90)
			return false;
//		if (edge->m_Color != RGBi(255, 255, 255))
//			return false;
		if (edge->m_pMaterial != NULL && *edge->m_pMaterial != BMAT_NAME_SIDING)
			return false;
	}
	return true;
}
Example #11
0
float3 Polygon::ClosestPoint(const float3 &point) const
{
    assume(IsPlanar());

    float3 ptOnPlane = PlaneCCW().Project(point);
    if (Contains(ptOnPlane))
        return ptOnPlane;

    float3 closestPt;
    float closestDist = FLOAT_MAX;
    for(int i = 0; i < NumEdges(); ++i)
    {
        float3 pt = Edge(i).ClosestPoint(point);
        float d = pt.DistanceSq(point);
        if (d < closestDist)
        {
            closestPt = pt;
            closestDist = d;
        }
    }
    return ptOnPlane;
}
Example #12
0
void vtLevel::SetRoofType(RoofType rt, int iSlope)
{
	int i, edges = NumEdges();

	if (rt == ROOF_FLAT)
	{
		// all edges are horizontal
		for (i = 0; i < edges; i++)
			m_Edges[i]->m_iSlope = 0;
		m_fStoryHeight = 0.0f;
	}
	if (rt == ROOF_SHED)
	{
		// all edges are vertical
		for (i = 0; i < edges; i++)
			m_Edges[i]->m_iSlope = 90;
		// except for the first edge
		m_Edges[0]->m_iSlope = iSlope;

		DetermineHeightFromSlopes();
	}
	if (rt == ROOF_GABLE)
	{
		// Algorithm for guessing which edges makes up the gable roof:
		if (NumEdges() == 4)
		{
			// In the case of a rectangular footprint, assume that the
			// shorter edge has the gable
			if (GetEdgeLength(1) > GetEdgeLength(0))
			{
				m_Edges[0]->m_iSlope = 90;
				m_Edges[1]->m_iSlope = iSlope;
				m_Edges[2]->m_iSlope = 90;
				m_Edges[3]->m_iSlope = iSlope;
			}
			else
			{
				m_Edges[0]->m_iSlope = iSlope;
				m_Edges[1]->m_iSlope = 90;
				m_Edges[2]->m_iSlope = iSlope;
				m_Edges[3]->m_iSlope = 90;
			}
		}
		else
		{
			// Assume that only convex edges can be gables, and no more than
			// one edge in a row is a gable.  All other edges are hip.
			bool last_gable = false;
			for (i = 0; i < edges; i++)
			{
				if (IsEdgeConvex(i) && !last_gable &&
					!((i == edges - 1) && (m_Edges[0]->m_iSlope == 90)))
				{
					m_Edges[i]->m_iSlope = 90;
					last_gable = true;
				}
				else
				{
					m_Edges[i]->m_iSlope = iSlope;
					last_gable = false;
				}
			}
		}
		DetermineHeightFromSlopes();
	}
	if (rt == ROOF_HIP)
	{
		for (i = 0; i < edges; i++)
			m_Edges[i]->m_iSlope = iSlope;

		DetermineHeightFromSlopes();
	}
}
Example #13
0
void Sweep(Mesh& mesh) {

//    SweepHelper(mesh);

//    ComputeNormals(mesh);

    printf("original vertices: %ld\n", mesh.vertices.size()  );
    printf("original faces: %ld\n", mesh.faces.size()  );

//    printf("original mesh\n"  );

//    mesh.Print();


    HalfEdgeMesh m(mesh);




    /*
    for(auto it = m.beginEdges(); it != m.endEdges(); ++it) {

	glm::vec3 a;
	glm::vec3 b;

	it->GetEdgePoints(a,b);


	printf("Edge: %s ยง %s \n", glm::to_string(a).c_str(), glm::to_string(b).c_str() );
    }
*/

    printf("\n");

    printf("Original vertex size\n");
    printf("Num Faces: %ld\n", m.NumFaces() );
    printf("Num Vertices: %ld\n", m.NumVertices() );
    printf("Num Half Edges: %ld\n", m.NumHalfEdges() );
    printf("Num Edges: %ld\n", m.NumEdges() );
    printf("\n");

    auto it = m.beginEdges();

    for(int i = 0; i < 50; ++i) { // if 20, it hangs. but 50 works
	++it;
    }
//    m.Flip(it);
//    VertexIter v = m.Split(it);
//    m.Split(v->halfEdge->edge);


    VertexIter v  = m.Collapse(it);
    v = m.Collapse(v->halfEdge->edge);
//        m.Split(v->halfEdge->edge);

//        v = m.Collapse(v->halfEdge->edge);



    printf("Modified vertex size\n");
    printf("Num Faces: %ld\n", m.NumFaces() );
    printf("Num Vertices: %ld\n", m.NumVertices() );
    printf("Num Half Edges: %ld\n", m.NumHalfEdges() );
    printf("Num Edges: %ld\n", m.NumEdges() );
    printf("\n");


    printf("COLLAPSED\n");
/*
    it = m.beginEdges();
    for(int i = 0; i < 3; ++i) {
	++it;
    }
    m.Split(it);
*/


    //m.Flip(it);


//    printf("modified vertices: %ld\n", m.vertices.size()  );
//    printf("modified faces: %ld\n", m.faces.size()  );



    for(auto it = m.beginFaces(); it != m.endFaces(); ++it) {
	printf("Face edge count:%d \n", it->NumEdges() );
    }

    for(auto it = m.beginVertices(); it != m.endVertices(); ++it) {
	printf("Vertex degree:%d \n", it->Degree() );
    }




    printf("CONVERT TO MESH:\n");
    Mesh m2 = m.ToMesh();
    printf("MADE TO MESH\n");


/*
    printf("new vertices: %ld\n", m2.vertices.size()  );
    printf("new faces: %ld\n\n", m2.faces.size()  );
*/

//    m2.Print();

    mesh = m2;
    ComputeNormals(mesh);


    /*


      compute normals.

      for all edges, find this info: we need to have the indices of (c,d) for every triangle. (a,b) is already stored in edge ID.
      we keep this in a hash named edgeJacadcenties.(we find this as follows: iterate over all faces, for every edge in that
      face, we already have one of the opposite vertices, so add to pair! we do this for all faces).


      iterate over all faces:
      iterate over all edges, and add SORTED edge to stack(use set to make sure we process all edges only once)

      we keep a set of all added triangles.


      iterate until stack is empty:
      pop edge e of stack.
      if e should be split according to criterion
      split it. so compute midpoint m from (a and b) and add to list.
      now use midpoint to create four new triangles. use all of a,b,c,d to compute normal of m.

      now add all four new edges. BUT WHEN WE SPLIT, ENSURE THAT edgeJacadcenties is properly updated.

      else
      add both triangles(opposite to e), if necessary.

    */

}
Example #14
0
bool Polyhedron::EulerFormulaHolds() const
{
	return NumVertices() + NumFaces() - NumEdges() == 2;
}