summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/control.cc6
-rw-r--r--src/csgtermnormalizer.cc9
-rw-r--r--src/csgtermnormalizer.h1
-rw-r--r--src/import.cc80
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);
}
}
}
contact: Jan Huwald // Impressum