8000 Added try..catch block to Triangulation::calculate_plane_coefficients. · matplotlib/matplotlib@01ddc8a · GitHub
[go: up one dir, main page]

Skip to content

Commit 01ddc8a

Browse files
committed
Added try..catch block to Triangulation::calculate_plane_coefficients.
1 parent 0a9f09c commit 01ddc8a

File tree

1 file changed

+78
-63
lines changed

1 file changed

+78
-63
lines changed

lib/matplotlib/tri/_tri.cpp

Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -392,80 +392,95 @@ Py::Object Triangulation::calculate_plane_coefficients(const Py::Tuple &args)
392392
throw Py::ValueError(
393393
"z array must have same length as triangulation x and y arrays");
394394
}
395-
const double* zs = (const double*)PyArray_DATA(z);
396-
397-
npy_intp dims[2] = {_ntri, 3};
398-
PyArrayObject* planes_array = (PyArrayObject*)PyArray_SimpleNew(
399-
2, dims, PyArray_DOUBLE);
400-
double* planes = (double*)PyArray_DATA(planes_array);
401-
const int* tris = get_triangles_ptr();
402-
const double* xs = (const double*)PyArray_DATA(_x);
403-
const double* ys = (const double*)PyArray_DATA(_y);
404-
for (int tri = 0; tri < _ntri; ++tri)
395+
396+
PyArrayObject* planes_array = 0; // Array to return.
397+
398+
try
405399
{
406-
if (is_masked(tri))
407-
{
408-
*planes++ = 0.0;
409-
*planes++ = 0.0;
410-
*planes++ = 0.0;
411-
tris += 3;
412-
}
413-
else
400+
const double* zs = (const double*)PyArray_DATA(z);
401+
402+
npy_intp dims[2] = {_ntri, 3};
403+
planes_array = (PyArrayObject*)PyArray_SimpleNew(2, dims,
404+
PyArray_DOUBLE);
405+
double* planes = (double*)PyArray_DATA(planes_array);
406+
const int* tris = get_triangles_ptr();
407+
const double* xs = (const double*)PyArray_DATA(_x);
408+
const double* ys = (const double*)PyArray_DATA(_y);
409+
for (int tri = 0; tri < _ntri; ++tri)
414410
{
415-
// Equation of plane for all points r on plane is r.normal = p
416-
// where normal is vector normal to the plane, and p is a constant.
417-
// Rewrite as r_x*normal_x + r_y*normal_y + r_z*normal_z = p
418-
// and rearrange to give
419-
// r_z = (-normal_x/normal_z)*r_x + (-normal_y/normal_z)*r_y +
420-
// p/normal_z
421-
XYZ point0(xs[*tris], ys[*tris], zs[*tris]);
422-
tris++;
423-
XYZ point1(xs[*tris], ys[*tris], zs[*tris]);
424-
tris++;
425-
XYZ point2(xs[*tris], ys[*tris], zs[*tris]);
426-
tris++;
427-
428-
XYZ normal = (point1 - point0).cross(point2 - point0);
429-
430-
if (normal.z == 0.0)
411+
if (is_masked(tri))
431412
{
432-
// Normal is in x-y plane which means triangle consists of
433-
// colinear points. Try to do the best we can by taking plane
434-
// through longest side of triangle.
435-
double length_sqr_01 = (point1 - point0).length_squared();
436-
double length_sqr_12 = (point2 - point1).length_squared();
437-
double length_sqr_20 = (point0 - point2).length_squared();
438-
if (length_sqr_01 > length_sqr_12)
439-
{
440-
if (length_sqr_01 > length_sqr_20)
441-
normal = normal.cross(point1 - point0);
442-
else
443-
normal = normal.cross(point0 - point2);
444-
}
445-
else
446-
{
447-
if (length_sqr_12 > length_sqr_20)
448-
normal = normal.cross(point2 - point1);
449-
else
450-
normal = normal.cross(point0 - point2);
451-
}
413+
*planes++ = 0.0;
414+
*planes++ = 0.0;
415+
*planes++ = 0.0;
416+
tris += 3;
417+
}
418+
else
419+
{
420+
// Equation of plane for all points r on plane is r.normal = p
421+
// where normal is vector normal to the plane, and p is a
422+
// constant. Rewrite as
423+
// r_x*normal_x + r_y*normal_y + r_z*normal_z = p
424+
// and rearrange to give
425+
// r_z = (-normal_x/normal_z)*r_x + (-normal_y/normal_z)*r_y +
426+
// p/normal_z
427+
XYZ point0(xs[*tris], ys[*tris], zs[*tris]);
428+
tris++;
429+
XYZ point1(xs[*tris], ys[*tris], zs[*tris]);
430+
tris++;
431+
XYZ point2(xs[*tris], ys[*tris], zs[*tris]);
432+
tris++;
433+
434+
XYZ normal = (point1 - point0).cross(point2 - point0);
452435

453436
if (normal.z == 0.0)
454437
{
455-
// The 3 triangle points have identical x and y! The best
456-
// we can do here is take normal = (0,0,1) and for the
457-
// constant p take the mean of the 3 points' z-values.
458-
normal = XYZ(0.0, 0.0, 1.0);
459-
point0.z = (point0.z + point1.z + point2.z) / 3.0;
438+
// Normal is in x-y plane which means triangle consists of
439+
// colinear points. Try to do the best we can by taking
440+
// plane through longest side of triangle.
441+
double length_sqr_01 = (point1 - point0).length_squared();
442+
double length_sqr_12 = (point2 - point1).length_squared();
443+
double length_sqr_20 = (point0 - point2).length_squared();
444+
if (length_sqr_01 > length_sqr_12)
445+
{
446+
if (length_sqr_01 > length_sqr_20)
447+
normal = normal.cross(point1 - point0);
448+
else
449+
normal = normal.cross(point0 - point2);
450+
}
451+
else
452+
{
453+
if (length_sqr_12 > length_sqr_20)
454+
normal = normal.cross(point2 - point1);
455+
else
456+
normal = normal.cross(point0 - point2);
457+
}
458+
459+
if (normal.z == 0.0)
460+
{
461+
// The 3 triangle points have identical x and y! The
462+
// best we can do here is take normal = (0,0,1) and for
463+
// the constant p take the mean of the 3 points'
464+
// z-values.
465+
normal = XYZ(0.0, 0.0, 1.0);
466+
point0.z = (point0.z + point1.z + point2.z) / 3.0;
467+
}
460468
}
461-
}
462469

463-
*planes++ = -normal.x / normal.z; // x
464-
*planes++ = -normal.y / normal.z; // y
465-
*planes++ = normal.dot(point0) / normal.z; // constant
470+
*planes++ = -normal.x / normal.z; // x
471+
*planes++ = -normal.y / normal.z; // y
472+
*planes++ = normal.dot(point0) / normal.z; // constant
473+
}
466474
}
467475
}
476+
catch (...)
477+
{
478+
Py_DECREF(z);
479+
Py_XDECREF(planes_array);
480+
throw;
481+
}
468482

483+
Py_DECREF(z);
469484
return Py::asObject((PyObject*)planes_array);
470485
}
471486

0 commit comments

Comments
 (0)
0