diff options
Diffstat (limited to 'src/primitives.cc')
-rw-r--r-- | src/primitives.cc | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/src/primitives.cc b/src/primitives.cc index f1a4ba7..c9e1072 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -34,11 +34,16 @@ #include "printutils.h" #include "visitor.h" #include "context.h" +#include "calc.h" +#include "mathc99.h" #include <sstream> #include <assert.h> #include <boost/assign/std/vector.hpp> using namespace boost::assign; // bring 'operator+=()' into scope +#include <boost/math/special_functions/fpclassify.hpp> +using boost::math::isinf; + #define F_MINIMUM 0.01 enum primitive_type_e { @@ -275,17 +280,6 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta return node; } -/*! - Returns the number of subdivision of a whole circle, given radius and - the three special variables $fn, $fs and $fa -*/ -int get_fragments_from_r(double r, double fn, double fs, double fa) -{ - if (r < GRID_FINE) return 3; - if (fn > 0.0) return (int)(fn >= 3 ? fn : 3); - return (int)ceil(fmax(fmin(360.0 / fa, r*2*M_PI / fs), 5)); -} - struct point2d { double x, y; }; @@ -303,8 +297,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; @@ -357,14 +352,14 @@ 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; double z; }; - int fragments = get_fragments_from_r(r1, fn, fs, fa); + int fragments = Calc::get_fragments_from_r(r1, fn, fs, fa); int rings = (fragments+1)/2; // Uncomment the following three lines to enable experimental sphere tesselation // if (rings % 2 == 0) rings++; // To ensure that the middle ring is at phi == 0 degrees @@ -425,9 +420,10 @@ sphere_next_r2: } if (this->type == CYLINDER && - this->h > 0 && this->r1 >=0 && this->r2 >= 0 && (this->r1 > 0 || this->r2 > 0)) - { - int fragments = get_fragments_from_r(fmax(this->r1, this->r2), this->fn, this->fs, this->fa); + 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; if (this->center) { @@ -490,12 +486,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); } } } @@ -525,7 +527,7 @@ sphere_next_r2: if (this->type == CIRCLE) { - int fragments = get_fragments_from_r(this->r1, this->fn, this->fs, this->fa); + int fragments = Calc::get_fragments_from_r(this->r1, this->fn, this->fs, this->fa); p->is2d = true; p->append_poly(); @@ -542,7 +544,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; |