Esempio n. 1
0
    double Mesh::ComputeVolume() const
    {
        const size_t nV = GetNPoints();
        const size_t nT = GetNTriangles();
        if (nV == 0 || nT == 0)
        {
            return 0.0;
        }

        Vec3<double> bary(0.0, 0.0, 0.0);
        for (size_t v = 0; v < nV; v++)
        {
            bary +=  GetPoint(v);
        }
        bary /= static_cast<double>(nV);

        Vec3<double> ver0, ver1, ver2;
        double totalVolume = 0.0;
        for(size_t t = 0; t < nT; t++)
        {
            const Vec3<int> & tri = GetTriangle(t);
            ver0 = GetPoint(tri[0]);
            ver1 = GetPoint(tri[1]);
            ver2 = GetPoint(tri[2]);
            totalVolume += ComputeVolume4(ver0, ver1, ver2, bary);
        }
        return totalVolume/6.0;
    }
Esempio n. 2
0
bool ICHull::IsInside(const Vec3<double>& pt0, const double eps)
{
	const Vec3<double> pt(pt0.X(), pt0.Y(), pt0.Z());
	if (m_isFlat)
	{
		size_t nT = m_mesh.m_triangles.GetSize();
		Vec3<double> ver0, ver1, ver2, a, b, c;
		double u, v;
		for (size_t t = 0; t < nT; t++)
		{
			ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
			ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
			ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z();
			ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X();
			ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y();
			ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z();
			ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X();
			ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y();
			ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z();
			a = ver1 - ver0;
			b = ver2 - ver0;
			c = pt - ver0;
			u = c * a;
			v = c * b;
			if (u >= 0.0 && u <= 1.0 && v >= 0.0 && u + v <= 1.0)
			{
				return true;
			}
			m_mesh.m_triangles.Next();
		}
		return false;
	}
	else
	{
		size_t nT = m_mesh.m_triangles.GetSize();
		Vec3<double> ver0, ver1, ver2;
		double vol;
		for (size_t t = 0; t < nT; t++)
		{
			ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X();
			ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y();
			ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z();
			ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X();
			ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y();
			ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z();
			ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X();
			ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y();
			ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z();
			vol = ComputeVolume4(ver0, ver1, ver2, pt);
			if (vol < eps)
			{
				return false;
			}
			m_mesh.m_triangles.Next();
		}
		return true;
	}
}
Esempio n. 3
0
bool ICHull::ComputePointVolume(double& totalVolume, bool markVisibleFaces)
{
	// mark visible faces
	CircularListElement<TMMTriangle>* fHead = m_mesh.GetTriangles().GetHead();
	CircularListElement<TMMTriangle>* f = fHead;
	CircularList<TMMVertex>& vertices = m_mesh.GetVertices();
	CircularListElement<TMMVertex>* vertex0 = vertices.GetHead();
	bool visible = false;
	Vec3<double> pos0 = Vec3<double>(vertex0->GetData().m_pos.X(),
									 vertex0->GetData().m_pos.Y(),
									 vertex0->GetData().m_pos.Z());
	double vol = 0.0;
	totalVolume = 0.0;
	Vec3<double> ver0, ver1, ver2;
	do
	{
		ver0.X() = f->GetData().m_vertices[0]->GetData().m_pos.X();
		ver0.Y() = f->GetData().m_vertices[0]->GetData().m_pos.Y();
		ver0.Z() = f->GetData().m_vertices[0]->GetData().m_pos.Z();
		ver1.X() = f->GetData().m_vertices[1]->GetData().m_pos.X();
		ver1.Y() = f->GetData().m_vertices[1]->GetData().m_pos.Y();
		ver1.Z() = f->GetData().m_vertices[1]->GetData().m_pos.Z();
		ver2.X() = f->GetData().m_vertices[2]->GetData().m_pos.X();
		ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y();
		ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z();
		vol = ComputeVolume4(ver0, ver1, ver2, pos0);
		if (vol < -sc_eps)
		{
			vol = fabs(vol);
			totalVolume += vol;
			if (markVisibleFaces)
			{
				f->GetData().m_visible = true;
				m_trianglesToDelete.PushBack(f);
			}
			visible = true;
		}
		f = f->GetNext();
	} while (f != fHead);

	if (m_trianglesToDelete.Size() == m_mesh.m_triangles.GetSize())
	{
		for (size_t i = 0; i < m_trianglesToDelete.Size(); i++)
		{
			m_trianglesToDelete[i]->GetData().m_visible = false;
		}
		visible = false;
	}
	// if no faces visible from p then p is inside the hull
	if (!visible && markVisibleFaces)
	{
		vertices.Delete();
		m_trianglesToDelete.Resize(0);
		return false;
	}
	return true;
}
Esempio n. 4
0
 bool Mesh::IsInside(const Vec3<double> & pt) const
 {
     const size_t nV = GetNPoints();
     const size_t nT = GetNTriangles();
     if (nV == 0 || nT == 0)
     {
         return false;
     }
     Vec3<double> ver0, ver1, ver2;
     double volume;
     for (size_t t = 0; t < nT; t++)
     {
         const Vec3<int> & tri = GetTriangle(t);
         ver0 = GetPoint(tri[0]);
         ver1 = GetPoint(tri[1]);
         ver2 = GetPoint(tri[2]);
         volume = ComputeVolume4(ver0, ver1, ver2, pt);
         if (volume < 0.0)
         {
             return false;
         }
     }
     return true;
 }
