Daniel,

I'm attaching the updated patch. I had missed something in the earlier one.

Regards,
Rakshika.
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 68040)
+++ CMakeLists.txt	(working copy)
@@ -20,6 +20,15 @@
   util.cpp
   volume.c
   voxels.c
+  MeshHealing/DCEL.h
+  MeshHealing/MeshConversion_brlcad.h
+  MeshHealing/MeshConversion_brlcad.cpp
+  MeshHealing/MeshConversion.h
+  MeshHealing/MeshConversion.cpp
+  MeshHealing/Zipper.h
+  MeshHealing/Zipper.cpp
+  MeshHealing/Geometry.h
+  MeshHealing/Geometry.cpp
   )
 
 add_subdirectory(tests)
Index: MeshHealing/DCEL.h
===================================================================
--- MeshHealing/DCEL.h	(revision 0)
+++ MeshHealing/DCEL.h	(working copy)
@@ -0,0 +1,40 @@
+#include <utility>
+
+struct DCEL_Edge;
+
+/* DCEL_Vertex record of a doubly-connected DCEL_Edge list includes:
+	1. DCEL_Vertex ID
+	2. Coordinates
+	3. An arbitrary incident DCEL_Edge - one with the particular DCEL_Vertex as its origin 
+*/
+struct DCEL_Vertex {
+	int vertex_id;
+	double coordinates[3];
+	DCEL_Edge* incident_edge;
+};
+
+/* DCEL_Face record of a doubly-connected DCEL_Edge list includes:
+	1. DCEL_Face ID,
+	2. ID of any DCEL_Edge that can be used to traverse the DCEL_Face in counter-clockwise order
+ */
+struct DCEL_Face {
+	int face_id;
+	DCEL_Edge* start_edge;
+};
+
+/* The half-DCEL_Edge record of a doubly-connected DCEL_Edge list includes:
+	1. DCEL_Edge ID
+	2. ID of the origin DCEL_Vertex
+	3. ID of the twin DCEL_Edge
+	4. ID of the incident DCEL_Face - DCEL_Face to its left (since we orient the faces in counter-clockwise order)
+	5. ID of the previous DCEL_Edge in the incident DCEL_Face
+	6. ID of the next DCEL_Edge in the incident DCEL_Face
+ */
+struct DCEL_Edge {
+	std::pair<int, int> edge_id;
+	DCEL_Vertex* origin;
+	DCEL_Edge* twin;
+	DCEL_Face* incident_face;
+	DCEL_Edge* next;
+	DCEL_Edge* previous;
+};
Index: MeshHealing/Geometry.cpp
===================================================================
--- MeshHealing/Geometry.cpp	(revision 0)
+++ MeshHealing/Geometry.cpp	(working copy)
@@ -0,0 +1,124 @@
+#include "Geometry.h"
+
+#include <cmath>
+
+/* Calculates the determinant of a 3x3 matrix */
+double calcDet(double m[3][3])
+{
+
+	double d;
+
+	d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]);
+	d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]);
+	d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]);
+
+	return d;
+}
+
+double* findOrthogonalProjection(double *A, double *B, double *C)
+{
+	/* Parameter in the line equation of AB */
+	double t;
+
+	double BA[3], CA[3];
+	double *D = new double[3];
+
+	for (int i = 0; i < 3; ++i) {
+
+		BA[i] = B[i] - A[i];
+		CA[i] = C[i] - A[i];
+	}
+
+	/* Finding parameter t for a point D on line AB such that AB and DC are perpendicular to each other using this formula: t = dot(B-A, C-A)/dot(B-A, B-A) */
+
+	t = DOT_PROD(BA, CA) / DOT_PROD(BA, BA);
+
+	/* t=0 and t=1 correspond to the end points */
+	if(t < 0)
+		t = 0;
+	else if(t > 1)
+		t = 1;
+
+	for (int i = 0; i < 3; ++i) {
+		D[i] = A[i] + t * BA[i];
+	}
+
+	return D;
+}
+
+bool isOrthoProjPossible(double *A, double *B, double *C)
+{
+	/* Parameter in the line equation of AB */
+	double t;
+
+	double BA[3], CA[3];
+
+	for (int i = 0; i < 3; ++i) {
+
+		BA[i] = B[i] - A[i];
+		CA[i] = C[i] - A[i];
+	}
+
+	/* Finding parameter t for a point D on line AB such that AB and DC are perpendicular to each other using this formula: t = dot(B-A, C-A)/dot(B-A, B-A) */
+
+	t = DOT_PROD(BA, CA) / DOT_PROD(BA, BA);
+
+	if(t > 0 && t < 1)
+		return true;
+
+	return false;
+}
+
+double shortestDistBwPoints(double *A, double *B)
+{
+	double dist = 0;
+	for(int i = 0; i < 3; i++) {
+		dist += (A[i] - B[i]) * (A[i] - B[i]);
+	}
+	dist = sqrt(dist);
+
+	return dist;
+}
+
+double shortestDistToLine(double *A, double *B, double *C)
+{
+	double dist;
+
+	dist = shortestDistBwPoints(C, findOrthogonalProjection(A, B, C));
+
+	return dist;
+}
+
+bool checkIfIntersects(double* A, double* B, double* C, double* D)
+{
+	int o1, o2, o3, o4;
+	o1 = orientation(A, B, C);
+	o2 = orientation(A, B, D);
+	o3 = orientation(C, D, A);
+	o4 = orientation(C, D, B);
+
+	if(o1 != o2 && o3 != o4)
+		return true;
+
+	return false;
+}
+
+int orientation(double* P, double* Q, double* R)
+{
+	double m[3][3];
+	double det;
+	for(int i = 0; i < 3; i++) {
+		m[0][i] = P[i];
+		m[1][i] = Q[i];
+		m[2][i] = R[i];
+	}
+
+	det = calcDet(m);
+
+	if(det > 0)
+		return CW;
+	else if(det < 0)
+		return CCW;
+	else
+		return COLL;
+}
Index: MeshHealing/Geometry.h
===================================================================
--- MeshHealing/Geometry.h	(revision 0)
+++ MeshHealing/Geometry.h	(working copy)
@@ -0,0 +1,40 @@
+#ifndef SRC_LIBANALYZE_MESHHEALING_GEOMETRY_H_
+#define SRC_LIBANALYZE_MESHHEALING_GEOMETRY_H_
+
+
+
+
+
+#endif /* SRC_LIBANALYZE_MESHHEALING_GEOMETRY_H_ */
+
+#define COLL 0
+#define CW 1
+#define CCW 2
+#define DOT_PROD(A, B) \
+	A[0] * B[0] \
+	+ A[1] * B[1] \
+	+ A[2] * B[2]
+
+/* Finds the orthogonal projection of a point C on a line segment formed by points A and B */
+double* findOrthogonalProjection(double *A, double *B, double *C);
+
+/* Returns true if orthogonal projection of C on the line segment AB is possible, false otherwise. */
+bool isOrthoProjPossible(double *A, double *B, double *C);
+
+/* Returns the shortest distance between the two points */
+double shortestDistBwPoints(double *A, double *B);
+
+/* Returns the shortest distance between a point A and a line segment BC */
+double shortestDistToLine(double *A, double *B, double *C);
+
+/* Checks if line segment AB and CD intersect */
+bool checkIfIntersects(double *A, double *B, double *C, double *D);
+
+/* To check the orientation of the triangle formed by the three points P, Q, and R
+ * 0 - Collinear
+ * 1 - Clockwise
+ * 2 - Counter-clockwise*/
+int orientation(double *P, double *Q, double *R);
+
+/* Calculates the determinant of the 3x3 matrix m */
+double calcDet(double m[3][3]);
Index: MeshHealing/MeshConversion.cpp
===================================================================
--- MeshHealing/MeshConversion.cpp	(revision 0)
+++ MeshHealing/MeshConversion.cpp	(working copy)
@@ -0,0 +1,393 @@
+#include "MeshConversion.h"
+#include "Geometry.h"
+
+#include <cstddef>
+#include <iterator>
+#include <limits>
+
+/* Vertex record function */
+
+void PolygonalMesh::initIncidentEdge()
+{
+
+	unsigned int num_vertices = this->getNumVertices();
+
+	for (unsigned int i = 0; i < num_vertices; ++i)
+	{
+		for (unsigned int j = 0; j < edgelist.size(); ++j)
+		{
+			if(vertexlist[i].vertex_id == edgelist[i].origin->vertex_id) {
+				vertexlist[i].incident_edge = &(edgelist[i]);
+				break;
+			}
+		}
+	}
+}
+
+/* Face record function */
+
+void PolygonalMesh::initFaces()
+{
+	unsigned int num_faces = this->getNumFaces();
+	for (unsigned int i = 0; i <= num_faces; i++) {
+		facelist[i].face_id = i;
+	}
+}
+
+/* Edge record functions */
+
+void PolygonalMesh::initTwinEdge()
+{
+
+	for (unsigned int i = 0; i < edgelist.size(); ++i) {
+		for (unsigned int j = 0; j < edgelist.size(); j++) {
+
+			if(edgelist[i].edge_id.first == edgelist[j].edge_id.second && edgelist[j].edge_id.first == edgelist[i].edge_id.second) {
+				
+				edgelist[i].twin = &(edgelist[j]);
+				break;
+			}
+		}
+	}
+}
+
+/* Getters and setters */
+
+DCEL_Vertex* PolygonalMesh::getVertex(int ID)
+{
+	if(ID < (signed int)vertexlist.size())
+		return &vertexlist[ID];
+	return NULL;
+}
+
+void PolygonalMesh::setVertexCoordsInRecord(int ID, double *coordinates)
+{
+	if(ID < (signed int)vertexlist.size()) {
+		vertexlist[ID].coordinates[0] = coordinates[0];
+		vertexlist[ID].coordinates[1] = coordinates[1];
+		vertexlist[ID].coordinates[2] = coordinates[2];
+
+		setVertexCoords(ID);
+	}
+}
+
+void PolygonalMesh::setVertexRecord(DCEL_Vertex *v1, DCEL_Vertex *v2)
+{
+	for (unsigned int i = 0; i < edgelist.size(); ++i)
+	{
+		/* Edges whose origin is v2 */
+		if(edgelist[i].origin->vertex_id == v2->vertex_id) {
+			edgelist[i].origin = v1;
+			edgelist[i].edge_id.first = v1->vertex_id;
+		}
+
+		/* Edges that end at v2 */
+		if(edgelist[i].edge_id.second == v2->vertex_id) {
+			edgelist[i].edge_id.second = v1->vertex_id;
+		}
+	}
+	setVertex(v1->vertex_id, v2->vertex_id);
+}
+
+void PolygonalMesh::deleteVertexRecord(int ID)
+{
+	int inc_face_id;
+
+	deleteVertex(ID);
+	/* Delete the vertex record with vertex id=ID. */
+	if(ID < (signed int)vertexlist.size()) {
+		vertexlist.erase(vertexlist.begin() + ID);
+		setNumVertices();
+	}
+
+	/* Deleting the edges that contain the vertex */
+	for (unsigned int i = 0; i < edgelist.size(); ++i) {
+		
+		if(edgelist[i].edge_id.first == ID || edgelist[i].edge_id.second == ID) {
+			edgelist.erase(edgelist.begin() + i);
+
+			/* Delete the face that this edge is incident on as well */
+			inc_face_id = edgelist[i].incident_face->face_id;
+			deleteFace(inc_face_id);
+			facelist.erase(facelist.begin() + inc_face_id);
+
+			setNumFaces();
+
+			/* Set the incident face of the edge to the unbounded face */
+			edgelist[i].incident_face = &facelist[getNumFaces()];
+		}
+	}
+}
+
+void PolygonalMesh::insertVertexOnEdge(DCEL_Vertex *vertex, DCEL_Edge *edge)
+{
+	/* edge11 and edge12 make up the edge passed as argument. edge21 and edge 22 make up the twin_edge */
+
+	DCEL_Edge edge11, edge12, edge21, edge22, *twin_edge;
+
+	vertex->incident_edge = &edge12;
+	
+	edge11.origin = edge->origin;
+	edge11.next = &edge12;
+	edge11.previous = edge->previous;
+	edge11.incident_face = edge->incident_face;
+
+	edge12.origin = vertex;
+	edge12.next = edge->next;
+	edge12.previous = &edge11;
+	edge12.incident_face = edge->incident_face;
+
+	edge->previous->next = &edge11;
+	edge->next->previous = &edge12;
+
+	/* If the edge was the starting edge of its incident face, change it to either one of the two new edges */
+	if(edge->incident_face->start_edge->edge_id.first == edge->edge_id.first)
+		edge->incident_face->start_edge = &edge11;
+	
+
+	twin_edge = edge->twin;
+
+	edge21.origin = twin_edge->origin;
+	edge21.next = &edge22;
+	edge21.previous = twin_edge->previous;
+	edge21.incident_face = twin_edge->incident_face;
+
+	edge22.origin = vertex;
+	edge22.next = twin_edge->next;
+	edge22.previous = &edge21;
+	edge22.incident_face = twin_edge->incident_face;
+
+	twin_edge->previous->next = &edge21;
+	twin_edge->next->previous = &edge22;
+
+	/* If the edge was the starting edge of its incident face, change it to either one of the two new edges */
+	if(twin_edge->incident_face->start_edge->edge_id.first == twin_edge->edge_id.first)
+		twin_edge->incident_face->start_edge = &edge11;
+
+	edge11.twin = &edge22;
+	edge21.twin = &edge12;
+	edge12.twin = &edge21;
+	edge22.twin = &edge11;
+
+
+	/* Delete the argument edge and its twin */
+	deleteEdge(std::make_pair(edge->edge_id.first, edge->edge_id.second));
+	deleteEdge(std::make_pair(edge->edge_id.second, edge->edge_id.first));
+}
+
+void PolygonalMesh::deleteEdge(std::pair<int, int> ID)
+{
+	for (unsigned int i = 0; i < edgelist.size(); ++i) {
+		
+		if(ID.first == edgelist[i].edge_id.first && ID.second == edgelist[i].edge_id.second) {
+			edgelist.erase(edgelist.begin() + i);
+		}
+	}
+}
+
+void PolygonalMesh::splitFace(int face_id, DCEL_Vertex *vertex, DCEL_Vertex *opp_vertex)
+{
+	DCEL_Edge *start_edge1, *start_edge2;
+	DCEL_Edge *new_edge1, *new_edge2;
+	/* Indices of the newly added faces */
+	int face1, face2;
+
+	/* Find the two starting edges of the resultant faces */
+	for (unsigned int i = 0; i < edgelist.size(); ++i) {
+
+		if(edgelist[i].edge_id.first == vertex->vertex_id) {
+
+			if(edgelist[i].incident_face->face_id == face_id)
+				start_edge1 = &edgelist[i];
+			else
+				start_edge2 = &edgelist[i];
+		}
+
+		if(start_edge1 != NULL && start_edge2 != NULL)
+			break;
+	}
+
+	face1 = addFaceRecord(start_edge1);
+	face2 = addFaceRecord(start_edge2);
+
+	/* Create two half edges from the vertex passed as argument and the vertex opposite to the edge it is present on */
+	new_edge1 = addEdge(std::make_pair(vertex->vertex_id, opp_vertex->vertex_id), vertex, NULL, &facelist[face1], start_edge1->previous, start_edge1);
+	new_edge2 = addEdge(std::make_pair(opp_vertex->vertex_id, vertex->vertex_id), opp_vertex, NULL, &facelist[face2], start_edge2, start_edge2->next);
+
+	new_edge1->twin = new_edge2;
+	new_edge2->twin = new_edge1;
+
+	deleteFaceRecord(face_id);
+}
+
+int PolygonalMesh::addFaceRecord(DCEL_Edge *start_edge)
+{
+	int last_face_id = facelist.back().face_id;
+	DCEL_Face new_face;
+	new_face.face_id = last_face_id + 1;
+	new_face.start_edge = start_edge;
+
+	facelist.push_back(new_face);
+
+	addFace(new_face.face_id);
+
+	return last_face_id + 1;
+}
+
+void PolygonalMesh::deleteDuplicateEdges()
+{
+	for (unsigned int i = 0; i < edgelist.size(); ++i) {
+
+		if(edgelist[i].incident_face->face_id == UNBOUNDED_FACE)
+			continue;
+
+		for (unsigned int j = 0; j < edgelist.size(); ++j) {
+
+			/* Looking for the duplicate half edge whose incident face will be the unbounded face */
+			if(edgelist[i].edge_id.first == edgelist[j].edge_id.first && edgelist[i].edge_id.second == edgelist[j].edge_id.second) {
+				edgelist.erase(edgelist.begin() + j);
+			}
+		}
+	}
+}
+
+DCEL_Edge* PolygonalMesh::addEdge(std::pair<int, int> edge_id, DCEL_Vertex *origin, DCEL_Edge *twin, DCEL_Face *inc_face, DCEL_Edge *next, DCEL_Edge *prev)
+{
+	DCEL_Edge *new_edge = new DCEL_Edge;
+	new_edge->edge_id = edge_id;
+	new_edge->origin = origin;
+	new_edge->twin = twin;
+	new_edge->incident_face = inc_face;
+	new_edge->next = next;
+	new_edge->previous = prev;
+	return new_edge;
+}
+
+void PolygonalMesh::deleteFaceRecord(int face_id)
+{
+	facelist.erase(facelist.begin() + face_id);
+	deleteFace(face_id);
+}
+
+DCEL_Edge* PolygonalMesh::getEdge(std::pair<int, int> ID)
+{
+	for(unsigned int i = 0; i < edgelist.size(); i++) {
+		if(edgelist[i].edge_id.first == ID.first && edgelist[i].edge_id.second == ID.second)
+			return &edgelist[i];
+	}
+	return NULL;
+}
+
+int PolygonalMesh::addVertexRecord(double *coordinates)
+{
+	int last_vertex_id = vertexlist[vertexlist.size() - 1].vertex_id;
+	DCEL_Vertex new_vertex;
+	new_vertex.vertex_id = last_vertex_id + 1;
+
+	new_vertex.coordinates[0] = coordinates[0];
+	new_vertex.coordinates[1] = coordinates[1];
+	new_vertex.coordinates[2] = coordinates[2];
+
+	vertexlist.push_back(new_vertex);
+
+	addVertex(new_vertex.vertex_id);
+
+	return last_vertex_id + 1;
+}
+
+DCEL_Edge* PolygonalMesh::findClosestEdge(DCEL_Vertex *vertex)
+{
+	double min_dist = std::numeric_limits<int>::max();
+	double dist;
+	double *ortho_proj;
+	DCEL_Edge *edge;
+	DCEL_Face *face;
+	DCEL_Edge *prev, *next;
+	int v1, v2;
+	bool is_eligible = true;
+
+	for (unsigned int i = 0; i < edgelist.size(); ++i) {
+		/* The edge should have the unbounded face incident on it */
+		if(edgelist[i].incident_face->face_id != UNBOUNDED_FACE)
+			continue;
+
+		/* The edge should not be incident on the vertex itself */
+		if(edgelist[i].edge_id.first == vertex->vertex_id || edgelist[i].edge_id.second == vertex->vertex_id)
+			continue;
+
+		/* Line joining the vertex to the edge should not cross any bounded face */
+
+		/* If the face incident on this edge/ or its twin contains the vertex, then it will cross a bounded face */
+		face = edgelist[i].incident_face;
+		if(isVertexInFace(vertex->vertex_id, face->face_id))
+			continue;
+
+		face = edgelist[i].twin->incident_face;
+		if(isVertexInFace(vertex->vertex_id, face->face_id))
+			continue;
+
+		do {
+
+			if(isVertexInFace(vertex->vertex_id, face->face_id)) {
+				is_eligible = false;
+				break;
+			}
+			ortho_proj = findOrthogonalProjection(getVertex(edgelist[i].edge_id.first)->coordinates, getVertex(edgelist[i].edge_id.second)->coordinates, vertex->coordinates);
+
+			/* Get the other two edges in the triangle and check if the line from the vertex to the edge intersects either of them
+			 * If it does, get the edge incident on the twin and check for the above condition
+			 */
+			prev = edgelist[i].previous;
+			next = edgelist[i].next;
+
+			v1 = prev->edge_id.first;
+			v2 = prev->edge_id.second;
+
+			if(checkIfIntersects(vertex->coordinates, ortho_proj, getVertex(v1)->coordinates, getVertex(v2)->coordinates)) {
+				face = prev->twin->incident_face;
+			}
+
+			else {
+				v1 = next->edge_id.first;
+				v2 = next->edge_id.second;
+
+				if(checkIfIntersects(vertex->coordinates, ortho_proj, getVertex(v1)->coordinates, getVertex(v2)->coordinates)) {
+					face = next->twin->incident_face;
+				}
+				else
+					break;
+			}
+		}
+		while(true);
+
+		if(!is_eligible)
+			continue;
+
+		dist = shortestDistBwPoints(vertex->coordinates, ortho_proj);
+
+		if(dist < min_dist) {
+			min_dist = dist;
+			edge = &edgelist[i];
+		}
+	}
+	return edge;
+}
+
+DCEL_Face* PolygonalMesh::getFace(int ID)
+{
+	return &facelist[ID];
+}
+
+bool PolygonalMesh::isVertexInFace(int vertex_id, int face_id)
+{
+	DCEL_Edge *edge = getFace(face_id)->start_edge;
+	if(face_id == UNBOUNDED_FACE)
+		return false;
+
+	for(int i = 0; i < 3; i++) {
+		if(edge->edge_id.first == vertex_id)
+			return true;
+		edge = edge->next;
+	}
+	return false;
+}
Index: MeshHealing/MeshConversion.h
===================================================================
--- MeshHealing/MeshConversion.h	(revision 0)
+++ MeshHealing/MeshConversion.h	(working copy)
@@ -0,0 +1,113 @@
+#include <utility>
+#include <vector>
+
+#include "DCEL.h"
+#include "Geometry.h"
+
+#define VERTICES_PER_FACE 3
+#define UNBOUNDED_FACE 0
+
+
+class PolygonalMesh {
+
+protected:
+	
+	/* DCEL records */	
+	std::vector<DCEL_Vertex> vertexlist;
+	std::vector<DCEL_Face> facelist;
+	std::vector<DCEL_Edge> edgelist;
+
+	/* Virtual functions to update the native structures */
+
+
+
+	/* DCEL_Vertex record functions 
+	*/
+
+	/* Returns number of vertices */
+	virtual int getNumVertices() = 0;
+	/* Sets the DCEL_Vertex IDs and coordinates for all the vertices */
+	virtual void initVertices() = 0;
+	/* For every DCEL_Vertex, sets an arbitrary DCEL_Vertex incident on it */
+	void initIncidentEdge();
+
+	/* DCEL_Face record functions 
+	*/
+
+	/* Returns number of faces */
+	virtual int getNumFaces() = 0;
+	/* Sets a DCEL_Face ID for each DCEL_Face */
+	void initFaces();
+	/* Sets an arbitrary DCEL_Edge that is a prt of the DCEL_Face, so that that it can be traversed in counter-clockwise order */ 
+	virtual void initStartEdge() = 0;
+
+	/* DCEL_Edge record functions 
+	*/
+
+	/* Sets DCEL_Edge ID and the origin of the DCEL_Edge */
+	virtual void initEdges() = 0;
+
+	/* Sets the DCEL_Face to the half-DCEL_Edge's left */
+	virtual void initIncidentFace() = 0;
+
+	/* Sets the twin DCEL_Edge of the half-DCEL_Edge */
+	void initTwinEdge();
+
+	/* Sets the DCEL_Edge previous to this DCEL_Edge in the incident DCEL_Face */
+	virtual void initPrevEdge() = 0;
+
+	/* Sets the DCEL_Edge next to this DCEL_Edge in the incident DCEL_Face */
+	virtual void initNextEdge() = 0;
+
+	virtual void setNumVertices() = 0;
+	virtual void setNumFaces() = 0;
+	virtual void setVertices() = 0;
+	virtual void setVertexCoords(int ID) = 0;
+	virtual void setVertex(int v1, int v2) = 0;
+	virtual void deleteVertex(int ID) = 0;
+	virtual void setFaces() = 0;
+	virtual void deleteFace(int ID) = 0;
+	virtual void addFace(int ID) = 0;
+	virtual void addVertex(int ID) = 0;
+
+public:
+
+	/* Getters and setters */
+
+	/* Get vertex with vertex id=ID */
+	DCEL_Vertex* getVertex(int ID);
+	/* Get edge with edge id=ID */
+	DCEL_Edge* getEdge(std::pair<int, int> ID);
+	/* Get face with face id=ID */
+	DCEL_Face* getFace(int ID);
+	/* Set the coordinates of the vertex with vertex id=ID */
+	void setVertexCoordsInRecord(int ID, double *coordinates);
+	/* Replace all references of vertex v2 with v1 */
+	void setVertexRecord(DCEL_Vertex *v1, DCEL_Vertex *v2);
+	/* Deletes a vertex with vertex id=ID */
+	void deleteVertexRecord(int ID);
+	/* Insert a vertex on the half edge */
+	void insertVertexOnEdge(DCEL_Vertex *vertex, DCEL_Edge *edge);
+	/* Deletes edge with edge id=ID */
+	void deleteEdge(std::pair<int, int> ID);
+	/* Split the face through the line joining the given vertex (on an edge) to the opposite vertex */
+	void splitFace(int face_id, DCEL_Vertex *vertex, DCEL_Vertex *opp_vertex);
+	/* Adds new face and sets the starting edge and returns the ID */
+	int addFaceRecord(DCEL_Edge *start_edge);
+	/* Deletes duplicate unused edges-if there are edges with the same start point and end point, delete the one with the unbounded incident face */
+	void deleteDuplicateEdges();
+	/* Adds an edge and sets the DCEL edge record attributes */
+	DCEL_Edge* addEdge(std::pair<int, int> edge_id, DCEL_Vertex *origin, DCEL_Edge *twin, DCEL_Face *inc_face, DCEL_Edge *next, DCEL_Edge *prev);
+	/* Deletes face with given face_id */
+	void deleteFaceRecord(int face_id);
+	/* Distance to an edge is the perpendicular distance if an orthogonal projection is possible,
+	 * else it is the distance to the closer end point.
+	 * Set the feature edge or the vertex accordingly. Set the other one to NULL.
+	 * The edge if set, it is the half edge with the unbounded face.
+	 * Line joining the vertex to the edge should not intersect any existing edge/vertex */
+	DCEL_Edge* findClosestEdge(DCEL_Vertex *vertex);
+	/*Adds new vertex with the given coordinates and returns ID*/
+	int addVertexRecord(double *coordinates);
+	/* Checks if the vertex with the given ID is present in the face with the given ID) */
+	bool isVertexInFace(int vertex_id, int face_id);
+};
Index: MeshHealing/MeshConversion_brlcad.cpp
===================================================================
--- MeshHealing/MeshConversion_brlcad.cpp	(revision 0)
+++ MeshHealing/MeshConversion_brlcad.cpp	(working copy)
@@ -0,0 +1,377 @@
+#include "MeshConversion_brlcad.h"
+
+#include <malloc.h>
+#include <stddef.h>
+#include <utility>
+#include <vector>
+
+
+BrlcadMesh::BrlcadMesh(rt_bot_internal *bot_mesh) {
+	bot = bot_mesh;
+	initVertices();
+	initFaces();
+	initEdges();
+	initIncidentFace();
+	initIncidentEdge();
+	initStartEdge();
+	initTwinEdge();
+	initPrevEdge();
+	initNextEdge();
+}
+
+/* DCEL_Vertex record functions */
+
+int BrlcadMesh::getNumVertices() {
+	return bot->num_vertices;
+}
+
+void BrlcadMesh::initVertices() {
+
+	std::vector<DCEL_Vertex> vertex_record;
+	unsigned int num_vertices = this->getNumVertices();
+
+	for (unsigned int i = 0; i < num_vertices; i++) {
+		vertex_record[i].vertex_id = i;
+		vertex_record[i].coordinates[0] = bot->vertices[VERTICES_PER_FACE * i];
+		vertex_record[i].coordinates[1] = bot->vertices[VERTICES_PER_FACE * i + 1];
+		vertex_record[i].coordinates[2] = bot->vertices[VERTICES_PER_FACE * i + 2];
+	}
+}
+
+
+/* DCEL_Face record functions 
+ * Note: The unbounded DCEL_Face will have face_id = 0. Its start_edge will be set to NULL.
+ */
+
+int BrlcadMesh::getNumFaces() {
+	return bot->num_faces;
+}
+
+
+void BrlcadMesh::initStartEdge() {
+
+	int vertex1, vertex2, vertex3;
+	int v1, v2;
+	unsigned int num_faces = this->getNumFaces();
+
+	/* Will contain the coordinates of the three vertex list */
+	double coords[3][3];
+	double determinant;
+
+	for (unsigned int i = 0; i < num_faces; ++i) {
+		vertex1 = bot->faces[VERTICES_PER_FACE * i];
+		vertex2 = bot->faces[VERTICES_PER_FACE * i + 1];
+		vertex3 = bot->faces[VERTICES_PER_FACE * i + 2];
+
+		if(bot->orientation == RT_BOT_CCW)
+			vertex2 = bot->faces[VERTICES_PER_FACE * i + 1];
+		else if(bot->orientation == RT_BOT_CW)
+			vertex2 = bot->faces[VERTICES_PER_FACE * i + 2];
+		else {
+			/* Determine the CCW orientation and set the vertex2 accordingly */
+
+			/* Finding the determinant formed by the coordinates of the three vertexlist to get the orientation */
+			for (unsigned int j = 0; j < 3; j++) {
+				coords[0][j] = bot->vertices[vertex1 * 3 + j];
+				coords[1][j] = bot->vertices[vertex2 * 3 + j];
+				coords[2][j] = bot->vertices[vertex3 * 3 + j];
+				
+			}
+			
+			determinant = calcDet(coords);
+
+			/* If the orientation is clockwise, switch the second and third vertexlist */
+			if(determinant > 0)
+				vertex2 = vertex3;
+
+		}
+
+		for (unsigned int j = 0; j < edgelist.size(); j++) {
+			v1 = edgelist[j].edge_id.first;
+			v2 = edgelist[j].edge_id.second;
+			
+			if(vertex1 == v1 && vertex2 == v2) {
+				/* i+1 due to the presence of the unbounded face record */
+				facelist[i + 1].start_edge = &(edgelist[j]);
+				break;
+			}
+		}
+	}
+}
+
+/* DCEL_Edge record functions */
+
+void BrlcadMesh::initEdges()
+{
+	unsigned int num_faces = this->getNumFaces();
+	int v1, v2;
+	
+	/* To check if the half-edges are already present */
+	int flag1, flag2;
+
+	for (unsigned int i = 0; i < num_faces; ++i) {
+		
+		DCEL_Edge temp;
+		std::pair<int, int> id;
+		
+		for (unsigned int j = 0; j < VERTICES_PER_FACE; ++j){
+			v1 = bot->faces[VERTICES_PER_FACE * i + j];
+			v2 = bot->faces[VERTICES_PER_FACE * i + (j + 1) % VERTICES_PER_FACE];
+
+			flag1 = 0;
+			flag2 = 0;
+
+			/* 	Checking if the DCEL_Edge from v1 to v2 is already present */
+			for (unsigned int k = 0; k < edgelist.size(); k++) {
+				if(v1 == edgelist[k].edge_id.first && v2 == edgelist[k].edge_id.second)
+					flag1 = 1;
+				else if (v2 == edgelist[k].edge_id.first && v1 == edgelist[k].edge_id.second)
+					flag2 = 1;
+
+				if(flag1 == 1 && flag2 == 1)
+					break;
+			}
+			if(flag1 == 0) {
+				/* Setting the DCEL_Edge record for the half record from v1 to v2 */
+				temp.origin = &(vertexlist[v1]);
+				id = std::make_pair(v1, v2);
+				temp.edge_id = id;
+				edgelist.push_back(temp);
+			}
+
+			if(flag2 == 0) {
+				/* Setting the DCEL_Edge record for the half record from v1 to v2 */
+				temp.origin = &(vertexlist[v2]);
+				id = std::make_pair(v2, v1);
+				temp.edge_id = id;
+				edgelist.push_back(temp);
+			}
+		}
+	}
+}
+
+void BrlcadMesh::initIncidentFace()
+{
+
+	int vertex1, vertex2;
+	unsigned int num_faces = this->getNumFaces();
+	int v1, v2, v3;
+	int *a, *b;
+
+	a = new int[2];
+	b = new int[3];
+
+	for (unsigned int i = 0; i < edgelist.size(); ++i) {
+		
+		vertex1 = edgelist[i].edge_id.first;
+		vertex2 = edgelist[i].edge_id.second;
+		
+		a[0] = vertex1;
+		a[1] = vertex2;
+
+		for (unsigned int j = 0; j < num_faces + 1; j++) {
+			v1 = bot->faces[VERTICES_PER_FACE * j];
+			v2 = bot->faces[VERTICES_PER_FACE * j + 1];
+			v3 = bot->faces[VERTICES_PER_FACE * j + 2];
+			
+			b[0] = v1;
+			b[1] = v2;
+			b[2] = v3;
+
+			/* Check if a (vertex1 and vertex2) is present in the same order as b (the triangle made of v1, v2, v3) */
+			if(rt_bot_same_orientation(a, b)) {
+				edgelist[i].incident_face = &(facelist[j]);
+				break;
+			}				
+		}
+		/* If no DCEL_Face has been set till here, set the unbounded DCEL_Face to be the incident DCEL_Face */
+		if(edgelist[i].incident_face == NULL) {
+			edgelist[i].incident_face = &(facelist[UNBOUNDED_FACE]);
+		}
+	}
+
+}
+
+void BrlcadMesh::initPrevEdge()
+{
+
+	int inc_face, third_vertex;
+	int vertex1, vertex2;
+	int v1, v2;
+
+	for (unsigned int i = 0; i < edgelist.size(); i++) {
+
+		/* inc_face has the face_id of the incident face for the current edge */
+		inc_face = edgelist[i].incident_face->face_id;
+
+		/* The vertex_id of the vertex list comprising the current half edge */
+		vertex1 = edgelist[i].edge_id.first;
+		vertex2 = edgelist[i].edge_id.second;
+
+		for (unsigned int j = 0; j < VERTICES_PER_FACE; j++) {
+
+			/*Finding the third vertex, that is one that is not vertex1 or vertex2 */
+			if(bot->faces[VERTICES_PER_FACE * inc_face + j] != vertex1 && bot->faces[VERTICES_PER_FACE * inc_face + j] != vertex2) {
+				third_vertex = bot->faces[VERTICES_PER_FACE * inc_face + j];
+				break;
+			}
+		}
+
+		/* Finding the edge_id of the edge from third_vertex to vertex1 */
+		for (unsigned int j = 0; j < edgelist.size(); j++) {
+			v1 = edgelist[j].edge_id.first;
+			v2 = edgelist[j].edge_id.second;
+
+			if(v1 == third_vertex && v2 == vertex1) {
+				edgelist[i].next = &(edgelist[j]);
+				break;
+			}
+		}
+	}
+}
+void BrlcadMesh::initNextEdge()
+{
+
+	int inc_face, third_vertex;
+	int vertex1, vertex2;
+	int v1, v2;
+
+	for (unsigned int i = 0; i < edgelist.size(); i++) {
+
+		/* inc_face has the face_id of the incident face for the current edge */
+		inc_face = edgelist[i].incident_face->face_id;
+
+		/* The vertex_id of the vertices comprising the current half edge */
+		vertex1 = edgelist[i].edge_id.first;
+		vertex2 = edgelist[i].edge_id.second;
+
+		for (unsigned int j = 0; j < VERTICES_PER_FACE; j++) {
+
+			/*Finding the third vertex, that is one that is not vertex1 or vertex2 */
+			if(bot->faces[VERTICES_PER_FACE * inc_face + j] != vertex1 && bot->faces[VERTICES_PER_FACE * inc_face + j] != vertex2) {
+				third_vertex = bot->faces[VERTICES_PER_FACE * inc_face + j];
+				break;
+			}
+		}
+
+		/* Finding the edge_id of the edge from vertex2 to third_vertex */
+		for (unsigned int j = 0; j < edgelist.size(); j++) {
+			v1 = edgelist[j].edge_id.first;
+			v2 = edgelist[j].edge_id.second;
+
+ 			if(v1 == vertex2 && v2 == third_vertex) {
+				edgelist[i].next = &(edgelist[j]);
+				break;
+			}
+		}
+	}
+}
+
+void BrlcadMesh::setNumVertices()
+{
+	bot->num_vertices = vertexlist.size();
+}
+
+void BrlcadMesh::setNumFaces()
+{
+	bot->num_faces = facelist.size();
+}
+
+void BrlcadMesh::setVertices()
+{
+	free(bot->vertices);
+	bot->vertices = (fastf_t*)malloc(sizeof(fastf_t) * bot->num_vertices * 3);
+
+	for (unsigned int i = 0; i < vertexlist.size(); i++) {
+
+		/* Check for edges incident on this vertex and update the ID to the current value of i */
+		for (unsigned int j = 0; j < edgelist.size(); ++j) {
+			if(edgelist[j].edge_id.first == vertexlist[i].vertex_id)
+				edgelist[j].edge_id.first = i;
+
+			else if(edgelist[i].edge_id.second == vertexlist[i].vertex_id)
+				edgelist[j].edge_id.second = i;
+		}
+
+		vertexlist[i].vertex_id = i;
+
+		for(int k = 0; k < 3; k++)
+			bot->vertices[3 * i + k] = vertexlist[i].coordinates[k];
+	}
+}
+
+void BrlcadMesh::setFaces()
+{
+	DCEL_Edge *edge;
+
+	/* Unbounded face is the first record, so skip */
+	for (unsigned int i = 1; i < facelist.size(); ++i) {
+		facelist[i].face_id = i;
+		edge = facelist[i].start_edge;
+		for (int j = 0; j < VERTICES_PER_FACE; ++j) {
+
+			bot->faces[VERTICES_PER_FACE * (i - 1) + j] = edge->edge_id.first;
+			edge = edge->next;
+		}
+	}
+}
+
+void BrlcadMesh::setVertexCoords(int ID)
+{
+	for(int i = 0; i < 3; i++) {
+		bot->vertices[3 * ID + i] = vertexlist[ID].coordinates[i];
+	}
+}
+
+void BrlcadMesh::setVertex(int v1, int v2)
+{
+	for (int i = 0; i < getNumFaces(); ++i) {
+		for(int j = 0; j < VERTICES_PER_FACE; ++j) {
+			if(bot->faces[VERTICES_PER_FACE * i + j] == v1)
+				bot->faces[VERTICES_PER_FACE * i + j] = v2;
+		}
+	}
+}
+
+void BrlcadMesh::deleteVertex(int ID)
+{
+	for(int i = 3 * ID ; i < 3 * getNumVertices(); i++) {
+		bot->vertices[i] = bot->vertices[i + 1];
+	}
+
+	bot->num_vertices -= 1;
+}
+
+void BrlcadMesh::deleteFace(int ID)
+{
+	for(int i = 3 * (ID - 1) ; i < 3 * getNumFaces(); i++) {
+		bot->faces[i] = bot->faces[i + 1];
+	}
+	bot->num_faces -= 1;
+}
+
+void BrlcadMesh::addFace(int ID)
+{
+	int *new_faces = (int*)realloc(bot->faces, getNumFaces() + 1);
+	bot->faces = new_faces;
+
+	DCEL_Edge *edge = facelist[ID].start_edge;
+
+	for(int i = 0; i < 3; i++) {
+		bot->faces[3 * (ID - 1) + i] = edge->edge_id.first;
+		edge = edge->next;
+	}
+	bot->num_faces += 1;
+}
+
+void BrlcadMesh::addVertex(int ID)
+{
+	fastf_t *new_vertices = (fastf_t*)realloc(bot->vertices, getNumVertices() + 1);
+
+	bot->vertices = new_vertices;
+
+	for(int i = 0; i < 3; i++) {
+		bot->vertices[3 * ID + i] = vertexlist[ID].coordinates[i];
+	}
+	bot->num_vertices += 1;
+}
Index: MeshHealing/MeshConversion_brlcad.h
===================================================================
--- MeshHealing/MeshConversion_brlcad.h	(revision 0)
+++ MeshHealing/MeshConversion_brlcad.h	(working copy)
@@ -0,0 +1,33 @@
+#include "MeshConversion.h"
+
+#include "rt/geom.h"
+#include "rt/primitives/bot.h"
+#include "vmath.h"
+
+class BrlcadMesh: public PolygonalMesh {
+
+private:
+	rt_bot_internal *bot;
+
+	BrlcadMesh(rt_bot_internal *bot_mesh);
+
+	int getNumVertices();
+	void initVertices();
+	int getNumFaces();
+	void initStartEdge();
+	void initEdges();
+	void initIncidentFace();
+	void initPrevEdge();
+	void initNextEdge();
+
+	void setNumVertices();
+	void setNumFaces();
+	void setVertices();
+	void setFaces();
+	void setVertexCoords(int ID);
+	void setVertex(int v1, int v2);
+	void deleteVertex(int ID);
+	void deleteFace(int ID);
+	void addFace(int ID);
+	void addVertex(int ID);
+};
Index: MeshHealing/Zipper.cpp
===================================================================
--- MeshHealing/Zipper.cpp	(revision 0)
+++ MeshHealing/Zipper.cpp	(working copy)
@@ -0,0 +1,159 @@
+#include "Zipper.h"
+#include "Geometry.h"
+#include <cstddef>
+
+void calcFeaturePair(PolygonalMesh *polymesh, queue_element *node)
+{
+	DCEL_Edge *closest_edge;
+	int new_vertex_id;
+	DCEL_Vertex *vertex = node->vertex;
+	/* IDs of the vertices of the closest edge */
+	DCEL_Vertex *v1, *v2;
+
+	/* Get the closest edge */
+	closest_edge = polymesh->findClosestEdge(vertex);
+	v1 = (polymesh->getVertex(closest_edge->edge_id.first));
+	v2 = (polymesh->getVertex(closest_edge->edge_id.second));
+
+	/* Check if orthogonal projection is possible, if yes set the feature_edge, else set the feature_vertex */
+	if(isOrthoProjPossible(v1->coordinates, v2->coordinates, vertex->coordinates)) {
+		node->feature_edge = closest_edge;
+		node->dist = shortestDistToLine(v1->coordinates, v2->coordinates, vertex->coordinates);
+	}
+
+	else {
+		/* Returns the closest end point */
+		new_vertex_id = polymesh->addVertexRecord(findOrthogonalProjection((polymesh->getVertex(closest_edge->edge_id.first))->coordinates, \
+		(polymesh->getVertex(closest_edge->edge_id.second))->coordinates, vertex->coordinates));
+
+		node->feature_vertex = polymesh->getVertex(new_vertex_id);
+		node->dist = shortestDistBwPoints(vertex->coordinates, node->feature_vertex->coordinates);
+	}
+}
+void initPriorityQueue(PolygonalMesh *polymesh, DCEL_Edge *start, DCEL_Edge *end)
+{
+	queue_element node;
+	DCEL_Vertex *vertex;
+	DCEL_Edge *edge;
+	int v_id;
+
+	edge = start;
+	do
+	{
+		/* Consider the starting v_id of each edge, we'll handle the ending v_id of the end edge separately */
+		v_id = edge->origin->vertex_id;
+		vertex = polymesh->getVertex(v_id);
+		node.vertex = vertex;
+		calcFeaturePair(polymesh, &node);
+
+		/* Push the queue element to the priority queue */
+		PQ.push(node);
+
+		edge = edge->next;
+	}
+
+	while(end->next->next != edge);
+}
+
+void zipperGaps(PolygonalMesh *polymesh, double tolerance)
+{
+	double coords[3];
+
+	double *A, *B, *C, *D;
+
+	/* Temporary priority queue */
+	std::priority_queue<queue_element, std::vector<queue_element>, compareDist> temp_PQ;
+
+	/* IDs of the vertices of the closest edge */
+	DCEL_Vertex *v1, *v2;
+
+	while(!PQ.empty()) {
+
+		/* To account for:
+		 * 1. Those vertices with invalid elements
+		 * 2. Those vertices whose coordinates have been changed, and hence the error measure - recalculate for all measures
+		 */
+		queue_element curr_element;
+		do {
+			curr_element = PQ.top();
+			PQ.pop();
+
+			if(!isValidFeature(polymesh, &curr_element)) {
+				calcFeaturePair(polymesh, &curr_element);
+			}
+			else {
+				if(curr_element.feature_vertex != NULL)
+					curr_element.dist = shortestDistBwPoints(curr_element.vertex->coordinates, curr_element.feature_vertex->coordinates);
+				else {
+					v1 = (polymesh->getVertex(curr_element.feature_edge->edge_id.first));
+					v2 = (polymesh->getVertex(curr_element.feature_edge->edge_id.second));
+					curr_element.dist = shortestDistToLine(v1->coordinates, v2->coordinates, curr_element.vertex->coordinates);
+				}
+			}
+
+			temp_PQ.push(curr_element);
+		}
+		while(!PQ.empty());
+
+		PQ = temp_PQ;
+
+		/* Check if the error measure is within the tolerance for zippering, if not break out of the loop, since all the error measures after this one are not going to be lesser than this one */
+		if(curr_element.dist > tolerance)
+			break;
+
+		/* If the feature is a vertex, move both these vertices to the midpoint of the line connecting the two vertices */
+		if(curr_element.feature_vertex != NULL) {
+
+			/* Find the mid-point */
+			coords[0] = (curr_element.vertex->coordinates[0] + curr_element.feature_vertex->coordinates[0]) / 2;
+			coords[1] = (curr_element.vertex->coordinates[1] + curr_element.feature_vertex->coordinates[1]) / 2;
+			coords[2] = (curr_element.vertex->coordinates[2] + curr_element.feature_vertex->coordinates[2]) / 2;
+
+			/* Changing the coordinates of the vertex to the midpoint of the vertex and its feature pair */
+			polymesh->setVertexCoordsInRecord(curr_element.vertex->vertex_id, coords);
+
+			/* Replace all references of the feature vertex with that of the vertex on the free edge chain */
+			polymesh->setVertexRecord(curr_element.vertex, curr_element.feature_vertex);
+
+			/* Delete the feature vertex's record */
+			polymesh->deleteVertexRecord(curr_element.feature_vertex->vertex_id);
+		}
+
+		/* Else if the feature is an edge, project the vertex orthogonally onto the edge and split the edge and its incident face at the point */
+		else if(curr_element.feature_edge != NULL) {
+
+			A = polymesh->getVertex(curr_element.feature_edge->edge_id.first)->coordinates;
+			B = polymesh->getVertex(curr_element.feature_edge->edge_id.second)->coordinates;
+			C = polymesh->getVertex(curr_element.vertex->vertex_id)->coordinates;
+
+			D = findOrthogonalProjection(A, B, C);
+
+			polymesh->setVertexCoordsInRecord(curr_element.vertex->vertex_id, D);
+
+			/* Insert a vertex with coordinates D on the feature edge. */
+			polymesh->insertVertexOnEdge(curr_element.vertex, curr_element.feature_edge);
+
+			/* Split the face incident on the half edge of the feature edge with a bounded face incident */
+			polymesh->splitFace(curr_element.feature_edge->twin->incident_face->face_id, curr_element.vertex, curr_element.feature_edge->next->origin);
+
+		}
+	}
+	polymesh->deleteDuplicateEdges();
+}
+
+int isValidFeature(PolygonalMesh *polymesh, queue_element *node)
+{
+	if(node->feature_vertex != NULL) {
+		if(polymesh->getVertex(node->feature_vertex->vertex_id) == NULL) {
+			return 0;
+		}
+		return 1;
+	}
+
+	else {
+		if(polymesh->getEdge(std::make_pair(node->feature_edge->edge_id.first, node->feature_edge->edge_id.second)) == NULL)
+			return 0;
+		return 1;
+	}
+}
+
Index: MeshHealing/Zipper.h
===================================================================
--- MeshHealing/Zipper.h	(revision 0)
+++ MeshHealing/Zipper.h	(working copy)
@@ -0,0 +1,40 @@
+#include "MeshConversion.h"
+
+#include <queue>
+
+struct queue_element {
+	DCEL_Vertex *vertex;
+
+	/* Either vertex feature or the edge feature will be set. Feature is the closest edge. If an orthogonal projection of the vertex on the edge is possible, the edge feature will be set. Else, the vertex feature will be set to the closer end point of the edge. */
+	DCEL_Vertex *feature_vertex;
+	DCEL_Edge *feature_edge;
+
+	/* Distance between the vertex and the feature - the error measure*/
+	double dist;
+};
+
+/* Operator to compare the error measures of two feature pairs */
+struct compareDist
+{
+  bool operator()(queue_element& lhs, queue_element& rhs)
+  {
+    return lhs.dist < rhs.dist;
+  }
+};
+
+
+/* Priority queue ordered based on the error measure */
+std::priority_queue<queue_element, std::vector<queue_element>, compareDist> PQ;
+
+/* Calculate error measures for the vertices on the free edge chain and push the queue_element variable to the priority queue */
+void initPriorityQueue(PolygonalMesh *polymesh, DCEL_Edge *start, DCEL_Edge *end);
+
+/* Take the priority queue and zippers all those vertices whose error measures fall within the tolerance for zippering */
+void zipperGaps(PolygonalMesh *polymesh, double tolerance);
+
+/* Check if the queue element has a valid feature */
+int isValidFeature(PolygonalMesh *polymesh, queue_element *node);
+
+/* Calculates the feature pair of a queue element */
+void calcFeaturePair(PolygonalMesh *polymesh, queue_element *node);
+
------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://sdm.link/zohomanageengine
_______________________________________________
BRL-CAD Developer mailing list
brlcad-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-devel

Reply via email to