Exemplo n.º 1
0
Vector3 Mesh::faceNormal(const Point3 &p0, const Point3 &p1, const Point3 &p2)
{
    //
    // ASSIGNMENT (PA04)
    //
    // The points p0, p1, and p2 bound a triangular face in clockwise
    // order. Compute two edges, take their cross product, and
    // normalize the result to get the face normal, which you return.
    //
    // 8 lines in instructor solution (YMMV)
    //

    // Get two edges (DOUBLE CHECK THIS)
    double e0x = p2.u.g.x - p1.u.g.x;
    double e0y = p2.u.g.y - p1.u.g.y;
    double e0z = p2.u.g.z - p1.u.g.z;

    double e1x = p1.u.g.x - p0.u.g.x;
    double e1y = p1.u.g.y - p0.u.g.y;
    double e1z = p1.u.g.z - p0.u.g.z;

    Vector3 edge0(e0x, e0y, e0z);
    Vector3 edge1(e1x, e1y, e1z);

    // Compute their cross product
    Vector3 cross = edge1.cross(edge0);

    // Find the normal
    //double magnitude = cross.mag();
    //Vector3 normal = cross / magnitude;

    return cross.normalized(); // permits template to compile cleanly
}
Exemplo n.º 2
0
double
SurfaceOverlapFacet::projected_overlap( SurfaceOverlapFacet &other_facet, CubitBoolean draw_overlap )
{
  double tmp_double = agt->ProjectedOverlap( t, other_facet.t, draw_overlap );

  if( tmp_double > 0.00 ) 
  {
    CubitVector edge0(t.e0.x, t.e0.y, t.e0.z);  
    CubitVector edge1(t.e1.x, t.e1.y, t.e1.z);  
    CubitVector normal = edge0 * edge1;
    double area_facet1 = normal.length() / 2;

    edge0.set(other_facet.t.e0.x, other_facet.t.e0.y, other_facet.t.e0.z);  
    edge1.set(other_facet.t.e1.x, other_facet.t.e1.y, other_facet.t.e1.z);  
    normal = edge0 * edge1;
    double area_facet2 = normal.length() / 2;
    
    //don't report overlapping area between facets unless it is greater 
    //than one hundredth of the area of the smaller facet
    if( area_facet1 < area_facet2 )
    {
      if( tmp_double < (area_facet1*0.01))
        tmp_double = 0.0;
    }
    else if( tmp_double < (area_facet2*0.01 ))
      tmp_double = 0.0;
  }
  return tmp_double;
}
Exemplo n.º 3
0
Vector3 Mesh::faceNormal(const Point3 &p0, const Point3 &p1, const Point3 &p2)
{
    //
    // Copy your previous (PA04) solution here.
    //
    
    // Get two edges (DOUBLE CHECK THIS)
    double e0x = p2.u.g.x - p1.u.g.x;
    double e0y = p2.u.g.y - p1.u.g.y;
    double e0z = p2.u.g.z - p1.u.g.z;

    double e1x = p1.u.g.x - p0.u.g.x;
    double e1y = p1.u.g.y - p0.u.g.y;
    double e1z = p1.u.g.z - p0.u.g.z;

    Vector3 edge0(e0x, e0y, e0z);
    Vector3 edge1(e1x, e1y, e1z);

    // Compute their cross product
    Vector3 cross = edge1.cross(edge0);

    // Find the normal
    //double magnitude = cross.mag();
    //Vector3 normal = cross / magnitude;

    return cross.normalized(); // permits template to compile cleanly
}
Exemplo n.º 4
0
Foam::label Foam::removePoints::countPointUsage
(
    const scalar minCos,
    boolList& pointCanBeDeleted
) const
{
    // Containers to store two edges per point:
    // -1   : not filled
    // >= 0 : edge label
    // -2   : more than two edges for point
    labelList edge0(mesh_.nPoints(), -1);
    labelList edge1(mesh_.nPoints(), -1);

    const edgeList& edges = mesh_.edges();

    forAll(edges, edgeI)
    {
        const edge& e = edges[edgeI];

        forAll(e, eI)
        {
            label pointI = e[eI];

            if (edge0[pointI] == -2)
            {
                // Already too many edges
            }
            else if (edge0[pointI] == -1)
            {
                // Store first edge using point
                edge0[pointI] = edgeI;
            }
            else
            {
                // Already one edge using point. Check second container.

                if (edge1[pointI] == -1)
                {
                    // Store second edge using point
                    edge1[pointI] = edgeI;
                }
                else
                {
                    // Third edge using point. Mark.
                    edge0[pointI] = -2;
                    edge1[pointI] = -2;
                }
            }
        }
    }
Exemplo n.º 5
0
  bool BSPTree::intersect(Ray &ray, const ISectTri &isecttri, double t_max) const 
  {
    tri_calls++;

    // This is the Möller-Trumbore method
    Vec3d direction(ray.direction);
    Vec3d edge0(isecttri.edge0);
    Vec3d edge1(isecttri.edge1);

    // Ray-triangle intersection
    Vec3d p = cross(direction, edge1);
    double a = dot(edge0, p);
    if(a > -d_eps && a < d_eps)
      return false;

    // Just delay these 
    Vec3d origin(ray.origin);
    Vec3d point0(isecttri.point0);    
    double f = 1.0/a;
    Vec3d s = origin - point0;
    double u = f*dot(s, p);
    if(u < 0.0 || u > 1.0)
      return false;

    Vec3d q = cross(s, edge0);
    double v = f*dot(direction, q);  
    if(v < 0.0 || u + v > 1.0)
      return false;

    double t = f*dot(edge1, q);
    if(t < f_eps || t*t < 1.0e-9)
      return false;
    if(t > t_max)
      return false;
    if(t > ray.dist)
      return false;
  
    ray.dist = t;
    ray.u = u;
    ray.v = v;
    ray.hit_object = (TriMesh*)isecttri.mesh_id;
    ray.hit_face_id = isecttri.tri_id;
    ray.has_hit=true;
    return true; 
  }
Exemplo n.º 6
0
dgFloat32 dgFastRayTest::PolygonIntersect (const dgVector& faceNormal, dgFloat32 maxT, const dgFloat32* const polygon, dgInt32 strideInBytes, const dgInt32* const indexArray, dgInt32 indexCount) const
{
	dgAssert (m_p0.m_w == dgFloat32 (0.0f));
	dgAssert (m_p1.m_w == dgFloat32 (0.0f));

	if (faceNormal.DotProduct(m_unitDir).GetScalar() < dgFloat32 (0.0f)) {
		dgInt32 stride = dgInt32(strideInBytes / sizeof (dgFloat32));
		dgBigVector v0(dgVector(&polygon[indexArray[indexCount - 1] * stride]) & dgVector::m_triplexMask);
		dgBigVector p0(m_p0);
		dgBigVector p0v0(v0 - p0);

		dgBigVector diff(m_diff);
		dgBigVector normal(faceNormal);
		dgFloat64 tOut = normal.DotProduct(p0v0).GetScalar() / normal.DotProduct(diff).GetScalar();
		if ((tOut >= dgFloat64(0.0f)) && (tOut <= maxT)) {
			dgBigVector p (p0 + diff.Scale (tOut));
			dgBigVector unitDir(m_unitDir);
			for (dgInt32 i = 0; i < indexCount; i++) {
				dgInt32 i2 = indexArray[i] * stride;
				dgBigVector v1(dgVector(&polygon[i2]) & dgVector::m_triplexMask);

				dgBigVector edge0(p - v0);
				dgBigVector edge1(v1 - v0);
				dgFloat64 area = unitDir.DotProduct (edge0.CrossProduct(edge1)).GetScalar();
				if (area < dgFloat32 (0.0f)) {
					return 1.2f;
				}
				v0 = v1;
			}

			return dgFloat32(tOut);
		}
	}

	return dgFloat32 (1.2f);
}
Exemplo n.º 7
0
hacd::HaI32 dgPolygonSoupDatabaseBuilder::FilterFace (hacd::HaI32 count, hacd::HaI32* const pool)
{
	if (count == 3) {
		dgBigVector p0 (m_vertexPoints[pool[2]]);
		for (hacd::HaI32 i = 0; i < 3; i ++) {
			dgBigVector p1 (m_vertexPoints[pool[i]]);
			dgBigVector edge (p1 - p0);
			hacd::HaF64 mag2 = edge % edge;
			if (mag2 < hacd::HaF32 (1.0e-6f)) {
				count = 0;
			}
			p0 = p1;
		}

		if (count == 3) {
			dgBigVector edge0 (m_vertexPoints[pool[2]] - m_vertexPoints[pool[0]]);
			dgBigVector edge1 (m_vertexPoints[pool[1]] - m_vertexPoints[pool[0]]);
			dgBigVector normal (edge0 * edge1);
			hacd::HaF64 mag2 = normal % normal;
			if (mag2 < hacd::HaF32 (1.0e-8f)) {
				count = 0;
			}
		}
	} else {
	dgPolySoupFilterAllocator polyhedra;

	count = polyhedra.AddFilterFace (hacd::HaU32 (count), pool);

	if (!count) {
		return 0;
	}

	dgEdge* edge = &polyhedra.GetRoot()->GetInfo();
	if (edge->m_incidentFace < 0) {
		edge = edge->m_twin;
	}

	bool flag = true;
	while (flag) {
		flag = false;
		if (count >= 3) {
			dgEdge* ptr = edge;

			dgBigVector p0 (&m_vertexPoints[ptr->m_incidentVertex].m_x);
			do {
				dgBigVector p1 (&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x);
				dgBigVector e0 (p1 - p0);
				hacd::HaF64 mag2 = e0 % e0;
				if (mag2 < hacd::HaF32 (1.0e-6f)) {
					count --;
					flag = true;
					edge = ptr->m_next;
					ptr->m_prev->m_next = ptr->m_next;
					ptr->m_next->m_prev = ptr->m_prev;
					ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev;
					ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next;
					break;
				}
				p0 = p1;
				ptr = ptr->m_next;
			} while (ptr != edge);
		}
	}
	if (count >= 3) {
		flag = true;
		dgBigVector normal (polyhedra.FaceNormal (edge, &m_vertexPoints[0].m_x, sizeof (dgBigVector)));

		HACD_ASSERT ((normal % normal) > hacd::HaF32 (1.0e-10f)); 
		normal = normal.Scale (dgRsqrt (normal % normal + hacd::HaF32 (1.0e-20f)));

		while (flag) {
			flag = false;
			if (count >= 3) {
				dgEdge* ptr = edge;

				dgBigVector p0 (&m_vertexPoints[ptr->m_prev->m_incidentVertex].m_x);
				dgBigVector p1 (&m_vertexPoints[ptr->m_incidentVertex].m_x);
				dgBigVector e0 (p1 - p0);
				e0 = e0.Scale (dgRsqrt (e0 % e0 + hacd::HaF32(1.0e-10f)));
				do {
					dgBigVector p2 (&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x);
					dgBigVector e1 (p2 - p1);

					e1 = e1.Scale (dgRsqrt (e1 % e1 + hacd::HaF32(1.0e-10f)));
					hacd::HaF64 mag2 = e1 % e0;
					if (mag2 > hacd::HaF32 (0.9999f)) {
						count --;
						flag = true;
						edge = ptr->m_next;
						ptr->m_prev->m_next = ptr->m_next;
						ptr->m_next->m_prev = ptr->m_prev;
						ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev;
						ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next;
						break;
					}

					dgBigVector n (e0 * e1);
					mag2 = n % normal;
					if (mag2 < hacd::HaF32 (1.0e-5f)) {
						count --;
						flag = true;
						edge = ptr->m_next;
						ptr->m_prev->m_next = ptr->m_next;
						ptr->m_next->m_prev = ptr->m_prev;
						ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev;
						ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next;
						break;
					}

					e0 = e1;
					p1 = p2;
					ptr = ptr->m_next;
				} while (ptr != edge);
			}
		}
	}

	dgEdge* first = edge;
	if (count >= 3) {
		hacd::HaF64 best = hacd::HaF32 (2.0f);
		dgEdge* ptr = edge;

		dgBigVector p0 (&m_vertexPoints[ptr->m_incidentVertex].m_x);
		dgBigVector p1 (&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x);
		dgBigVector e0 (p1 - p0);
		e0 = e0.Scale (dgRsqrt (e0 % e0 + hacd::HaF32(1.0e-10f)));
		do {
			dgBigVector p2 (&m_vertexPoints[ptr->m_next->m_next->m_incidentVertex].m_x);
			dgBigVector e1 (p2 - p1);

			e1 = e1.Scale (dgRsqrt (e1 % e1 + hacd::HaF32(1.0e-10f)));
			hacd::HaF64 mag2 = fabs (e1 % e0);
			if (mag2 < best) {
				best = mag2;
				first = ptr;
			}

			e0 = e1;
			p1 = p2;
			ptr = ptr->m_next;
		} while (ptr != edge);

		count = 0;
		ptr = first;
		do {
			pool[count] = ptr->m_incidentVertex;
			count ++;
			ptr = ptr->m_next;
		} while (ptr != first);
	}

#ifdef _DEBUG
	if (count >= 3) {
		hacd::HaI32 j0 = count - 2;  
		hacd::HaI32 j1 = count - 1;  
		dgBigVector normal (polyhedra.FaceNormal (edge, &m_vertexPoints[0].m_x, sizeof (dgBigVector)));
		for (hacd::HaI32 j2 = 0; j2 < count; j2 ++) { 
			dgBigVector p0 (&m_vertexPoints[pool[j0]].m_x);
			dgBigVector p1 (&m_vertexPoints[pool[j1]].m_x);
			dgBigVector p2 (&m_vertexPoints[pool[j2]].m_x);
			dgBigVector e0 ((p0 - p1));
			dgBigVector e1 ((p2 - p1));

			dgBigVector n (e1 * e0);
			HACD_ASSERT ((n % normal) > hacd::HaF32 (0.0f));
			j0 = j1;
			j1 = j2;
		}
	}
#endif
	}

	return (count >= 3) ? count : 0;
}
Exemplo n.º 8
0
void dgPolygonSoupDatabaseBuilder::AddMesh (const hacd::HaF32* const vertex, hacd::HaI32 vertexCount, hacd::HaI32 strideInBytes, hacd::HaI32 faceCount,	
	const hacd::HaI32* const faceArray, const hacd::HaI32* const indexArray, const hacd::HaI32* const faceTagsData, const dgMatrix& worldMatrix) 
{
	hacd::HaI32 faces[256];
	hacd::HaI32 pool[2048];


	m_vertexPoints[m_vertexCount + vertexCount].m_x = hacd::HaF64 (0.0f);
	dgBigVector* const vertexPool = &m_vertexPoints[m_vertexCount];

	worldMatrix.TransformTriplex (&vertexPool[0].m_x, sizeof (dgBigVector), vertex, strideInBytes, vertexCount);
	for (hacd::HaI32 i = 0; i < vertexCount; i ++) {
		vertexPool[i].m_w = hacd::HaF64 (0.0f);
	}

	hacd::HaI32 totalIndexCount = faceCount;
	for (hacd::HaI32 i = 0; i < faceCount; i ++) {
		totalIndexCount += faceArray[i];
	}

	m_vertexIndex[m_indexCount + totalIndexCount] = 0;
	m_faceVertexCount[m_faceCount + faceCount] = 0;

	hacd::HaI32 k = 0;
	for (hacd::HaI32 i = 0; i < faceCount; i ++) {
		hacd::HaI32 count = faceArray[i];
		for (hacd::HaI32 j = 0; j < count; j ++) {
			hacd::HaI32 index = indexArray[k];
			pool[j] = index + m_vertexCount;
			k ++;
		}

		hacd::HaI32 convexFaces = 0;
		if (count == 3) {
			convexFaces = 1;
			dgBigVector p0 (m_vertexPoints[pool[2]]);
			for (hacd::HaI32 i = 0; i < 3; i ++) {
				dgBigVector p1 (m_vertexPoints[pool[i]]);
				dgBigVector edge (p1 - p0);
				hacd::HaF64 mag2 = edge % edge;
				if (mag2 < hacd::HaF32 (1.0e-6f)) {
					convexFaces = 0;
				}
				p0 = p1;
			}

			if (convexFaces) {
				dgBigVector edge0 (m_vertexPoints[pool[2]] - m_vertexPoints[pool[0]]);
				dgBigVector edge1 (m_vertexPoints[pool[1]] - m_vertexPoints[pool[0]]);
				dgBigVector normal (edge0 * edge1);
				hacd::HaF64 mag2 = normal % normal;
				if (mag2 < hacd::HaF32 (1.0e-8f)) {
					convexFaces = 0;
				}
			}

			if (convexFaces) {
				faces[0] = 3;
			}

		} else {
			convexFaces = AddConvexFace (count, pool, faces);
		}

		hacd::HaI32 index = 0;
		for (hacd::HaI32 k = 0; k < convexFaces; k ++) {
			hacd::HaI32 count = faces[k];
			m_vertexIndex[m_indexCount] = faceTagsData[i];
			m_indexCount ++;
			for (hacd::HaI32 j = 0; j < count; j ++) {
				m_vertexIndex[m_indexCount] = pool[index];
				index ++;
				m_indexCount ++;
			}
			m_faceVertexCount[m_faceCount] = count + 1;
			m_faceCount ++;
		}
	}
	m_vertexCount += vertexCount;
	m_run -= vertexCount;
	if (m_run <= 0) {
		PackArray();
	}
}
Exemplo n.º 9
0
HE_Mesh::HE_Mesh(FVMesh& mesh)
: Mesh(nullptr)
{
    for (int vIdx = 0 ; vIdx < mesh.vertices.size() ; vIdx++)
    {
        vertices.push_back(HE_Vertex(mesh.vertices[vIdx].p, -1));
    }

    for (int fIdx = 0 ; fIdx < mesh.faces.size() ; fIdx++)
    {
        FVMeshFace& fvFace = mesh.faces[fIdx];
        HE_Face heFace;
        HE_Edge edge0(fvFace.vertex_index[0], fIdx); // vertices in face are ordered counter-clockwise
        HE_Edge edge1(fvFace.vertex_index[1], fIdx);
        HE_Edge edge2(fvFace.vertex_index[2], fIdx);

        int newEdgeIndex = edges.size();

        vertices[ fvFace.vertex_index[0] ].someEdge_idx = newEdgeIndex+0; // overwrites existing data, if present
        vertices[ fvFace.vertex_index[1] ].someEdge_idx = newEdgeIndex+1;
        vertices[ fvFace.vertex_index[2] ].someEdge_idx = newEdgeIndex+2;

        edge0.next_edge_idx = newEdgeIndex+1;
        edge1.next_edge_idx = newEdgeIndex+2;
        edge2.next_edge_idx = newEdgeIndex+0;

        edges.push_back(edge0);
        edges.push_back(edge1);
        edges.push_back(edge2);

        heFace.edge_idx[0] = newEdgeIndex+0;
        heFace.edge_idx[1] = newEdgeIndex+1;
        heFace.edge_idx[2] = newEdgeIndex+2;
        faces.push_back(heFace);

    }


    // connect half-edges:

    bool faceEdgeIsConnected[mesh.faces.size()][3] = {}; // initialize all as false


    // for each edge of each face : if it doesn't have a converse then find the converse in the edges of the opposite face
    for (int fIdx = 0 ; fIdx < mesh.faces.size() ; fIdx++)
    {
        FVMeshFace& fvFace = mesh.faces[fIdx];
        //FVMeshFaceHandle fh(mesh, fIdx);

        HE_FaceHandle fnew(*this, fIdx); // face index on FVMesh corresponds to index in HE_Mesh

//        HE_EdgeHandle edge = fnew.edge0();
//        HE_EdgeHandle edgeStart = edge;
//        do //
        for (int eIdx = 0; eIdx < 3; eIdx++)
        {
            if (faceEdgeIsConnected[fIdx][eIdx])
                { // edge.next();
                continue; }

            int edge_idx = faces[fIdx].edge_idx[eIdx];
            HE_Edge& edge = edges[ edge_idx ];
            int face2 = fvFace.connected_face_index[eIdx]; // connected_face X is connected via vertex X and vertex X+1

            if (face2 < 0)
            {
                atlas::logError("Incorrect model: disconnected faces. Support generation aborted.\n");
                exit(1); // TODO: not exit, but continue without support!
            }

            for (int e2 = 0; e2 < 3; e2++)
            {
                if (mesh.faces[face2].vertex_index[e2] == edges[edge.next_edge_idx].from_vert_idx)
                {
                    edges[ faces[face2].edge_idx[e2] ].converse_edge_idx = edge_idx;
                    edge.converse_edge_idx = faces[face2].edge_idx[e2];
                    faceEdgeIsConnected[face2][e2] = true; // the other way around doesn't have to be set; we will not pass the same edge twice
                    break;
                }
                if (e2 == 2) std::cerr << "Couldn't find converse of edge " << std::to_string(edge_idx) <<"!!!!!" << std::endl;
            }


            //edge = edge.next();
        } //while (edge != edgeStart)

    }

    HE_MESH_DEBUG_DO(
        mesh.debugOutputWholeMesh();
     )

}