Esempio n. 5
0
ICHullError ICHull::DoubleTriangle()
{
    // find three non colinear points
    m_isFlat = false;
    CircularList<TMMVertex>& vertices = m_mesh.GetVertices();
    CircularListElement<TMMVertex>* v0 = vertices.GetHead();
    while (Colinear(v0->GetData().m_pos,
        v0->GetNext()->GetData().m_pos,
        v0->GetNext()->GetNext()->GetData().m_pos)) {
        if ((v0 = v0->GetNext()) == vertices.GetHead()) {
            return ICHullErrorCoplanarPoints;
        }
    }
    CircularListElement<TMMVertex>* v1 = v0->GetNext();
    CircularListElement<TMMVertex>* v2 = v1->GetNext();
    // mark points as processed
    v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true;

    // create two triangles
    CircularListElement<TMMTriangle>* f0 = MakeFace(v0, v1, v2, 0);
    MakeFace(v2, v1, v0, f0);

    // find a fourth non-coplanar point to form tetrahedron
    CircularListElement<TMMVertex>* v3 = v2->GetNext();
    vertices.GetHead() = v3;

    double vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos);
    while (fabs(vol) < sc_eps && !v3->GetNext()->GetData().m_tag) {
        v3 = v3->GetNext();
        vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos);
    }
    if (fabs(vol) < sc_eps) {
        // compute the barycenter
        Vec3<double> bary(0.0, 0.0, 0.0);
        CircularListElement<TMMVertex>* vBary = v0;
        do {
            bary += vBary->GetData().m_pos;
        } while ((vBary = vBary->GetNext()) != v0);
        bary /= static_cast<double>(vertices.GetSize());

        // Compute the normal to the plane
        Vec3<double> p0 = v0->GetData().m_pos;
        Vec3<double> p1 = v1->GetData().m_pos;
        Vec3<double> p2 = v2->GetData().m_pos;
        m_normal = (p1 - p0) ^ (p2 - p0);
        m_normal.Normalize();
        // add dummy vertex placed at (bary + normal)
        vertices.GetHead() = v2;
        Vec3<double> newPt = bary + m_normal;
        AddPoint(newPt, sc_dummyIndex);
        m_isFlat = true;
        return ICHullErrorOK;
    }
    else if (v3 != vertices.GetHead()) {
        TMMVertex temp;
        temp.m_name = v3->GetData().m_name;
        temp.m_pos = v3->GetData().m_pos;
        v3->GetData().m_name = vertices.GetHead()->GetData().m_name;
        v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos;
        vertices.GetHead()->GetData().m_name = temp.m_name;
        vertices.GetHead()->GetData().m_pos = temp.m_pos;
    }
    return ICHullErrorOK;
}