Skip to content

Commit 241cf72

Browse files
committed
qhull: Wrap Qhull info in a class for auto-destruction.
1 parent 587b0a0 commit 241cf72

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

src/qhull_wrap.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,33 @@ at_least_3_unique_points(npy_intp npoints, const double* x, const double* y)
9595
return false;
9696
}
9797

98+
/* Holds on to info from Qhull so that it can be destructed automatically. */
99+
class QhullInfo {
100+
public:
101+
QhullInfo(FILE *error_file, qhT* qh) {
102+
this->error_file = error_file;
103+
this->qh = qh;
104+
}
105+
106+
~QhullInfo() {
107+
qh_freeqhull(this->qh, !qh_ALL);
108+
int curlong, totlong; /* Memory remaining. */
109+
qh_memfreeshort(this->qh, &curlong, &totlong);
110+
if (curlong || totlong) {
111+
PyErr_WarnEx(PyExc_RuntimeWarning,
112+
"Qhull could not free all allocated memory", 1);
113+
}
114+
115+
if (this->error_file != stderr) {
116+
fclose(error_file);
117+
}
118+
}
119+
120+
private:
121+
FILE* error_file;
122+
qhT* qh;
123+
};
124+
98125
/* Delaunay implementation method.
99126
* If hide_qhull_errors is true then qhull error messages are discarded;
100127
* if it is false then they are written to stderr. */
@@ -111,7 +138,6 @@ delaunay_impl(npy_intp npoints, const double* x, const double* y,
111138
int exitcode; /* Value returned from qh_new_qhull(). */
112139
std::vector<int> tri_indices; /* Maps qhull facet id to triangle index. */
113140
int indices[3];
114-
int curlong, totlong; /* Memory remaining after qh_memfreeshort. */
115141
PyObject* tuple; /* Return tuple (triangles, neighbors). */
116142
const int ndim = 2;
117143
npy_intp dims[2];
@@ -157,6 +183,7 @@ delaunay_impl(npy_intp npoints, const double* x, const double* y,
157183
}
158184

159185
/* Perform Delaunay triangulation. */
186+
QhullInfo info(error_file, qh);
160187
qh_zero(qh, error_file);
161188
exitcode = qh_new_qhull(qh, ndim, (int)npoints, points.data(), False,
162189
(char*)"qhull d Qt Qbb Qc Qz", NULL, error_file);
@@ -165,7 +192,7 @@ delaunay_impl(npy_intp npoints, const double* x, const double* y,
165192
"Error in qhull Delaunay triangulation calculation: %s (exitcode=%d)%s",
166193
qhull_error_msg[exitcode], exitcode,
167194
hide_qhull_errors ? "; use python verbose option (-v) to see original qhull error." : "");
168-
goto error;
195+
return NULL;
169196
}
170197

171198
/* Split facets so that they only have 3 points each. */
@@ -230,17 +257,6 @@ delaunay_impl(npy_intp npoints, const double* x, const double* y,
230257
}
231258
}
232259

233-
/* Clean up. */
234-
qh_freeqhull(qh, !qh_ALL);
235-
qh_memfreeshort(qh, &curlong, &totlong);
236-
if (curlong || totlong) {
237-
PyErr_WarnEx(PyExc_RuntimeWarning,
238-
"Qhull could not free all allocated memory", 1);
239-
}
240-
if (hide_qhull_errors) {
241-
fclose(error_file);
242-
}
243-
244260
tuple = PyTuple_New(2);
245261
PyTuple_SetItem(tuple, 0, (PyObject*)triangles);
246262
PyTuple_SetItem(tuple, 1, (PyObject*)neighbors);
@@ -250,12 +266,6 @@ delaunay_impl(npy_intp npoints, const double* x, const double* y,
250266
/* Clean up. */
251267
Py_XDECREF(triangles);
252268
Py_XDECREF(neighbors);
253-
qh_freeqhull(qh, !qh_ALL);
254-
qh_memfreeshort(qh, &curlong, &totlong);
255-
/* Don't bother checking curlong and totlong as raising error anyway. */
256-
if (hide_qhull_errors) {
257-
fclose(error_file);
258-
}
259269

260270
return NULL;
261271
}

0 commit comments

Comments
 (0)