@@ -392,80 +392,95 @@ Py::Object Triangulation::calculate_plane_coefficients(const Py::Tuple &args)
392
392
throw Py::ValueError (
393
393
" z array must have same length as triangulation x and y arrays" );
394
394
}
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
405
399
{
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)
414
410
{
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))
431
412
{
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);
452
435
453
436
if (normal.z == 0.0 )
454
437
{
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
+ }
460
468
}
461
- }
462
469
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
+ }
466
474
}
467
475
}
476
+ catch (...)
477
+ {
478
+ Py_DECREF (z);
479
+ Py_XDECREF (planes_array);
480
+ throw ;
481
+ }
468
482
483
+ Py_DECREF (z);
469
484
return Py::asObject ((PyObject*)planes_array);
470
485
}
471
486
0 commit comments