bugfix: division by zero can cause malformed primitives

export-menu
Marius Kintel 2014-01-13 20:49:55 -05:00
parent e6bfee021b
commit 23b04c3a9f
7 changed files with 41 additions and 10 deletions

View File

@ -13,6 +13,8 @@ float fmax(float a, float b);
#else
#include <math.h>
#include <cmath>
using std::isinf;
#endif

View File

@ -35,6 +35,7 @@
#include "visitor.h"
#include "context.h"
#include "calc.h"
#include "mathc99.h"
#include <sstream>
#include <assert.h>
#include <boost/assign/std/vector.hpp>
@ -293,8 +294,9 @@ PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const
{
PolySet *p = new PolySet();
if (this->type == CUBE && this->x > 0 && this->y > 0 && this->z > 0)
{
if (this->type == CUBE &&
this->x > 0 && this->y > 0 && this->z > 0 &&
!isinf(this->x) > 0 && !isinf(this->y) > 0 && !isinf(this->z) > 0) {
double x1, x2, y1, y2, z1, z2;
if (this->center) {
x1 = -this->x/2;
@ -347,7 +349,7 @@ PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const
p->append_vertex(x1, y2, z2);
}
if (this->type == SPHERE && this->r1 > 0)
if (this->type == SPHERE && this->r1 > 0 && !isinf(this->r1))
{
struct ring_s {
point2d *points;
@ -415,8 +417,9 @@ sphere_next_r2:
}
if (this->type == CYLINDER &&
this->h > 0 && this->r1 >=0 && this->r2 >= 0 && (this->r1 > 0 || this->r2 > 0))
{
this->h > 0 && !isinf(this->h) &&
this->r1 >=0 && this->r2 >= 0 && (this->r1 + this->r2) > 0 &&
!isinf(this->r1) && !isinf(this->r2)) {
int fragments = Calc::get_fragments_from_r(fmax(this->r1, this->r2), this->fn, this->fs, this->fa);
double z1, z2;
@ -480,12 +483,18 @@ sphere_next_r2:
for (size_t i=0; i<this->faces.toVector().size(); i++)
{
p->append_poly();
for (size_t j=0; j<this->faces.toVector()[i].toVector().size(); j++) {
size_t pt = this->faces.toVector()[i].toVector()[j].toDouble();
const Value::VectorType &vec = this->faces.toVector()[i].toVector();
for (size_t j=0; j<vec.size(); j++) {
size_t pt = vec[j].toDouble();
if (pt < this->points.toVector().size()) {
double px, py, pz;
if (this->points.toVector()[pt].getVec3(px, py, pz))
p->insert_vertex(px, py, pz);
if (!this->points.toVector()[pt].getVec3(px, py, pz) ||
isinf(px) || isinf(py) || isinf(pz)) {
PRINTB("ERROR: Unable to convert point at index %d to a vec3 of numbers", j);
delete p;
return NULL;
}
p->insert_vertex(px, py, pz);
}
}
}
@ -532,7 +541,8 @@ sphere_next_r2:
for (size_t i=0; i<this->points.toVector().size(); i++) {
double x,y;
if (!this->points.toVector()[i].getVec2(x, y)) {
if (!this->points.toVector()[i].getVec2(x, y) ||
isinf(x) || isinf(y)) {
PRINTB("ERROR: Unable to convert point at index %d to a vec2 of numbers", i);
delete p;
return NULL;

View File

@ -0,0 +1,9 @@
cube(1/0);
cube([0,0,1/0]);
cylinder(h=10, r=1/0);
cylinder(h=10, r1=1, r2=1/0);
cylinder(h=1/0);
sphere(1/0);
polygon([[0,0,0],[1,0,0],[1,1/0,0]]);
polyhedron(points = [[1/0,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]],
triangles = [[0,4,2],[0,2,5],[0,3,4],[0,5,3],[1,2,4],[1,5,2],[1,4,3], [1,3,5]]);

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,10 @@
group() {
cube(size = [inf, inf, inf], center = false);
cube(size = [0, 0, inf], center = false);
cylinder($fn = 0, $fa = 12, $fs = 2, h = 10, r1 = inf, r2 = inf, center = false);
cylinder($fn = 0, $fa = 12, $fs = 2, h = 10, r1 = 1, r2 = inf, center = false);
cylinder($fn = 0, $fa = 12, $fs = 2, h = inf, r1 = 1, r2 = 1, center = false);
sphere($fn = 0, $fa = 12, $fs = 2, r = inf);
polygon(points = [[0, 0, 0], [1, 0, 0], [1, inf, 0]], paths = undef, convexity = 1);
polyhedron(points = [[inf, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 4, 3], [1, 3, 5]], convexity = 1);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB