Merge branch 'master' into color-priority

felipesanches-svg
Marius Kintel 2011-12-27 14:46:10 +01:00
commit bac92dbd0e
19 changed files with 381 additions and 267 deletions

View File

@ -6,35 +6,64 @@ boost {
!isEmpty(BOOST_DIR) {
QMAKE_INCDIR += $$BOOST_DIR
message("boost location: $$BOOST_DIR")
win32:QMAKE_LIBDIR += -L$$BOOST_DIR/lib
win32: QMAKE_LIBDIR += -L$$BOOST_DIR/lib
}
win32:!CONFIG(mingw-cross-env) {
LIBS += -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1
}
CONFIG(mingw-cross-env) {
DEFINES += BOOST_STATIC
DEFINES += BOOST_THREAD_USE_LIB
DEFINES += Boost_USE_STATIC_LIBS
LIBS += -lboost_thread_win32-mt -lboost_program_options-mt
BOOST_LINK_FLAGS = -lboost_thread_win32-mt -lboost_program_options-mt
}
unix {
BMT_TEST1 = /usr/lib64/libboost*thread-mt*
BMT_TEST2 = /usr/lib/libboost*thread-mt*
BMT_TEST3 = $$BOOST_DIR/lib/libboost*thread-mt*
isEmpty(BOOST_LINK_FLAGS):win32 {
BOOST_LINK_FLAGS = -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1
}
exists($$BMT_TEST1)|exists($$BMT_TEST2)|exists($$BMT_TEST3) {
LIBS += -lboost_thread-mt -lboost_program_options-mt
BOOST_IS_MT = true
}
}
unix|macx {
isEmpty(BOOST_IS_MT) {
LIBS += -lboost_thread -lboost_program_options
# check for OPENSCAD_LIBDIR + multithread
isEmpty(BOOST_LINK_FLAGS) {
OPENSCAD_LIBDIR = $$(OPENSCAD_LIBRARIES)
!isEmpty(OPENSCAD_LIBDIR) {
exists($$OPENSCAD_LIBDIR/lib/libboost*thread-mt*) {
BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt
} else {
exists($$OPENSCAD_LIBDIR/lib/libboost*thread*) {
BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options
}
}
}
}
# check for BOOSTDIR + multithread
isEmpty(BOOST_LINK_FLAGS) {
BOOST_DIR = $$(BOOSTDIR)
!isEmpty(BOOST_DIR) {
exists($$BOOST_DIR/lib/libboost*thread-mt*) {
BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt
} else {
exists($$BOOST_DIR/lib/libboost*thread*) {
BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options
}
}
}
}
isEmpty(BOOST_LINK_FLAGS) {
unix {
BMT_TEST1 = /usr/lib64/libboost*thread-mt*
BMT_TEST2 = /usr/lib/libboost*thread-mt*
exists($$BMT_TEST1)|exists($$BMT_TEST2) {
BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt
}
}
}
isEmpty(BOOST_LINK_FLAGS) {
unix|macx {
BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options
}
}
LIBS += $$BOOST_LINK_FLAGS
}

View File

@ -259,7 +259,6 @@ o variants of module transparent() { %child(); }
o define modules
o define functions
o built-in variables and constants (builtin-tests.scad)
o Write a regression test for the hexagonal cylinder orientation issue
o Caching
- Test that caching is actually performed (speedup + same results)
- Test the modifier characters correctly influence the cache (also when

View File

@ -50,26 +50,33 @@ Adding a new regression test:
Troubleshooting:
------------------------------
0. Headless unix servers (no X11)
0. Headless unix servers
$ Xvfb :5 -screen 0 800x600x24 &
If you are attempting to run the tests on a unix-like system but only
have shell-console access, you may be able to run the tests by using a
virtual framebuffer program like Xvnc or Xvfb. For example:
$ Xvfb :5 -screen 0 800x600x24 &
$ DISPLAY=:5 ctest
1. Trouble finding libraries
Some versions of Xvfb may fail, however.
1. Trouble finding libraries on unix
To help CMAKE find eigen2, OpenCSG, CGAL, Boost, and GLEW, you can use
environment variables, just like for the main qmake & openscad.pro. Examples:
OPENCSGDIR=~/OpenCSG-1.3.2 EIGEN2DIR=~/eigen2 cmake .
OPENSCAD_LIBRARIES=~ cmake .
CGALDIR=~/CGAL-3.9 BOOSTDIR=~/boost-1.47.0 cmake .
Valid variables are as follows (see CMakeLists.txt for more info):
Valid variables are as follows:
BOOSTDIR, CGALDIR, EIGEN2DIR, GLEWDIR, OPENCSGDIR, OPENSCAD_LIBRARIES
2. Logs
2. Location of logs
Logs of test runs are found in tests/build/Testing/Temporary
Pretty-printed index.html is in a subdir of tests/build/Testing/Temporary
A pretty-printed index.html is in a subdir of tests/build/Testing/Temporary
Expected results are found in tests/regression/*
Actual results are found in tests/build/testname-output/*
@ -77,28 +84,23 @@ Actual results are found in tests/build/testname-output/*
Cross-compiling of tests has not been automated nor tested
4. Image-based tests takes a long time, they fail, and it says 'return -11'
4. Image-based tests takes a long time, they fail, and the log says 'return -11'
Imagemagick may have crashed. You can try using the alternate IM comparator
based on Normalized Cross Correlation. Pass -DCOMPARATOR=ncc to cmake
Imagemagick may have crashed while comparing the expected images to the
test-run generated (actual) images. You can try using the alternate
ImageMagick comparison method by by erasing CMakeCache, and re-running
cmake with -DCOMPARATOR=ncc. This will enable the Normalized Cross
Comparison method.
5. Testing images fails with 'morphology' not found for ImageMagick
5. Testing images fails with 'morphology not found" for ImageMagick in the log
Your version of imagemagick is old. Upgrade, or pass -DCOMPARATOR=old to
cmake. The comparison will be of lowered reliability.
6. Unexplained or bizarre errors.
6. Other issues
This can happen on dynamic-library systems (linux) where you try to use
your own version of a library while the system still has another version
under the system paths. You can diagnose this by looking at your cmake
log as well as your sysinfo.txt file, as well as running 'ldd' against
your binaries, to make sure that the proper versions of libraries are
getting compiled and linked with the test binaries.
7. Other issues
The OpenSCAD User Manual has a section on buildling. Check there for updates:
The OpenSCAD User Manual has a section on buildling. Please check there
for updates:
http://en.wikibooks.org/wiki/OpenSCAD_User_Manual

View File

@ -1,20 +1,36 @@
eigen2 {
CONFIG(mingw-cross-env) {
EIGEN2_INCLUDEPATH = mingw-cross-env/include/eigen2
}
# Optionally specify location of Eigen2 using the
# OPENSCAD_LIBRARIES env. variable
isEmpty(EIGEN2_INCLUDEPATH) {
OPENSCAD_LIBRARIES_DIR = $$(OPENSCAD_LIBRARIES)
!isEmpty(OPENSCAD_LIBRARIES_DIR) {
exists($$OPENSCAD_LIBRARIES_DIR/include/eigen2) {
EIGEN2_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/eigen2
}
}
}
# Optionally specify location of Eigen2 using the
# EIGEN2DIR env. variable
EIGEN2_DIR = $$(EIGEN2DIR)
!isEmpty(EIGEN2_DIR) {
EIGEN2_INCLUDEPATH = $$EIGEN2_DIR
}
else {
CONFIG(mingw-cross-env) {
EIGEN2_INCLUDEPATH = mingw-cross-env/include/eigen2
} else {
freebsd-g++: EIGEN2_INCLUDEPATH *= /usr/local/include/eigen2
macx: EIGEN2_INCLUDEPATH *= /opt/local/include/eigen2
!macx:!freebsd-g++:!win32:EIGEN2_INCLUDEPATH *= /usr/include/eigen2
isEmpty(EIGEN2_INCLUDEPATH) {
EIGEN2_DIR = $$(EIGEN2DIR)
!isEmpty(EIGEN2_DIR) {
EIGEN2_INCLUDEPATH = $$EIGEN2_DIR
message("EIGEN2 location: $$EIGEN2_INCLUDEPATH")
}
}
isEmpty(EIGEN2_INCLUDEPATH) {
freebsd-g++: EIGEN2_INCLUDEPATH = /usr/local/include/eigen2
macx: EIGEN2_INCLUDEPATH = /opt/local/include/eigen2
linux*: EIGEN2_INCLUDEPATH = /usr/include/eigen2
}
# eigen2 being under 'include/eigen2' needs special prepending
QMAKE_INCDIR_QT = $$EIGEN2_INCLUDEPATH $$QMAKE_INCDIR_QT

View File

@ -146,6 +146,7 @@ HEADERS += src/renderer.h \
src/builtin.h \
src/context.h \
src/csgterm.h \
src/csgtermnormalizer.h \
src/dxfdata.h \
src/dxfdim.h \
src/dxftess.h \
@ -197,6 +198,7 @@ SOURCES += src/mathc99.cc \
src/node.cc \
src/context.cc \
src/csgterm.cc \
src/csgtermnormalizer.cc \
src/polyset.cc \
src/csgops.cc \
src/transform.cc \

View File

@ -7,7 +7,9 @@ CGALCache *CGALCache::inst = NULL;
void CGALCache::insert(const std::string &id, const CGAL_Nef_polyhedron &N)
{
this->cache.insert(id, new CGAL_Nef_polyhedron(N), N.weight());
#ifdef DEBUG
PRINTF("CGAL Cache insert: %s (%d verts)", id.substr(0, 40).c_str(), N.weight());
#endif
}
void CGALCache::print()

View File

@ -139,127 +139,6 @@ void CSGTerm::initBoundingBox()
}
}
shared_ptr<CSGTerm> CSGTerm::normalize(shared_ptr<CSGTerm> term)
{
// This function implements the CSG normalization
// Reference:
// Goldfeather, J., Molnar, S., Turk, G., and Fuchs, H. Near
// Realtime CSG Rendering Using Tree Normalization and Geometric
// Pruning. IEEE Computer Graphics and Applications, 9(3):20-28,
// 1989.
// http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf
if (term->type == TYPE_PRIMITIVE) {
return term;
}
do {
while (term && normalize_tail(term)) { }
if (!term || term->type == TYPE_PRIMITIVE) return term;
term->left = normalize(term->left);
} while (term->type != TYPE_UNION &&
(term->right->type != TYPE_PRIMITIVE || term->left->type == TYPE_UNION));
term->right = normalize(term->right);
// FIXME: Do we need to take into account any transformation of item here?
if (!term->right) {
if (term->type == TYPE_UNION || term->type == TYPE_DIFFERENCE) return term->left;
else return term->right;
}
if (!term->left) {
if (term->type == TYPE_UNION) return term->right;
else return term->left;
}
return term;
}
bool CSGTerm::normalize_tail(shared_ptr<CSGTerm> &term)
{
if (term->type == TYPE_UNION || term->type == TYPE_PRIMITIVE) return false;
// Part A: The 'x . (y . z)' expressions
shared_ptr<CSGTerm> x = term->left;
shared_ptr<CSGTerm> y = term->right->left;
shared_ptr<CSGTerm> z = term->right->right;
shared_ptr<CSGTerm> result = term;
// 1. x - (y + z) -> (x - y) - z
if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_UNION) {
term = createCSGTerm(TYPE_DIFFERENCE,
createCSGTerm(TYPE_DIFFERENCE, x, y),
z);
return true;
}
// 2. x * (y + z) -> (x * y) + (x * z)
else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_UNION) {
term = createCSGTerm(TYPE_UNION,
createCSGTerm(TYPE_INTERSECTION, x, y),
createCSGTerm(TYPE_INTERSECTION, x, z));
return true;
}
// 3. x - (y * z) -> (x - y) + (x - z)
else if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_INTERSECTION) {
term = createCSGTerm(TYPE_UNION,
createCSGTerm(TYPE_DIFFERENCE, x, y),
createCSGTerm(TYPE_DIFFERENCE, x, z));
return true;
}
// 4. x * (y * z) -> (x * y) * z
else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_INTERSECTION) {
term = createCSGTerm(TYPE_INTERSECTION,
createCSGTerm(TYPE_INTERSECTION, x, y),
z);
return true;
}
// 5. x - (y - z) -> (x - y) + (x * z)
else if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_DIFFERENCE) {
term = createCSGTerm(TYPE_UNION,
createCSGTerm(TYPE_DIFFERENCE, x, y),
createCSGTerm(TYPE_INTERSECTION, x, z));
return true;
}
// 6. x * (y - z) -> (x * y) - z
else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_DIFFERENCE) {
term = createCSGTerm(TYPE_DIFFERENCE,
createCSGTerm(TYPE_INTERSECTION, x, y),
z);
return true;
}
// Part B: The '(x . y) . z' expressions
x = term->left->left;
y = term->left->right;
z = term->right;
// 7. (x - y) * z -> (x * z) - y
if (term->left->type == TYPE_DIFFERENCE && term->type == TYPE_INTERSECTION) {
term = createCSGTerm(TYPE_DIFFERENCE,
createCSGTerm(TYPE_INTERSECTION, x, z),
y);
return true;
}
// 8. (x + y) - z -> (x - z) + (y - z)
else if (term->left->type == TYPE_UNION && term->type == TYPE_DIFFERENCE) {
term = createCSGTerm(TYPE_UNION,
createCSGTerm(TYPE_DIFFERENCE, x, z),
createCSGTerm(TYPE_DIFFERENCE, y, z));
return true;
}
// 9. (x + y) * z -> (x * z) + (y * z)
else if (term->left->type == TYPE_UNION && term->type == TYPE_INTERSECTION) {
term = createCSGTerm(TYPE_UNION,
createCSGTerm(TYPE_INTERSECTION, x, z),
createCSGTerm(TYPE_INTERSECTION, y, z));
return true;
}
return false;
}
std::string CSGTerm::dump()
{
std::stringstream dump;

View File

@ -33,9 +33,6 @@ public:
const BoundingBox &getBoundingBox() const { return this->bbox; }
static shared_ptr<CSGTerm> normalize(shared_ptr<CSGTerm> term);
static bool normalize_tail(shared_ptr<CSGTerm> &term);
std::string dump();
private:
CSGTerm(type_e type, shared_ptr<CSGTerm> left, shared_ptr<CSGTerm> right);

150
src/csgtermnormalizer.cc Normal file
View File

@ -0,0 +1,150 @@
#include "csgtermnormalizer.h"
#include "csgterm.h"
#include "printutils.h"
shared_ptr<CSGTerm> CSGTermNormalizer::normalize(const shared_ptr<CSGTerm> &root)
{
shared_ptr<CSGTerm> temp = root;
while (1) {
shared_ptr<CSGTerm> n = normalizePass(temp);
if (temp == n) break;
temp = n;
int num = count(temp);
#ifdef DEBUG
PRINTF("Normalize count: %d\n", num);
#endif
if (num > 5000) {
PRINTF("WARNING: Normalized tree is growing past 5000 elements. Aborting normalization.\n");
return root;
}
}
return temp;
}
shared_ptr<CSGTerm> CSGTermNormalizer::normalizePass(shared_ptr<CSGTerm> term)
{
// This function implements the CSG normalization
// Reference:
// Goldfeather, J., Molnar, S., Turk, G., and Fuchs, H. Near
// Realtime CSG Rendering Using Tree Normalization and Geometric
// Pruning. IEEE Computer Graphics and Applications, 9(3):20-28,
// 1989.
// http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf
if (term->type == CSGTerm::TYPE_PRIMITIVE) {
return term;
}
do {
while (term && normalize_tail(term)) { }
if (!term || term->type == CSGTerm::TYPE_PRIMITIVE) return term;
term->left = normalizePass(term->left);
} while (term->type != CSGTerm::TYPE_UNION &&
(term->right->type != CSGTerm::TYPE_PRIMITIVE || term->left->type == CSGTerm::TYPE_UNION));
term->right = normalizePass(term->right);
// FIXME: Do we need to take into account any transformation of item here?
if (!term->right) {
if (term->type == CSGTerm::TYPE_UNION || term->type == CSGTerm::TYPE_DIFFERENCE) return term->left;
else return term->right;
}
if (!term->left) {
if (term->type == CSGTerm::TYPE_UNION) return term->right;
else return term->left;
}
return term;
}
bool CSGTermNormalizer::normalize_tail(shared_ptr<CSGTerm> &term)
{
if (term->type == CSGTerm::TYPE_UNION || term->type == CSGTerm::TYPE_PRIMITIVE) return false;
// Part A: The 'x . (y . z)' expressions
shared_ptr<CSGTerm> x = term->left;
shared_ptr<CSGTerm> y = term->right->left;
shared_ptr<CSGTerm> z = term->right->right;
shared_ptr<CSGTerm> result = term;
// 1. x - (y + z) -> (x - y) - z
if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_UNION) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE,
CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y),
z);
return true;
}
// 2. x * (y + z) -> (x * y) + (x * z)
else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_UNION) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y),
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z));
return true;
}
// 3. x - (y * z) -> (x - y) + (x - z)
else if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_INTERSECTION) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,
CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y),
CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, z));
return true;
}
// 4. x * (y * z) -> (x * y) * z
else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_INTERSECTION) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION,
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y),
z);
return true;
}
// 5. x - (y - z) -> (x - y) + (x * z)
else if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_DIFFERENCE) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,
CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y),
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z));
return true;
}
// 6. x * (y - z) -> (x * y) - z
else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_DIFFERENCE) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE,
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y),
z);
return true;
}
// Part B: The '(x . y) . z' expressions
x = term->left->left;
y = term->left->right;
z = term->right;
// 7. (x - y) * z -> (x * z) - y
if (term->left->type == CSGTerm::TYPE_DIFFERENCE && term->type == CSGTerm::TYPE_INTERSECTION) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE,
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z),
y);
return true;
}
// 8. (x + y) - z -> (x - z) + (y - z)
else if (term->left->type == CSGTerm::TYPE_UNION && term->type == CSGTerm::TYPE_DIFFERENCE) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,
CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, z),
CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, y, z));
return true;
}
// 9. (x + y) * z -> (x * z) + (y * z)
else if (term->left->type == CSGTerm::TYPE_UNION && term->type == CSGTerm::TYPE_INTERSECTION) {
term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z),
CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, y, z));
return true;
}
return false;
}
int CSGTermNormalizer::count(const shared_ptr<CSGTerm> &term) const
{
if (!term) return 0;
return term->type == CSGTerm::TYPE_PRIMITIVE ? 1 : 0 + count(term->left) + count(term->right);
}

22
src/csgtermnormalizer.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef CSGTERMNORMALIZER_H_
#define CSGTERMNORMALIZER_H_
#include "memory.h"
class CSGTermNormalizer
{
public:
CSGTermNormalizer() : counter(0) {}
~CSGTermNormalizer() {}
shared_ptr<class CSGTerm> normalize(const shared_ptr<CSGTerm> &term);
private:
shared_ptr<CSGTerm> normalizePass(shared_ptr<CSGTerm> term) ;
bool normalize_tail(shared_ptr<CSGTerm> &term);
int count(const shared_ptr<CSGTerm> &term) const;
int counter;
};
#endif

View File

@ -45,6 +45,7 @@
#include "ProgressWidget.h"
#endif
#include "ThrownTogetherRenderer.h"
#include "csgtermnormalizer.h"
#include <QMenu>
#include <QTime>
@ -782,15 +783,8 @@ void MainWindow::compileCSG(bool procevents)
if (procevents)
QApplication::processEvents();
this->root_norm_term = this->root_raw_term;
// CSG normalization
while (1) {
shared_ptr<CSGTerm> n = CSGTerm::normalize(this->root_norm_term);
if (this->root_norm_term == n) break;
this->root_norm_term = n;
}
CSGTermNormalizer normalizer;
this->root_norm_term = normalizer.normalize(this->root_raw_term);
assert(this->root_norm_term);
root_chain = new CSGChain();
@ -804,11 +798,7 @@ void MainWindow::compileCSG(bool procevents)
highlights_chain = new CSGChain();
for (unsigned int i = 0; i < highlight_terms.size(); i++) {
while (1) {
shared_ptr<CSGTerm> n = CSGTerm::normalize(highlight_terms[i]);
if (highlight_terms[i] == n) break;
highlight_terms[i] = n;
}
highlight_terms[i] = normalizer.normalize(highlight_terms[i]);
highlights_chain->import(highlight_terms[i]);
}
}
@ -821,11 +811,7 @@ void MainWindow::compileCSG(bool procevents)
background_chain = new CSGChain();
for (unsigned int i = 0; i < background_terms.size(); i++) {
while (1) {
shared_ptr<CSGTerm> n = CSGTerm::normalize(background_terms[i]);
if (background_terms[i] == n) break;
background_terms[i] = n;
}
background_terms[i] = normalizer.normalize(background_terms[i]);
background_chain->import(background_terms[i]);
}
}

View File

@ -364,6 +364,10 @@ int main(int argc, char **argv)
}
if (dxf_output_file) {
if (root_N.dim != 2) {
fprintf(stderr, "Current top level object is not a 2D object.\n");
exit(1);
}
std::ofstream fstream(dxf_output_file);
if (!fstream.is_open()) {
PRINTF("Can't open file \"%s\" for export", dxf_output_file);

View File

@ -12,4 +12,9 @@ translate([22,-11,0]) cylinder(h=5, r=5, r1=0, center=true);
translate([22,0,0]) cylinder(h=5, r=5, r2=0);
translate([22,11,0]) cylinder(h=15, r=5, r2=5);
// This tests for hexagonal cylinder orientation, since people
// tend to "abuse" this for captured nut slots
translate([-10,0,0]) cylinder(h=2, r=3, $fn=6);
// FIXME: We could test $fs, $fa, $fn as well

View File

@ -64,22 +64,32 @@ endif()
# Build test apps
#
function(inclusion user_set_path found_paths)
# This function exists as a wrapper for INCLUDE_DIRECTORIES
# to deal with systems in which some libraries are found
# in the system paths, (/usr) but others are found in customized
# paths set in environment variables (CGAL_DIR).
# message(STATUS "inclusion ${user_set_path} ${found_paths}")
# message(STATUS "inclusion ${${user_set_path}} ${${found_paths}}")
set( inclusion_match 0 )
foreach( found_path ${${found_paths}} )
if (${found_path} MATCHES ${${user_set_path}}.*)
set( inclusion_match 1 )
endif()
endforeach()
if (user_set_path AND inclusion_match)
include_directories(BEFORE ${${found_paths}})
# message(STATUS "inclusion prepend ${${found_paths}} for ${user_set_path}")
else()
include_directories(AFTER ${${found_paths}})
# message(STATUS "inclusion append ${${found_paths}} for ${user_set_path}")
endif()
set( inclusion_match 0 )
endfunction()
# Boost
if (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
set(BOOST_ROOT "$ENV{OPENSCAD_LIBRARIES}")
endif()
if (NOT $ENV{BOOSTDIR} STREQUAL "")
set(BOOST_DIR "$ENV{BOOSTDIR}")
endif()
if (NOT ${BOOST_DIR} STREQUAL "")
set(BOOST_ROOT ${BOOST_DIR})
message(STATUS "BOOST_ROOT: " ${BOOST_ROOT})
set(Boost_NO_SYSTEM_PATHS "TRUE")
set(Boost_DEBUG TRUE)
endif()
# Update this if FindBoost.cmake gets out of sync with the current boost release
# set(Boost_ADDITIONAL_VERSIONS "1.47.0" "1.46.0")
if (WIN32)
set(Boost_USE_STATIC_LIBS TRUE)
@ -87,21 +97,32 @@ if (WIN32)
set(BOOST_THREAD_USE_LIB TRUE)
endif()
# Update this if FindBoost.cmake gets out of sync with the current boost release
# set(Boost_ADDITIONAL_VERSIONS "1.47.0" "1.46.0")
find_package( Boost 1.35.0 COMPONENTS thread program_options REQUIRED)
if(Boost_FOUND)
message(STATUS "Boost includes found: " ${Boost_INCLUDE_DIRS})
message(STATUS "Boost libraries found:")
foreach(boostlib ${Boost_LIBRARIES})
message(STATUS " " ${boostlib})
endforeach()
include_directories(${Boost_INCLUDE_DIRS})
else()
message(STATUS "BOOST_ROOT: ${BOOST_ROOT}")
message(FATAL_ERROR "Boost not found.")
if (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
set(BOOST_ROOT "$ENV{OPENSCAD_LIBRARIES}")
if (EXISTS ${BOOST_ROOT}/include/boost)
# if boost is under OPENSCAD_LIBRARIES, then
# don't look in the system paths (workaround FindBoost.cmake bug)
set(Boost_NO_SYSTEM_PATHS "TRUE")
message(STATUS "BOOST_ROOT: " ${BOOST_ROOT})
endif()
endif()
if (NOT $ENV{BOOSTDIR} STREQUAL "")
set(BOOST_ROOT "$ENV{BOOSTDIR}")
set(Boost_NO_SYSTEM_PATHS "TRUE")
set(Boost_DEBUG TRUE)
message(STATUS "BOOST_ROOT: " ${BOOST_ROOT})
endif()
find_package( Boost 1.35.0 COMPONENTS thread program_options REQUIRED)
message(STATUS "Boost includes found: " ${Boost_INCLUDE_DIRS})
message(STATUS "Boost libraries found:")
foreach(boostlib ${Boost_LIBRARIES})
message(STATUS " " ${boostlib})
endforeach()
inclusion(BOOST_ROOT Boost_INCLUDE_DIRS)
# Mac OS X
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
FIND_LIBRARY(COCOA_LIBRARY Cocoa REQUIRED)
@ -109,18 +130,11 @@ endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Qt4
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
# make /usr/local/include/qt4 come before /usr/local/include (QT4 vs QT3)
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
endif()
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
find_package(OpenGL REQUIRED)
find_package(Qt4 COMPONENTS QtCore QtGui QtOpenGL REQUIRED)
include(${QT_USE_FILE})
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE OFF)
endif()
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE OFF)
# Eigen2
@ -131,24 +145,32 @@ if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
endif()
endif()
if (NOT $ENV{EIGEN2DIR} STREQUAL "")
set(EIGEN2_DIR "$ENV{EIGEN2DIR}")
elseif (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
set(EIGEN2_DIR "$ENV{OPENSCAD_LIBRARIES}")
endif()
if (NOT EIGEN2_INCLUDE_DIR)
if (EIGEN2_DIR)
set(EIGEN2_FIND_HINTS "${EIGEN2_DIR}/include/eigen2")
endif()
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(EIGEN2_FIND_PATHS /usr/local/include/eigen2)
else()
set(EIGEN2_FIND_PATHS /opt/local/include/eigen2 /usr/include/eigen2)
endif()
find_path(EIGEN2_INCLUDE_DIR
Eigen/Core
HINTS $ENV{EIGEN2DIR}
PATHS /opt/local/include/eigen2 /usr/include/eigen2)
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_path(EIGEN2_INCLUDE_DIR
Eigen/Core
HINTS $ENV{EIGEN2DIR}
PATHS /usr/local/include/eigen2 )
endif()
HINTS ${EIGEN2_FIND_HINTS}
PATHS ${EIGEN2_FIND_PATHS})
if (NOT EIGEN2_INCLUDE_DIR)
message(FATAL_ERROR "Eigen2 not found")
else()
message(STATUS "Eigen2 found in " ${EIGEN2_INCLUDE_DIR})
endif()
endif()
include_directories(${EIGEN2_INCLUDE_DIR})
inclusion(EIGEN2_DIR EIGEN2_INCLUDE_DIR)
# OpenCSG
if (NOT $ENV{OPENCSGDIR} STREQUAL "")
@ -171,10 +193,14 @@ if (NOT OPENCSG_INCLUDE_DIR)
message(STATUS "OpenCSG library found in " ${OPENCSG_LIBRARY})
endif()
endif()
include_directories(${OPENCSG_INCLUDE_DIR})
inclusion(OPENCSG_DIR OPENCSG_INCLUDE_DIR)
# GLEW
if(WIN32_STATIC_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGLEW_STATIC")
endif()
if (NOT $ENV{GLEWDIR} STREQUAL "")
set(GLEW_DIR "$ENV{GLEWDIR}")
elseif (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
@ -182,11 +208,8 @@ elseif (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
endif()
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_PATH})
if(WIN32_STATIC_BUILD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGLEW_STATIC")
endif()
inclusion( GLEW_DIR GLEW_INCLUDE_PATH )
# Flex/Bison
find_package(BISON REQUIRED)
@ -211,8 +234,13 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/parser_yacc.c PROPERTIES
if (NOT $ENV{CGALDIR} STREQUAL "")
set(CGAL_DIR "$ENV{CGALDIR}")
elseif (NOT $ENV{OPENSCAD_LIBRARIES} STREQUAL "")
set(CGAL_DIR "$ENV{OPENSCAD_LIBRARIES}/lib/CGAL")
set(CMAKE_MODULE_PATH "${CGAL_DIR}")
if (EXISTS "$ENV{OPENSCAD_LIBRARIES}/lib/CGAL")
set(CGAL_DIR "$ENV{OPENSCAD_LIBRARIES}/lib/CGAL")
set(CMAKE_MODULE_PATH "${CGAL_DIR}")
elseif (EXISTS "$ENV{OPENSCAD_LIBRARIES}/include/CGAL")
set(CGAL_DIR "$ENV{OPENSCAD_LIBRARIES}")
set(CMAKE_MODULE_PATH "${CGAL_DIR}")
endif()
endif()
message(STATUS "CGAL_DIR: " ${CGAL_DIR})
find_package(CGAL REQUIRED)
@ -224,7 +252,7 @@ message(STATUS "CGAL libraries found in " ${CGAL_LIBRARIES_DIR} )
if("${CGAL_MAJOR_VERSION}.${CGAL_MINOR_VERSION}" VERSION_LESS 3.6)
message(FATAL_ERROR "CGAL >= 3.6 required")
endif()
include_directories(${CGAL_INCLUDE_DIRS})
inclusion(CGAL_DIR CGAL_INCLUDE_DIRS)
# Imagemagick
@ -253,6 +281,7 @@ set(CORE_SOURCES
../src/node.cc
../src/context.cc
../src/csgterm.cc
../src/csgtermnormalizer.cc
../src/polyset.cc
../src/csgops.cc
../src/transform.cc
@ -453,8 +482,8 @@ endfunction()
# comparison method to use
if (NOT $ENV{COMPARATOR} STREQUAL "")
set(COMPARATOR "$ENV{COMPARATOR}")
message(STATUS "ImageMagick method modified with COMPARATOR: " ${COMPARATOR})
endif()
message(STATUS "COMPARATOR: " ${COMPARATOR})
#
# This functions adds cmd-line tests given files.

View File

@ -19,6 +19,7 @@
#include "ThrownTogetherRenderer.h"
#include "csgterm.h"
#include "csgtermnormalizer.h"
#include "OffscreenView.h"
#include <QApplication>
@ -315,12 +316,8 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
}
// CSG normalization
csgInfo.root_norm_term = root_raw_term;
while (1) {
shared_ptr<CSGTerm> n = CSGTerm::normalize(csgInfo.root_norm_term);
if (csgInfo.root_norm_term == n) break;
csgInfo.root_norm_term = n;
}
CSGTermNormalizer normalizer;
csgInfo.root_norm_term = normalizer.normalize(root_raw_term);
assert(csgInfo.root_norm_term);
@ -333,11 +330,7 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
csgInfo.highlights_chain = new CSGChain();
for (unsigned int i = 0; i < csgInfo.highlight_terms.size(); i++) {
while (1) {
shared_ptr<CSGTerm> n = CSGTerm::normalize(csgInfo.highlight_terms[i]);
if (csgInfo.highlight_terms[i] == n) break;
csgInfo.highlight_terms[i] = n;
}
csgInfo.highlight_terms[i] = normalizer.normalize(csgInfo.highlight_terms[i]);
csgInfo.highlights_chain->import(csgInfo.highlight_terms[i]);
}
}
@ -347,11 +340,7 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
csgInfo.background_chain = new CSGChain();
for (unsigned int i = 0; i < csgInfo.background_terms.size(); i++) {
while (1) {
shared_ptr<CSGTerm> n = CSGTerm::normalize(csgInfo.background_terms[i]);
if (csgInfo.background_terms[i] == n) break;
csgInfo.background_terms[i] = n;
}
csgInfo.background_terms[i] = normalizer.normalize(csgInfo.background_terms[i]);
csgInfo.background_chain->import(csgInfo.background_terms[i]);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -29,4 +29,7 @@
multmatrix([[1, 0, 0, 22], [0, 1, 0, 11], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cylinder($fn = 0, $fa = 12, $fs = 2, h = 15, r1 = 5, r2 = 5, center = false);
}
multmatrix([[1, 0, 0, -10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cylinder($fn = 6, $fa = 12, $fs = 2, h = 2, r1 = 3, r2 = 3, center = false);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB