//----------------------------------------------------------------------------- // Triangle mesh file reader. Reads an STL file triangle mesh and creates // a SovleSpace SMesh from it. Supports only Linking, not import. // // Copyright 2020 Paul Kahler. //----------------------------------------------------------------------------- #include "solvespace.h" #include "sketch.h" #include #define MIN_POINT_DISTANCE 0.001 // we will check for duplicate verticies and keep all their normals class vertex { public: Vector p; std::vector normal; }; static bool isEdgeVertex(vertex &v) { unsigned int i,j; bool result = false; for(i=0;i &lv, Vector &p, Vector &n) { unsigned int i; for(i=0; iAdd(&en); return en.h; } // check if a vertex is unique and add it via newPoint if it is. static void addVertex(EntityList *el, Vector v) { if(el->n < 15000) { int id = el->n+2; newPoint(el, id, v); } } static hEntity newLine(EntityList *el, int id, hEntity p0, hEntity p1) { Entity en = {}; en.type = Entity::Type::LINE_SEGMENT; en.point[0] = p0; en.point[1] = p1; en.extraPoints = 0; en.timesApplied = 0; en.group.v = 493; en.construction = true; en.style.v = Style::CONSTRUCTION; en.actVisible = true; en.forceHidden = false; en.h.v = id + en.group.v*65536; el->Add(&en); return en.h; } namespace SolveSpace { bool LinkStl(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *sh) { dbp("\nLink STL triangle mesh."); el->Clear(); std::string data; if(!ReadFile(filename, &data)) { Error("Couldn't read from '%s'", filename.raw.c_str()); return false; } std::stringstream f(data); char str[80] = {}; f.read(str, 80); uint32_t n; uint32_t color; f.read((char*)&n, 4); dbp("%d triangles", n); float x,y,z; float xn,yn,zn; //add the STL origin as an entity addVertex(el, Vector::From(0.0, 0.0, 0.0)); std::vector verts = {}; for(uint32_t i = 0; i> 7) & 0xf8; tr.meta.color.green = (color >> 2) & 0xf8; tr.meta.color.blue = (color << 3); tr.meta.color.alpha = 255; } else { tr.meta.color.red = 90; tr.meta.color.green = 120; tr.meta.color.blue = 140; tr.meta.color.alpha = 255; } m->AddTriangle(&tr); Vector normal = tr.Normal().WithMagnitude(1.0); addUnique(verts, tr.a, normal); addUnique(verts, tr.b, normal); addUnique(verts, tr.c, normal); } dbp("%d verticies", verts.size()); BBox box = {}; box.minp = verts[0].p; box.maxp = verts[0].p; // determine the bounding box for all vertexes for(unsigned int i=1; in+2; p[0] = newPoint(el, id++, Vector::From(box.minp.x, box.minp.y, box.minp.z)); p[1] = newPoint(el, id++, Vector::From(box.maxp.x, box.minp.y, box.minp.z)); p[2] = newPoint(el, id++, Vector::From(box.minp.x, box.maxp.y, box.minp.z)); p[3] = newPoint(el, id++, Vector::From(box.maxp.x, box.maxp.y, box.minp.z)); p[4] = newPoint(el, id++, Vector::From(box.minp.x, box.minp.y, box.maxp.z)); p[5] = newPoint(el, id++, Vector::From(box.maxp.x, box.minp.y, box.maxp.z)); p[6] = newPoint(el, id++, Vector::From(box.minp.x, box.maxp.y, box.maxp.z)); p[7] = newPoint(el, id++, Vector::From(box.maxp.x, box.maxp.y, box.maxp.z)); newLine(el, id++, p[0], p[1]); newLine(el, id++, p[0], p[2]); newLine(el, id++, p[3], p[1]); newLine(el, id++, p[3], p[2]); newLine(el, id++, p[4], p[5]); newLine(el, id++, p[4], p[6]); newLine(el, id++, p[7], p[5]); newLine(el, id++, p[7], p[6]); newLine(el, id++, p[0], p[4]); newLine(el, id++, p[1], p[5]); newLine(el, id++, p[2], p[6]); newLine(el, id++, p[3], p[7]); for(unsigned int i=0; i