mirror of https://github.com/vitalif/openscad
Added stand-alone 2D tesselator
parent
3e2ff23c00
commit
3f6a590a2f
|
@ -0,0 +1,6 @@
|
|||
This folder contains some CGAL test programs to easier develop and debug CGAL-based components.
|
||||
|
||||
## polyhole-tessellator
|
||||
|
||||
Tessellate an almost planar 3D polygon with holes into a vector of double precision 3D triangles.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
0,0,0
|
||||
2,0,0
|
||||
2,2,0
|
||||
0,2,0
|
||||
|
||||
0.5,0.5,0
|
||||
1.5,0.5,0
|
||||
1.5,1.5,0
|
||||
0.5,1.5,0
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
0,0,0
|
||||
2,0,0
|
||||
2,2,0
|
|
@ -0,0 +1,126 @@
|
|||
#include <boost/foreach.hpp>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <locale.h>
|
||||
|
||||
#include "cgalutils.h"
|
||||
|
||||
// Nef polyhedron are using CGAL_Kernel3 (Cartesian<Gmpq>)
|
||||
// Triangulation will use Epick
|
||||
|
||||
static void export_stl(const Polygons &triangles, std::ostream &output)
|
||||
{
|
||||
setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output
|
||||
output << "solid OpenSCAD_Model\n";
|
||||
BOOST_FOREACH(const Polygon &p, triangles) {
|
||||
assert(p.size() == 3); // STL only allows triangles
|
||||
std::stringstream stream;
|
||||
stream << p[0][0] << " " << p[0][1] << " " << p[0][2];
|
||||
std::string vs1 = stream.str();
|
||||
stream.str("");
|
||||
stream << p[1][0] << " " << p[1][1] << " " << p[1][2];
|
||||
std::string vs2 = stream.str();
|
||||
stream.str("");
|
||||
stream << p[2][0] << " " << p[2][1] << " " << p[2][2];
|
||||
std::string vs3 = stream.str();
|
||||
if (vs1 != vs2 && vs1 != vs3 && vs2 != vs3) {
|
||||
// The above condition ensures that there are 3 distinct vertices, but
|
||||
// they may be collinear. If they are, the unit normal is meaningless
|
||||
// so the default value of "1 0 0" can be used. If the vertices are not
|
||||
// collinear then the unit normal must be calculated from the
|
||||
// components.
|
||||
Vector3d normal = (p[1] - p[0]).cross(p[2] - p[0]);
|
||||
normal.normalize();
|
||||
output << " facet normal " << normal[0] << " " << normal[1] << " " << normal[2] << "\n";
|
||||
output << " outer loop\n";
|
||||
|
||||
BOOST_FOREACH(const Vector3d &v, p) {
|
||||
output << " vertex " << v[0] << " " << v[1] << " " << v[2] << "\n";
|
||||
}
|
||||
output << " endloop\n";
|
||||
output << " endfacet\n";
|
||||
}
|
||||
}
|
||||
output << "endsolid OpenSCAD_Model\n";
|
||||
setlocale(LC_NUMERIC, ""); // Set default locale
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
file format:
|
||||
1. polygon coordinates (x,y,z) are comma separated (+/- spaces) and
|
||||
each coordinate is on a separate line
|
||||
2. each polygon is separated by one or more blank lines
|
||||
*/
|
||||
bool import_polygon(PolyholeK &polyhole, const std::string &filename)
|
||||
{
|
||||
std::ifstream ifs(filename.c_str());
|
||||
if (!ifs) return false;
|
||||
|
||||
std::string line;
|
||||
PolygonK polygon;
|
||||
while (std::getline(ifs, line)) {
|
||||
std::stringstream ss(line);
|
||||
double X = 0.0, Y = 0.0, Z = 0.0;
|
||||
if (!(ss >> X)) {
|
||||
//ie blank lines => flag start of next polygon
|
||||
if (polygon.size() > 0) polyhole.push_back(polygon);
|
||||
polygon.clear();
|
||||
continue;
|
||||
}
|
||||
char c = ss.peek();
|
||||
while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces before comma
|
||||
if (c == ',') {ss.read(&c, 1); c = ss.peek();} //gobble comma
|
||||
while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces after comma
|
||||
if (!(ss >> Y)) {
|
||||
std::cerr << "Y error\n";
|
||||
return false;
|
||||
}
|
||||
c = ss.peek();
|
||||
while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces before comma
|
||||
if (c == ',') {ss.read(&c, 1); c = ss.peek();} //gobble comma
|
||||
while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces after comma
|
||||
if (!(ss >> Z)) {
|
||||
std::cerr << "Z error\n";
|
||||
return false;
|
||||
}
|
||||
polygon.push_back(Vertex3K(X, Y, Z));
|
||||
}
|
||||
if (polygon.size() > 0) polyhole.push_back(polygon);
|
||||
ifs.close();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
PolyholeK polyhole;
|
||||
if (argc == 2) {
|
||||
if (!import_polygon(polyhole, argv[1])) {
|
||||
std::cerr << "Error importing polygon" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
std::cerr << "Imported " << polyhole.size() << " polygons" << std::endl;
|
||||
}
|
||||
else {
|
||||
//construct two non-intersecting nested polygons
|
||||
PolygonK polygon1;
|
||||
polygon1.push_back(Vertex3K(0,0,0));
|
||||
polygon1.push_back(Vertex3K(2,0,0));
|
||||
polygon1.push_back(Vertex3K(2,2,0));
|
||||
polygon1.push_back(Vertex3K(0,2,0));
|
||||
PolygonK polygon2;
|
||||
polygon2.push_back(Vertex3K(0.5,0.5,0));
|
||||
polygon2.push_back(Vertex3K(1.5,0.5,0));
|
||||
polygon2.push_back(Vertex3K(1.5,1.5,0));
|
||||
polygon2.push_back(Vertex3K(0.5,1.5,0));
|
||||
polyhole.push_back(polygon1);
|
||||
polyhole.push_back(polygon2);
|
||||
}
|
||||
|
||||
Polygons triangles;
|
||||
bool ok = CGALUtils::tessellatePolygonWithHoles(polyhole, triangles);
|
||||
std::cerr << "Tessellated into " << triangles.size() << " triangles" << std::endl;
|
||||
|
||||
export_stl(triangles, std::cout);
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
debug: DEFINES += DEBUG
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
INCLUDEPATH += ../src
|
||||
DEPENDPATH += ../src
|
||||
|
||||
# Handle custom library location.
|
||||
# Used when manually installing 3rd party libraries
|
||||
isEmpty(OPENSCAD_LIBDIR) OPENSCAD_LIBDIR = $$(OPENSCAD_LIBRARIES)
|
||||
macx:isEmpty(OPENSCAD_LIBDIR) {
|
||||
exists(/opt/local):exists(/usr/local/Cellar) {
|
||||
error("It seems you might have libraries in both /opt/local and /usr/local. Please specify which one to use with qmake OPENSCAD_LIBDIR=<prefix>")
|
||||
} else {
|
||||
exists(/opt/local) {
|
||||
#Default to MacPorts on Mac OS X
|
||||
message("Automatically searching for libraries in /opt/local. To override, use qmake OPENSCAD_LIBDIR=<prefix>")
|
||||
OPENSCAD_LIBDIR = /opt/local
|
||||
} else:exists(/usr/local/Cellar) {
|
||||
message("Automatically searching for libraries in /usr/local. To override, use qmake OPENSCAD_LIBDIR=<prefix>")
|
||||
OPENSCAD_LIBDIR = /usr/local
|
||||
}
|
||||
}
|
||||
}
|
||||
!isEmpty(OPENSCAD_LIBDIR) {
|
||||
QMAKE_INCDIR = $$OPENSCAD_LIBDIR/include
|
||||
QMAKE_LIBDIR = $$OPENSCAD_LIBDIR/lib
|
||||
}
|
||||
|
||||
TARGET = polyhole-tessellator
|
||||
mac {
|
||||
CONFIG -= app_bundle
|
||||
}
|
||||
|
||||
macx {
|
||||
# Mac needs special care to link against the correct C++ library
|
||||
# We attempt to auto-detect it by inspecting Boost
|
||||
dirs = $${BOOSTDIR} $${QMAKE_LIBDIR}
|
||||
for(dir, dirs) {
|
||||
system(grep -q __112basic_string $${dir}/libboost_thread* >& /dev/null) {
|
||||
message("Detected libc++-linked boost in $${dir}")
|
||||
CONFIG += libc++
|
||||
}
|
||||
}
|
||||
|
||||
libc++ {
|
||||
QMAKE_CXXFLAGS += -stdlib=libc++
|
||||
QMAKE_LFLAGS += -stdlib=libc++
|
||||
QMAKE_OBJECTIVE_CFLAGS += -stdlib=libc++
|
||||
# libc++ on requires Mac OS X 10.7+
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
|
||||
}
|
||||
}
|
||||
|
||||
# See Dec 2011 OpenSCAD mailing list, re: CGAL/GCC bugs.
|
||||
*g++* {
|
||||
QMAKE_CXXFLAGS *= -fno-strict-aliasing
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-local-typedefs # ignored before 4.8
|
||||
}
|
||||
|
||||
*clang* {
|
||||
# http://llvm.org/bugs/show_bug.cgi?id=9182
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-overloaded-virtual
|
||||
# disable enormous amount of warnings about CGAL / boost / etc
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions
|
||||
# might want to actually turn this on once in a while
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-format-security
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Application configuration
|
||||
CONFIG += cgal
|
||||
CONFIG += boost
|
||||
CONFIG += eigen
|
||||
CONFIG += gettext
|
||||
|
||||
include(../common.pri)
|
||||
|
||||
HEADERS += ../src/cgal.h \
|
||||
../src/cgalutils.h \
|
||||
../src/linalg.h \
|
||||
../src/printutils.h
|
||||
|
||||
SOURCES += polyhole-tessellator.cpp \
|
||||
../src/cgalutils-tess.cc \
|
||||
../src/printutils.cc
|
Loading…
Reference in New Issue