diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/control.cc | 6 | ||||
-rw-r--r-- | src/csgtermnormalizer.cc | 9 | ||||
-rw-r--r-- | src/csgtermnormalizer.h | 1 | ||||
-rw-r--r-- | src/import.cc | 80 |
4 files changed, 65 insertions, 31 deletions
diff --git a/src/control.cc b/src/control.cc index bdd0f40..44847f5 100644 --- a/src/control.cc +++ b/src/control.cc @@ -96,8 +96,10 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation size_t n = 0; if (inst->argvalues.size() > 0) { double v; - if (inst->argvalues[0].getDouble(v)) - n = v; + if (inst->argvalues[0].getDouble(v)) { + if (v < 0) return NULL; // Disallow negative child indices + n = trunc(v); + } } for (int i = Context::ctx_stack.size()-1; i >= 0; i--) { const Context *c = Context::ctx_stack[i]; diff --git a/src/csgtermnormalizer.cc b/src/csgtermnormalizer.cc index e2474e9..461e965 100644 --- a/src/csgtermnormalizer.cc +++ b/src/csgtermnormalizer.cc @@ -7,6 +7,7 @@ */ shared_ptr<CSGTerm> CSGTermNormalizer::normalize(const shared_ptr<CSGTerm> &root) { + this->aborted = false; shared_ptr<CSGTerm> temp = root; while (1) { this->rootnode = temp; @@ -20,7 +21,7 @@ shared_ptr<CSGTerm> CSGTermNormalizer::normalize(const shared_ptr<CSGTerm> &root PRINTB("WARNING: Normalized tree is growing past %d elements. Aborting normalization.\n", this->limit); // Clean up any partially evaluated terms shared_ptr<CSGTerm> newroot = root, tmproot; - while (newroot != tmproot) { + while (newroot && newroot != tmproot) { tmproot = newroot; newroot = collapse_null_terms(tmproot); } @@ -49,14 +50,16 @@ shared_ptr<CSGTerm> CSGTermNormalizer::normalizePass(shared_ptr<CSGTerm> term) while (term && match_and_replace(term)) { } this->nodecount++; if (nodecount > this->limit) { + PRINTB("WARNING: Normalized tree is growing past %d elements. Aborting normalization.\n", this->limit); + this->aborted = true; return shared_ptr<CSGTerm>(); } if (!term || term->type == CSGTerm::TYPE_PRIMITIVE) return term; if (term->left) term->left = normalizePass(term->left); - } while (term->type != CSGTerm::TYPE_UNION && + } while (!this->aborted && term->type != CSGTerm::TYPE_UNION && ((term->right && term->right->type != CSGTerm::TYPE_PRIMITIVE) || (term->left && term->left->type == CSGTerm::TYPE_UNION))); - term->right = normalizePass(term->right); + if (!this->aborted) term->right = normalizePass(term->right); // FIXME: Do we need to take into account any transformation of item here? return collapse_null_terms(term); diff --git a/src/csgtermnormalizer.h b/src/csgtermnormalizer.h index c331f11..f7a444f 100644 --- a/src/csgtermnormalizer.h +++ b/src/csgtermnormalizer.h @@ -17,6 +17,7 @@ private: shared_ptr<CSGTerm> collapse_null_terms(const shared_ptr<CSGTerm> &term); unsigned int count(const shared_ptr<CSGTerm> &term) const; + bool aborted; size_t limit; size_t nodecount; shared_ptr<class CSGTerm> rootnode; diff --git a/src/import.cc b/src/import.cc index 6a6d925..8980448 100644 --- a/src/import.cc +++ b/src/import.cc @@ -52,6 +52,9 @@ namespace fs = boost::filesystem; using namespace boost::assign; // bring 'operator+=()' into scope #include "boosty.h" +#include <boost/detail/endian.hpp> +#include <boost/cstdint.hpp> + class ImportModule : public AbstractModule { public: @@ -112,6 +115,47 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati return node; } +#define STL_FACET_NUMBYTES 4*3*4+2 +// as there is no 'float32_t' standard, we assume the systems 'float' +// is a 'binary32' aka 'single' standard IEEE 32-bit floating point type +union stl_facet { + uint8_t data8[ STL_FACET_NUMBYTES ]; + uint32_t data32[4*3]; + struct facet_data { + float i, j, k; + float x1, y1, z1; + float x2, y2, z2; + float x3, y3, z3; + uint16_t attribute_byte_count; + } data; +}; + +void uint32_byte_swap( uint32_t &x ) +{ +#if defined(__GNUC__) || defined(__clang__) + x = __builtin_bswap32( x ); +#elif defined(_MSC_VER) + x = _byteswap_ulong( x ); +#else + uint32_t b1 = ( 0x000000FF & x ) << 24; + uint32_t b2 = ( 0x0000FF00 & x ) << 8; + uint32_t b3 = ( 0x00FF0000 & x ) >> 8; + uint32_t b4 = ( 0xFF000000 & x ) >> 24; + x = b1 | b2 | b3 | b4; +#endif +} + +void read_stl_facet( std::ifstream &f, stl_facet &facet ) +{ + f.read( (char*)facet.data8, STL_FACET_NUMBYTES ); +#ifdef BOOST_BIG_ENDIAN + for ( int i = 0; i < 12; i++ ) { + uint32_byte_swap( facet.data32[ i ] ); + } + // we ignore attribute byte count +#endif +} + PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const { PolySet *p = NULL; @@ -137,9 +181,11 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const int file_size = f.tellg(); f.seekg(80); if (!f.eof()) { - int facenum = 0; - // FIXME: Assumes little endian - f.read((char *)&facenum, sizeof(int)); + uint32_t facenum = 0; + f.read((char *)&facenum, sizeof(uint32_t)); +#ifdef BOOST_BIG_ENDIAN + uint32_byte_swap( facenum ); +#endif if (file_size == 80 + 4 + 50*facenum) binary = true; } f.seekg(0); @@ -186,32 +232,14 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const else { f.ignore(80-5+4); - // FIXME: Assumes little endian while (1) { -#ifdef _MSC_VER -#pragma pack(push,1) -#endif - struct { - float i, j, k; - float x1, y1, z1; - float x2, y2, z2; - float x3, y3, z3; - unsigned short acount; - } -#ifdef __GNUC__ - __attribute__ ((packed)) -#endif - stldata; -#ifdef _MSC_VER -#pragma pack(pop) -#endif - - f.read((char*)&stldata, sizeof(stldata)); + stl_facet facet; + read_stl_facet( f, facet ); if (f.eof()) break; p->append_poly(); - p->append_vertex(stldata.x1, stldata.y1, stldata.z1); - p->append_vertex(stldata.x2, stldata.y2, stldata.z2); - p->append_vertex(stldata.x3, stldata.y3, stldata.z3); + p->append_vertex(facet.data.x1, facet.data.y1, facet.data.z1); + p->append_vertex(facet.data.x2, facet.data.y2, facet.data.z2); + p->append_vertex(facet.data.x3, facet.data.y3, facet.data.z3); } } } |