jgelderloos 2014-12-13 16:21:18 -05:00
commit 01ce545e1a
66 changed files with 1025 additions and 133 deletions

View File

@ -12,6 +12,10 @@
#
# PREFIX defines the base installation folder
#
# SUFFIX defines an optional suffix for the binary and the
# resource folder. E.g. using SUFFIX=-nightly will name the
# resulting binary openscad-nightly.
#
# Please see the 'Building' sections of the OpenSCAD user manual
# for updated tips & workarounds.
#
@ -78,8 +82,10 @@ macx {
TARGET = OpenSCAD
}
else {
TARGET = openscad
TARGET = openscad$${SUFFIX}
}
FULLNAME = openscad$${SUFFIX}
!isEmpty(SUFFIX): DEFINES += INSTALL_SUFFIX="\"\\\"$${SUFFIX}\\\"\""
macx {
ICON = icons/OpenSCAD.icns
@ -110,7 +116,6 @@ macx {
win* {
RC_FILE = openscad_win32.rc
QTPLUGIN += qtaccessiblewidgets
}
CONFIG += qt
@ -124,8 +129,6 @@ unix:!macx {
QMAKE_LIBS_OPENGL *= -lX11
}
#QTPLUGIN += qtaccessiblewidgets
netbsd* {
QMAKE_LFLAGS += -L/usr/X11R7/lib
QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib
@ -491,54 +494,57 @@ QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh
# Create install targets for the languages defined in LINGUAS
LINGUAS = $$cat(locale/LINGUAS)
LOCALE_PREFIX = $$PREFIX/share/openscad/locale
LOCALE_PREFIX = "$$PREFIX/share/$${FULLNAME}/locale"
for(language, LINGUAS) {
catalog = locale/$$language/LC_MESSAGES/openscad.mo
exists($$catalog) {
catalogdir = locale/$$language/LC_MESSAGES
exists(locale/$${language}.po) {
# Use .extra and copy manually as the source path might not exist,
# e.g. on a clean checkout. In that case qmake would not create
# the needed targets in the generated Makefile.
translation_path = translation_$${language}.path
translation_files = translation_$${language}.files
translation_extra = translation_$${language}.extra
translation_depends = translation_$${language}.depends
$$translation_path = $$LOCALE_PREFIX/$$language/LC_MESSAGES/
$$translation_files = $$catalog
$$translation_extra = cp -f $${catalogdir}/openscad.mo \"\$(INSTALL_ROOT)$$LOCALE_PREFIX/$$language/LC_MESSAGES/openscad.mo\"
$$translation_depends = locale/$${language}.po
INSTALLS += translation_$$language
}
}
examples.path = $$PREFIX/share/openscad/examples/
examples.path = "$$PREFIX/share/$${FULLNAME}/examples/"
examples.files = examples/*
INSTALLS += examples
libraries.path = $$PREFIX/share/openscad/libraries/
libraries.path = "$$PREFIX/share/$${FULLNAME}/libraries/"
libraries.files = libraries/*
INSTALLS += libraries
fonts.path = $$PREFIX/share/openscad/fonts/
fonts.path = "$$PREFIX/share/$${FULLNAME}/fonts/"
fonts.files = fonts/*
INSTALLS += fonts
colorschemes.path = $$PREFIX/share/openscad/color-schemes/
colorschemes.path = "$$PREFIX/share/$${FULLNAME}/color-schemes/"
colorschemes.files = color-schemes/*
INSTALLS += colorschemes
applications.path = $$PREFIX/share/applications
applications.files = icons/openscad.desktop
applications.extra = cat icons/openscad.desktop | sed -e \"'s/^Icon=openscad/Icon=$${FULLNAME}/; s/^Exec=openscad/Exec=$${FULLNAME}/'\" > \"\$(INSTALL_ROOT)$${applications.path}/$${FULLNAME}.desktop\"
INSTALLS += applications
mimexml.path = $$PREFIX/share/mime/packages
mimexml.files = icons/openscad.xml
mimexml.extra = cp -f icons/openscad.xml \"\$(INSTALL_ROOT)$${mimexml.path}/$${FULLNAME}.xml\"
INSTALLS += mimexml
appdata.path = $$PREFIX/share/appdata
appdata.files = openscad.appdata.xml
appdata.extra = cp -f openscad.appdata.xml \"\$(INSTALL_ROOT)$${appdata.path}/$${FULLNAME}.appdata.xml\"
INSTALLS += appdata
icons.path = $$PREFIX/share/pixmaps
icons.files = icons/openscad.png
icons.extra = cp -f icons/openscad.png \"\$(INSTALL_ROOT)$${icons.path}/$${FULLNAME}.png\"
INSTALLS += icons
man.path = $$PREFIX/share/man/man1
man.files = doc/openscad.1
man.extra = cp -f doc/openscad.1 \"\$(INSTALL_ROOT)$${man.path}/$${FULLNAME}.1\"
INSTALLS += man
CONFIG(winconsole) {

View File

@ -515,7 +515,7 @@ build_freetype()
cd "$BASEDIR"/src
rm -rf "freetype-$version"
if [ ! -f "freetype-$version.tar.gz" ]; then
curl --insecure -LO "http://download.savannah.gnu.org/releases/freetype/freetype-$version.tar.gz"
curl --insecure -LO "http://downloads.sourceforge.net/project/freetype/freetype2/$version/freetype-$version.tar.gz"
fi
tar xzf "freetype-$version.tar.gz"
cd "freetype-$version"
@ -655,7 +655,7 @@ build_ragel()
cd "$BASEDIR"/src
rm -rf "ragel-$version"
if [ ! -f "ragel-$version.tar.gz" ]; then
curl --insecure -LO "http://www.colm.net/wp-content/uploads/2014/10/ragel-$version.tar.gz"
curl --insecure -LO "http://www.colm.net/files/ragel/ragel-$version.tar.gz"
fi
tar xzf "ragel-$version.tar.gz"
cd "ragel-$version"
@ -770,7 +770,7 @@ fi
echo "Using basedir:" $BASEDIR
mkdir -p $SRCDIR $DEPLOYDIR
build_qt5 5.3.1
build_qt5 5.3.2
build_qscintilla 2.8.4
# NB! For eigen, also update the path in the function
build_eigen 3.2.1
@ -784,7 +784,7 @@ build_gettext 0.18.3.2
build_libffi 3.1
build_glib2 2.40.0
build_opencsg 1.4.0
build_freetype 2.5.3 --without-png
build_freetype 2.5.4 --without-png
build_ragel 6.9
build_harfbuzz 0.9.35 "--with-coretext=auto --with-glib=no"
export FREETYPE_CFLAGS="-I$DEPLOYDIR/include -I$DEPLOYDIR/include/freetype2"

View File

@ -48,6 +48,11 @@ size_t CGAL_Nef_polyhedron::memsize() const
return memsize;
}
bool CGAL_Nef_polyhedron::isEmpty() const
{
return !this->p3 || this->p3->is_empty();
}
/*!
Creates a new PolySet and initializes it with the data from this polyhedron

View File

@ -19,7 +19,7 @@ public:
virtual std::string dump() const;
virtual unsigned int getDimension() const { return 3; }
// Empty means it is a geometric node which has zero area/volume
virtual bool isEmpty() const { return !p3; }
virtual bool isEmpty() const;
virtual Geometry *copy() const { return new CGAL_Nef_polyhedron(*this); }
void reset() { p3.reset(); }

View File

@ -12,13 +12,8 @@
class CsgInfo
{
public:
CsgInfo()
CsgInfo() : glview(NULL), root_chain(NULL), highlights_chain(NULL), background_chain(NULL), progress_function(NULL)
{
root_chain = NULL;
highlights_chain = NULL;
background_chain = NULL;
glview = NULL;
progress_function = NULL;
normalizelimit = RenderSettings::inst()->openCSGTermLimit;
}
OffscreenView *glview;
@ -43,12 +38,6 @@ public:
CSGTermEvaluator evaluator(tree, &geomevaluator);
boost::shared_ptr<CSGTerm> root_raw_term = evaluator.evaluateCSGTerm( *root_node, this->highlight_terms, this->background_terms );
if (!root_raw_term && this->background_terms.empty()) {
PRINT("Error: CSG generation failed! (no objects found)");
call_progress_function();
return false;
}
PRINT("Compiling design (CSG Products normalization)...");
call_progress_function();
CSGTermNormalizer normalizer( normalizelimit );

View File

@ -63,10 +63,12 @@ shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const AbstractNod
PolySet *ps = new PolySet(3);
ps->setConvexity(N->getConvexity());
this->root.reset(ps);
bool err = CGALUtils::createPolySetFromNefPolyhedron3(*N->p3, *ps);
if (err) {
PRINT("ERROR: Nef->PolySet failed");
}
if (!N->isEmpty()) {
bool err = CGALUtils::createPolySetFromNefPolyhedron3(*N->p3, *ps);
if (err) {
PRINT("ERROR: Nef->PolySet failed");
}
}
smartCacheInsert(node, this->root);
}
@ -123,8 +125,9 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const Abstr
if (op == OPENSCAD_MINKOWSKI) return ResultObject(CGALUtils::applyMinkowski(children));
CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron;
CGALUtils::applyOperator(children, *N, op);
CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(children, op);
// FIXME: Clarify when we can return NULL and what that means
if (!N) N = new CGAL_Nef_polyhedron;
return ResultObject(N);
}
@ -354,6 +357,7 @@ void GeometryEvaluator::addToParent(const State &state,
// Root node, insert into cache
smartCacheInsert(node, geom);
this->root = geom;
assert(this->visitedchildren.empty());
}
}
@ -547,7 +551,12 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node)
node.matrix(1,0), node.matrix(1,1), node.matrix(1,3),
node.matrix(3,0), node.matrix(3,1), node.matrix(3,3);
newpoly->transform(mat2);
geom = newpoly;
// A 2D transformation may flip the winding order of a polygon.
// If that happens with a sanitized polygon, we need to reverse
// the winding order for it to be correct.
if (newpoly->isSanitized() && mat2.matrix().determinant() <= 0) {
geom.reset(ClipperUtils::sanitize(*newpoly));
}
}
else if (geom->getDimension() == 3) {
shared_ptr<const PolySet> ps = dynamic_pointer_cast<const PolySet>(geom);

View File

@ -29,12 +29,20 @@ std::string LibraryInfo::info()
{
std::stringstream s;
#if defined(__x86_64__) || defined(_M_X64)
std::string bits(" 64bit");
#elif defined(__i386) || defined(_M_IX86)
std::string bits(" 32bit");
#else
std::string bits("");
#endif
#if defined(__GNUG__) && !defined(__clang__)
std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) );
std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) + bits);
#elif defined(_MSC_VER)
std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) );
std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) + bits);
#elif defined(__clang__)
std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) );
std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) + bits);
#else
std::string compiler_info( "unknown compiler" );
#endif
@ -80,6 +88,7 @@ std::string LibraryInfo::info()
const char *env_font_path = getenv("OPENSCAD_FONT_PATH");
s << "OpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION)
<< "\nSystem information: " << PlatformUtils::sysinfo()
<< "\nCompiler, build date: " << compiler_info << ", " << __DATE__
<< "\nBoost version: " << BOOST_LIB_VERSION
<< "\nEigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION

View File

@ -543,6 +543,9 @@
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
<property name="menuRole">
<enum>QAction::QuitRole</enum>
</property>
</action>
<action name="editActionUndo">
<property name="text">
@ -955,6 +958,9 @@
<property name="text">
<string>About</string>
</property>
<property name="menuRole">
<enum>QAction::AboutRole</enum>
</property>
</action>
<action name="helpActionManual">
<property name="text">
@ -983,6 +989,9 @@
<property name="text">
<string>Preferences</string>
</property>
<property name="menuRole">
<enum>QAction::PreferencesRole</enum>
</property>
</action>
<action name="editActionFind">
<property name="text">

View File

@ -1,4 +1,8 @@
#include "PlatformUtils.h"
#include <sys/types.h>
#include <sys/sysctl.h>
#include <boost/lexical_cast.hpp>
#import <Foundation/Foundation.h>
std::string PlatformUtils::pathSeparatorChar()
@ -35,5 +39,33 @@ unsigned long PlatformUtils::stackLimit()
return STACK_LIMIT_DEFAULT;
}
std::string PlatformUtils::sysinfo()
{
std::string result;
result += "Mac OS X ";
result += [[[NSProcessInfo processInfo] operatingSystemVersionString] UTF8String];
int mib[2];
int64_t physical_memory;
int32_t numcpu;
size_t length64 = sizeof(int64_t);
size_t length32 = sizeof(int32_t);;
sysctlbyname("hw.memsize", &physical_memory, &length64, NULL, 0);
sysctlbyname("hw.physicalcpu", &numcpu, &length32, NULL, 0);
result += " ";
result += boost::lexical_cast<std::string>(numcpu);
result += " CPU";
if (numcpu > 1) result += "s";
result += " ";
result += PlatformUtils::toMemorySizeString(physical_memory, 2);
result += " RAM";
return result;
}
void PlatformUtils::ensureStdIO(void) {}

View File

@ -1,4 +1,13 @@
#include <string>
#include <fstream>
#include <streambuf>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/utsname.h>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include "PlatformUtils.h"
#include "boosty.h"
@ -60,5 +69,109 @@ unsigned long PlatformUtils::stackLimit()
return STACK_LIMIT_DEFAULT;
}
static std::string readText(const std::string &path)
{
std::ifstream s(path.c_str());
s.seekg(0, std::ios::end);
if (s.fail() || s.tellg() > 4096) {
return "";
}
s.seekg(0, std::ios::beg);
std::string text((std::istreambuf_iterator<char>(s)), std::istreambuf_iterator<char>());
return text;
}
/**
* Check /etc/os-release as defined by systemd.
* @see http://0pointer.de/blog/projects/os-release.html
* @see http://www.freedesktop.org/software/systemd/man/os-release.html
* @return the PRETTY_NAME from the os-release file or an empty string.
*/
static std::string checkOsRelease()
{
std::string os_release(readText("/etc/os-release"));
boost::smatch results;
boost::regex pretty_name("^PRETTY_NAME=\"([^\"]+)\"");
if (boost::regex_search(os_release, results, pretty_name)) {
return results[1];
}
return "";
}
static std::string checkEtcIssue()
{
std::string issue(readText("/etc/issue"));
boost::regex nl("\n.*$");
issue = boost::regex_replace(issue, nl, "");
boost::regex esc("\\\\.");
issue = boost::regex_replace(issue, esc, "");
boost::algorithm::trim(issue);
return issue;
}
static std::string detectDistribution()
{
std::string osrelease = checkOsRelease();
if (!osrelease.empty()) {
return osrelease;
}
std::string etcissue = checkEtcIssue();
if (!etcissue.empty()) {
return etcissue;
}
return "";
}
std::string PlatformUtils::sysinfo()
{
std::string result;
struct utsname osinfo;
if (uname(&osinfo) == 0) {
result += osinfo.sysname;
result += " ";
result += osinfo.release;
result += " ";
result += osinfo.version;
result += " ";
result += osinfo.machine;
} else {
result += "Unknown Linux";
}
long numcpu = sysconf(_SC_NPROCESSORS_ONLN);
if (numcpu > 0) {
result += " ";
result += boost::lexical_cast<std::string>(numcpu);
result += " CPU";
if (numcpu > 1) {
result += "s";
}
}
long pages = sysconf(_SC_PHYS_PAGES);
long pagesize = sysconf(_SC_PAGE_SIZE);
if ((pages > 0) && (pagesize > 0)) {
result += " ";
result += PlatformUtils::toMemorySizeString(pages * pagesize, 2);
result += " RAM";
}
std::string distribution = detectDistribution();
if (!distribution.empty()) {
result += " ";
result += distribution;
}
return result;
}
void PlatformUtils::ensureStdIO(void) {}

View File

@ -98,6 +98,96 @@ unsigned long PlatformUtils::stackLimit()
return STACK_LIMIT_DEFAULT;
}
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
static BOOL IsWow64()
{
BOOL bIsWow64 = FALSE;
//IsWow64Process is not available on all supported versions of Windows.
//Use GetModuleHandle to get a handle to the DLL that contains the function
//and GetProcAddress to get a pointer to the function if available.
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
if (NULL != fnIsWow64Process) {
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
{
return false;
}
}
return bIsWow64;
}
std::string PlatformUtils::sysinfo()
{
std::string result;
OSVERSIONINFOEX osinfo;
osinfo.dwOSVersionInfoSize = sizeof(osinfo);
if (GetVersionEx((OSVERSIONINFO*)&osinfo) == 0) {
result += "Unknown Windows";
} else {
unsigned int version = osinfo.dwMajorVersion * 1000 + osinfo.dwMinorVersion;
if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
switch (version) {
case 5000:
result += "Windows 2000";
break;
case 5001:
result += "Windows XP";
break;
case 5002:
result += "Windows Server 2003";
break;
case 6000:
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows Server 2008");
break;
case 6001:
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows Server 2008 R2");
break;
case 6002:
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows Server 2012");
break;
case 6003:
// For applications that have been manifested for Windows 8.1.
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows Server 2012 R2");
break;
}
boost::format fmt(" (v%d.%d)");
fmt % osinfo.dwMajorVersion % osinfo.dwMinorVersion;
result += fmt.str();
} else {
boost::format fmt("Unknown Windows (dwPlatformId = %d, dwMajorVersion = %d, dwMinorVersion = %d");
fmt % osinfo.dwPlatformId % osinfo.dwMajorVersion % osinfo.dwMinorVersion;
result += fmt.str();
}
}
SYSTEM_INFO systeminfo;
bool isWow64 = IsWow64();
if (isWow64) {
GetNativeSystemInfo(&systeminfo);
} else {
GetSystemInfo(&systeminfo);
}
int numcpu = systeminfo.dwNumberOfProcessors;
boost::format fmt(" %d CPU%s%s");
fmt % numcpu % (numcpu > 1 ? "s" : "") % (isWow64 ? " WOW64" : "");
result += fmt.str();
MEMORYSTATUSEX memoryinfo;
memoryinfo.dwLength = sizeof(memoryinfo);
if (GlobalMemoryStatusEx(&memoryinfo) != 0) {
result += " ";
result += PlatformUtils::toMemorySizeString(memoryinfo.ullTotalPhys, 2);
result += " RAM";
}
return result;
}
#include <io.h>
#include <stdio.h>
#include <fstream>

View File

@ -1,7 +1,14 @@
#include <stdlib.h>
#include <iomanip>
#include "PlatformUtils.h"
#ifdef INSTALL_SUFFIX
#define RESOURCE_FOLDER(path) path INSTALL_SUFFIX
#else
#define RESOURCE_FOLDER(path) path
#endif
extern std::vector<std::string> librarypath;
extern std::vector<std::string> fontpath;
@ -28,8 +35,8 @@ static std::string lookupResourcesPath()
};
#else
const char *searchpath[] = {
"../share/openscad",
"../../share/openscad",
RESOURCE_FOLDER("../share/openscad"),
RESOURCE_FOLDER("../../share/openscad"),
".",
"..",
"../..",
@ -184,3 +191,25 @@ int PlatformUtils::setenv(const char *name, const char *value, int overwrite)
return ::setenv(name, value, overwrite);
#endif
}
std::string PlatformUtils::toMemorySizeString(unsigned long bytes, int digits)
{
static const char *units[] = { "B", "kB", "MB", "GB", "TB", NULL };
int idx = 0;
double val = bytes;
while (true) {
if (val < 1024.0) {
break;
}
if (units[idx + 1] == NULL) {
break;
}
idx++;
val /= 1024.0;
}
boost::format fmt("%f %s");
fmt % boost::io::group(std::setprecision(digits), val) % units[idx];
return fmt.str();
}

View File

@ -34,6 +34,20 @@ namespace PlatformUtils {
std::string backupPath();
bool createBackupPath();
/**
* Return a human readable text describing the operating system
* the application is currently running on. This is mainly intended
* to provide information for bug reports (e.g. to be included in
* the LibraryInfoDialog).
*
* If there is some error to retrieve the details, at least the
* OS type is reported based on what platform the application was
* built for.
*
* @return system information.
*/
std::string sysinfo();
/**
* Platform abstraction to set environment variables. Windows/MinGW
* does not support setenv(), but needs _putenv().
@ -65,4 +79,10 @@ namespace PlatformUtils {
* Currently limited to MS Windows GUI application console only.
*/
void ensureStdIO(void);
/**
* Convert the number of bytes to a human readable string with
* a given number of digits.
*/
std::string toMemorySizeString(unsigned long bytes, int digits);
}

View File

@ -11,8 +11,10 @@
We can store sanitized vs. unsanitized polygons. Sanitized polygons
will have opposite winding order for holes and is guaranteed to not
have intersecting geometry. Sanitization is typically done by ClipperUtils, but
if you create geometry which you know is sanitized, the flag can be set manually.
have intersecting geometry. The winding order will be counter-clockwise
for positive outlines and clockwise for holes. Sanitization is typically
done by ClipperUtils, but if you create geometry which you know is sanitized,
the flag can be set manually.
*/
size_t Polygon2d::memsize() const

View File

@ -273,7 +273,11 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps)
if (ps.isEmpty()) return new CGAL_Nef_polyhedron();
assert(ps.getDimension() == 3);
if (ps.is_convex()) {
// Since is_convex doesn't work well with non-planar faces,
// we tessellate the polyset before checking.
PolySet ps_tri(3);
PolysetUtils::tessellate_faces(ps, ps_tri);
if (ps_tri.is_convex()) {
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
// Collect point cloud
std::set<K::Point_3> points;
@ -316,10 +320,8 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps)
}
}
if (plane_error) try {
PolySet ps2(3);
CGAL_Polyhedron P;
PolysetUtils::tessellate_faces(ps, ps2);
bool err = CGALUtils::createPolyhedronFromPolySet(ps2,P);
bool err = CGALUtils::createPolyhedronFromPolySet(ps_tri, P);
if (!err) N = new CGAL_Nef_polyhedron3(P);
}
catch (const CGAL::Assertion_exception &e) {
@ -603,14 +605,13 @@ namespace CGALUtils {
fake_children.push_back(std::make_pair((const AbstractNode*)NULL,
shared_ptr<const Geometry>(createNefPolyhedronFromGeometry(ps))));
}
CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron;
CGALUtils::applyOperator(fake_children, *N, OPENSCAD_UNION);
CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(fake_children, OPENSCAD_UNION);
t.stop();
PRINTDB("Minkowski: Union done: %f s",t.time());
t.reset();
operands[0] = N;
} else {
return NULL;
operands[0] = new CGAL_Nef_polyhedron();
}
}
@ -623,17 +624,16 @@ namespace CGALUtils {
// If anything throws we simply fall back to Nef Minkowski
PRINTD("Minkowski: Falling back to Nef Minkowski");
CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron;
applyOperator(children, *N, OPENSCAD_MINKOWSKI);
CGAL_Nef_polyhedron *N = applyOperator(children, OPENSCAD_MINKOWSKI);
return N;
}
}
/*!
Applies op to all children and stores the result in dest.
Applies op to all children and returns the result.
The child list should be guaranteed to contain non-NULL 3D or empty Geometry objects
*/
void applyOperator(const Geometry::ChildList &children, CGAL_Nef_polyhedron &dest, OpenSCADOperator op)
CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op)
{
// Speeds up n-ary union operations significantly
CGAL::Nef_nary_union_3<CGAL_Nef_polyhedron3> nary_union;
@ -720,13 +720,15 @@ namespace CGALUtils {
}
CGAL::set_error_behaviour(old_behaviour);
}
if (N) dest = *N;
return N;
}
/*!
Modifies target by applying op to target and src:
target = target [op] src
*/
//FIXME: Old, can be removed:
#if 0
void applyBinaryOperator(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op)
{
if (target.getDimension() != 2 && target.getDimension() != 3) {
@ -772,6 +774,7 @@ namespace CGALUtils {
}
CGAL::set_error_behaviour(old_behaviour);
}
#endif
static void add_outline_to_poly(CGAL_Nef_polyhedron2::Explorer &explorer,
CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator circ,
@ -932,6 +935,13 @@ namespace CGALUtils {
};
/*!
Check if all faces of a polyset is within 0.1 degree of being convex.
NB! This function can give false positives if the polyset contains
non-planar faces. To be on the safe side, consider passing a tessellated polyset.
See issue #1061.
*/
bool is_approximately_convex(const PolySet &ps) {
const double angle_threshold = cos(.1/180*M_PI); // .1°

View File

@ -13,8 +13,9 @@ typedef std::vector<PolygonK> PolyholeK;
namespace CGALUtils {
bool applyHull(const Geometry::ChildList &children, PolySet &P);
void applyOperator(const Geometry::ChildList &children, CGAL_Nef_polyhedron &dest, OpenSCADOperator op);
void applyBinaryOperator(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op);
CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op);
//FIXME: Old, can be removed:
//void applyBinaryOperator(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op);
Polygon2d *project(const CGAL_Nef_polyhedron &N, bool cut);
CGAL_Iso_cuboid_3 boundingBox(const CGAL_Nef_polyhedron3 &N);
bool is_approximately_convex(const PolySet &ps);

View File

@ -53,10 +53,7 @@ void export_png_preview_common(Tree &tree, Camera &cam, std::ostream &output, Pr
{
PRINTD("export_png_preview_common");
CsgInfo csgInfo = CsgInfo();
if (!csgInfo.compile_chains(tree)) {
fprintf(stderr,"Couldn't initialize CSG chains\n");
return;
}
csgInfo.compile_chains(tree);
try {
csgInfo.glview = new OffscreenView(cam.pixel_width, cam.pixel_height);

View File

@ -36,6 +36,7 @@
#include "stl-utils.h"
#include "printutils.h"
#include "stackcheck.h"
#include "exceptions.h"
#include <boost/foreach.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
@ -150,9 +151,12 @@ ValuePtr FunctionTailRecursion::evaluate(const Context *ctx, const EvalContext *
EvalContext ec(&c, call->call_arguments);
Context tmp(&c);
unsigned int counter = 0;
while (invert ^ expr->first->evaluate(&c)) {
tmp.setVariables(definition_arguments, &ec);
c.apply_variables(tmp);
if (counter++ == 1000000) throw RecursionException("function", this->name);
}
ValuePtr result = endexpr->evaluate(&c);

View File

@ -1051,9 +1051,6 @@ void MainWindow::compileCSG(bool procevents)
CSGTermEvaluator csgrenderer(this->tree, &geomevaluator);
if (procevents) QApplication::processEvents();
this->root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms);
if (!root_raw_term && background_terms.empty()) {
PRINT("ERROR: CSG generation failed! (no objects found)");
}
GeometryCache::instance()->print();
#ifdef ENABLE_CGAL
CGALCache::instance()->print();
@ -1768,8 +1765,8 @@ void MainWindow::actionRenderDone(shared_ptr<const Geometry> root_geom)
int s = this->progresswidget->elapsedTime() / 1000;
PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60));
if (const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron *>(root_geom.get())) {
if (!N->isEmpty()) {
if (root_geom && !root_geom->isEmpty()) {
if (const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron *>(root_geom.get())) {
if (N->getDimension() == 3) {
PRINT(" Top level object is a 3D object:");
PRINTB(" Simple: %6s", (N->p3->is_simple() ? "yes" : "no"));
@ -1781,16 +1778,16 @@ void MainWindow::actionRenderDone(shared_ptr<const Geometry> root_geom)
PRINTB(" Volumes: %6d", N->p3->number_of_volumes());
}
}
}
else if (const PolySet *ps = dynamic_cast<const PolySet *>(root_geom.get())) {
assert(ps->getDimension() == 3);
PRINT(" Top level object is a 3D object:");
PRINTB(" Facets: %6d", ps->numPolygons());
} else if (const Polygon2d *poly = dynamic_cast<const Polygon2d *>(root_geom.get())) {
PRINT(" Top level object is a 2D object:");
PRINTB(" Contours: %6d", poly->outlines().size());
} else {
assert(false && "Unknown geometry type");
else if (const PolySet *ps = dynamic_cast<const PolySet *>(root_geom.get())) {
assert(ps->getDimension() == 3);
PRINT(" Top level object is a 3D object:");
PRINTB(" Facets: %6d", ps->numPolygons());
} else if (const Polygon2d *poly = dynamic_cast<const Polygon2d *>(root_geom.get())) {
PRINT(" Top level object is a 2D object:");
PRINTB(" Contours: %6d", poly->outlines().size());
} else {
assert(false && "Unknown geometry type");
}
}
PRINT("Rendering finished.");

View File

@ -626,14 +626,20 @@ int gui(vector<string> &inputFiles, const fs::path &original_path, int argc, cha
updater->init();
#endif
QGLFormat fmt;
#if 0 /*** disabled by clifford wolf: adds rendering artefacts with OpenCSG ***/
// turn on anti-aliasing
QGLFormat f;
f.setSampleBuffers(true);
f.setSamples(4);
QGLFormat::setDefaultFormat(f);
fmt.setSampleBuffers(true);
fmt.setSamples(4);
#endif
// The default SwapInterval causes very bad interactive behavior as
// waiting for the buffer swap seems to block mouse events. So the
// effect is that we can process mouse events at the frequency of
// the screen retrace interval causing them to queue up.
// (see https://bugreports.qt-project.org/browse/QTBUG-39370
fmt.setSwapInterval(0);
QGLFormat::setDefaultFormat(fmt);
set_render_color_scheme(arg_colorscheme, false);
bool noInputFiles = false;

View File

@ -2,7 +2,9 @@
#include "polyset.h"
#include "Polygon2d.h"
#include "printutils.h"
#ifdef ENABLE_CGAL
#include "cgalutils.h"
#endif
#include <boost/foreach.hpp>
@ -45,6 +47,7 @@ namespace PolysetUtils {
The tessellation will be robust wrt. degenerate and self-intersecting
*/
void tessellate_faces(const PolySet &inps, PolySet &outps) {
#ifdef ENABLE_CGAL
int degeneratePolygons = 0;
for (size_t i = 0; i < inps.polygons.size(); i++) {
const Polygon pgon = inps.polygons[i];
@ -76,5 +79,17 @@ namespace PolysetUtils {
}
}
if (degeneratePolygons > 0) PRINT("WARNING: PolySet has degenerate polygons");
#else
assert(false);
#endif
}
bool is_approximately_convex(const PolySet &ps) {
#ifdef ENABLE_CGAL
return CGALUtils::is_approximately_convex(ps);
#else
return false;
#endif
}
}

View File

@ -7,5 +7,6 @@ namespace PolysetUtils {
Polygon2d *project(const PolySet &ps);
void tessellate_faces(const PolySet &inps, PolySet &outps);
bool is_approximately_convex(const PolySet &ps);
};

View File

@ -25,6 +25,7 @@
*/
#include "polyset.h"
#include "polyset-utils.h"
#include "linalg.h"
#include "printutils.h"
#include <Eigen/LU>
@ -140,20 +141,10 @@ void PolySet::transform(const Transform3d &mat)
}
}
namespace CGALUtils {
extern bool is_approximately_convex(const PolySet &ps);
}
bool PolySet::is_convex() const {
if (convex) return true;
if (convex || this->isEmpty()) return true;
if (!convex) return false;
#ifdef ENABLE_CGAL
convex = CGALUtils::is_approximately_convex(*this);
return convex;
#else
return false;
#endif
return PolysetUtils::is_approximately_convex(*this);
}
void PolySet::resize(Vector3d newsize, const Eigen::Matrix<bool,3,1> &autosize)

View File

@ -2,12 +2,16 @@
#include <sstream>
#include <stdio.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/circular_buffer.hpp>
std::list<std::string> print_messages_stack;
OutputHandlerFunc *outputhandler = NULL;
void *outputhandler_data = NULL;
std::string OpenSCAD::debug("");
boost::circular_buffer<std::string> lastmessages(5);
void set_output_handler(OutputHandlerFunc *newhandler, void *userdata)
{
outputhandler = newhandler;
@ -46,6 +50,16 @@ void PRINT(const std::string &msg)
void PRINT_NOCACHE(const std::string &msg)
{
if (msg.empty()) return;
if (boost::starts_with(msg, "WARNING") || boost::starts_with(msg, "ERROR")) {
int i;
for (i=0;i<lastmessages.size();i++) {
if (lastmessages[i] != msg) break;
}
if (i == 5) return; // Suppress output after 5 equal ERROR or WARNING outputs.
else lastmessages.push_back(msg);
}
if (!outputhandler) {
fprintf(stderr, "%s\n", msg.c_str());
} else {

View File

@ -877,6 +877,11 @@ ValuePtr ValuePtr::operator-() const
return ValuePtr(-**this);
}
ValuePtr ValuePtr::operator!() const
{
return ValuePtr(!**this);
}
ValuePtr ValuePtr::operator[](const ValuePtr &v) const
{
return ValuePtr((**this)[*v]);

View File

@ -187,6 +187,7 @@ public:
bool operator>=(const ValuePtr &v) const;
bool operator>(const ValuePtr &v) const;
ValuePtr operator-() const;
ValuePtr operator!() const;
ValuePtr operator[](const ValuePtr &v) const;
ValuePtr operator+(const ValuePtr &v) const;
ValuePtr operator-(const ValuePtr &v) const;

View File

@ -6,5 +6,5 @@ translate([5,0,0]) scale([2,4/3]) obj2D();
translate([10,0,0]) scale(2) obj2D();
// Scale by zero; 2D object
linear_extrude() scale([0,0]) obj2D();
linear_extrude() scale([0,1]) obj2D();
translate([-5,0,0]) linear_extrude() scale([0,0]) obj2D();
translate([-5,0,0]) linear_extrude() scale([0,1]) obj2D();

View File

@ -0,0 +1,4 @@
difference() {
cube(1, center=true);
cube(2, center=true);
}

View File

@ -0,0 +1,4 @@
intersection() {
translate([-2,0,0]) cube(1);
translate([2,0,0]) cube(1);
}

View File

@ -0,0 +1,10 @@
intersection() {
minkowski() {
intersection() {
translate([-2,0,0]) cube(1);
translate([2,0,0]) cube(1);
}
cube();
}
cube();
}

View File

@ -0,0 +1,7 @@
minkowski() {
intersection() {
translate([-2,0,0]) cube(1);
translate([2,0,0]) cube(1);
}
cube();
}

View File

@ -0,0 +1,7 @@
module obj2D() polygon([[-0.5,-0.5], [1,-0.5], [1,1], [-0.5, 0.5]])
square([2,3], center=true);
linear_extrude(1) scale([1, -1]) obj2D();
translate([3,0,0]) linear_extrude(1) scale([-1, -0.5]) obj2D();
translate([0,3,0]) linear_extrude(1) mirror() obj2D();
translate([2,3,0]) linear_extrude(1) mirror([0,1]) obj2D();

View File

@ -15,5 +15,3 @@ multmatrix([[1,0.4,0.1,-25],
[0.4,0.8,0,-25],
[0.2,0.2,0.5,0],
[0,0,0,1]]) mycyl();
//FIXME: mirror() and scale()

1
testdata/scad/bugs/issue1061.scad vendored Normal file
View File

@ -0,0 +1 @@
polyhedron(points = [[-5, -5, 0], [-5, 5, 0], [5, 5, 0], [5, -5, 0], [-1.87866, -4.21311, 3], [-4.21311, 5.51058, 3], [5.51058, 7.84504, 3], [7.84504, -1.87866, 3], [1.05099, -3.48892, 6], [-3.48892, 5.42115, 6], [5.42115, 9.96105, 6], [9.96105, 1.05099, 6], [3.39596, -3.09852, 9], [-3.09852, 4.50554, 9], [4.50554, 11, 9], [11, 3.39596, 9], [4.91038, -3.17979, 12], [-3.17979, 2.69807, 12], [2.69807, 10.7882, 12], [10.7882, 4.91038, 12], [5.53441, -3.70439, 15], [-3.70439, 0.122447, 15], [0.122447, 9.36124, 15], [9.36124, 5.53441, 15], [5.39234, -4.48455, 18], [-4.48455, -2.9202, 18], [-2.9202, 6.95668, 18], [6.95668, 5.39234, 18]], faces = [[0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [4, 5, 9, 8], [5, 6, 10, 9], [6, 7, 11, 10], [7, 4, 8, 11], [8, 9, 13, 12], [9, 10, 14, 13], [10, 11, 15, 14], [11, 8, 12, 15], [12, 13, 17, 16], [13, 14, 18, 17], [14, 15, 19, 18], [15, 12, 16, 19], [16, 17, 21, 20], [17, 18, 22, 21], [18, 19, 23, 22], [19, 16, 20, 23], [20, 21, 25, 24], [21, 22, 26, 25], [22, 23, 27, 26], [23, 20, 24, 27], [3, 2, 1, 0], [24, 25, 26, 27]]);

View File

@ -0,0 +1,41 @@
values = [
undef, // special undefined value
1/0, // infinity
-1/0, // -infinity
0/0, // not a number
0, -4.2, -2, 3, 42.42, 242, // number
true, false, // boolean
"", "text", // string
[], [ 0 ], [ 1 ], // vector
[ 0 : 0 ], [ 1 : 2 ] // range
];
array = [ "a", "b", "c", "d" ];
for (v = values) {
echo(v = v, op = "not v", result = !v);
echo(v = v, op = "-v", result = -v);
echo(v = v, op = "v *", result = v * 3);
echo(v = v, op = "* v", result = 2 * v);
echo(v = v, op = "v /", result = v / 3);
echo(v = v, op = "/ v", result = 2 / v);
echo(v = v, op = "v %", result = v % 3);
echo(v = v, op = "% v", result = 2 % v);
echo(v = v, op = "v +", result = v + 3);
echo(v = v, op = "+ v", result = 2 + v);
echo(v = v, op = "v -", result = v - 3);
echo(v = v, op = "- v", result = 2 - v);
echo(v = v, op = "v and true", result = v && true);
echo(v = v, op = "v and false", result = v && false);
echo(v = v, op = "v or true", result = v || true);
echo(v = v, op = "v or false", result = v || false);
// echo(v = v, op = "<", result = v < 3);
// echo(v = v, op = "<=", result = v <= 3);
// echo(v = v, op = "==", result = v == 3);
// echo(v = v, op = "!=", result = v != 3);
// echo(v = v, op = ">=", result = v >= 3);
// echo(v = v, op = ">", result = v > 3);
echo(v = v, op = "[v]", result = array[v]);
echo(v = v, op = "v[0]", result = v[0]);
echo(v = v, op = "v[4]", result = v[4]);
}

View File

@ -0,0 +1,16 @@
polyhedron(points=[
[0,0,0],
[10,0,0],
[10,10,0],
[0,10,0],
[0,-20,20],
[10,-20,20],
[10,-20,30],
[0,-20,30]
],
faces = [[0,1,2,3],[4,5,6,7],
[1,2,5,4],
[2,3,6,5],
[3,0,6,5],
[0,1,4,7]
]);

View File

@ -632,7 +632,6 @@ set(CORE_SOURCES
../src/csgtermnormalizer.cc
../src/Geometry.cc
../src/Polygon2d.cc
../src/polyset.cc
../src/csgops.cc
../src/transform.cc
../src/color.cc
@ -666,7 +665,10 @@ set(NOCGAL_SOURCES
../src/builtin.cc
../src/import.cc
../src/export.cc
../src/LibraryInfo.cc)
../src/LibraryInfo.cc
../src/polyset.cc
../src/polyset-utils.cc)
set(CGAL_SOURCES
${NOCGAL_SOURCES}
@ -678,7 +680,6 @@ set(CGAL_SOURCES
../src/CGALCache.cc
../src/CGAL_Nef_polyhedron_DxfData.cc
../src/Polygon2d-CGAL.cc
../src/polyset-utils.cc
../src/svg.cc
../src/GeometryEvaluator.cc)
@ -749,20 +750,20 @@ set_target_properties(tests-offscreen PROPERTIES COMPILE_FLAGS "${ENABLE_OPENCSG
# modulecachetest
#
add_executable(modulecachetest modulecachetest.cc)
target_link_libraries(modulecachetest tests-nocgal)
target_link_libraries(modulecachetest tests-nocgal ${GLEW_LIBRARY} ${OPENCSG_LIBRARY} ${APP_SERVICES_LIBRARY})
#
# csgtexttest
#
add_executable(csgtexttest csgtexttest.cc CSGTextRenderer.cc CSGTextCache.cc)
target_link_libraries(csgtexttest tests-nocgal)
target_link_libraries(csgtexttest tests-nocgal ${GLEW_LIBRARY} ${OPENCSG_LIBRARY} ${APP_SERVICES_LIBRARY})
#
# cgalcachetest
#
add_executable(cgalcachetest cgalcachetest.cc)
set_target_properties(cgalcachetest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")
target_link_libraries(cgalcachetest tests-cgal)
target_link_libraries(cgalcachetest tests-cgal ${GLEW_LIBRARY} ${OPENCSG_LIBRARY} ${APP_SERVICES_LIBRARY})
#
# openscad no-qt
@ -1025,6 +1026,7 @@ list(APPEND EXAMPLE_FILES ${EXAMPLE_3D_FILES} ${EXAMPLE_2D_FILES})
list(APPEND ECHO_FILES ${FUNCTION_FILES}
${CMAKE_SOURCE_DIR}/../testdata/scad/3D/features/for-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/expression-evaluation-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/echo-tests.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/escape-test.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/parser-tests.scad
@ -1114,6 +1116,9 @@ list(APPEND EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/3D/features
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-wing.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad)
list(APPEND EXPORTCSG_TEST_FILES
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/nonmanifold-polyhedron.scad)
disable_tests(
# These don't output anything
dxfpngtest_text-empty-tests
@ -1123,6 +1128,7 @@ disable_tests(
# Not useful
throwntogethertest_internal-cavity
throwntogethertest_internal-cavity-polyhedron
throwntogethertest_nullspace-difference
# these take too long, for little relative gain in testing
stlpngtest_iteration
@ -1211,9 +1217,16 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1004.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad)
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad)
list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES})
list(REMOVE_ITEM EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad)
list(REMOVE_ITEM EXPORT3D_TEST_FILES
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad)
list(APPEND EXPORTCSG_TEST_FILES
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad)
list(APPEND ALL_2D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad)
list(APPEND OPENCSGTEST_FILES ${BUGS_FILES})
@ -1231,6 +1244,8 @@ foreach(FILE ${BUGS_FILES})
set_test_config(Bugs ${TEST_FULLNAME})
get_test_fullname(stlpngtest ${FILE} TEST_FULLNAME)
set_test_config(Bugs ${TEST_FULLNAME})
get_test_fullname(stlcsgpngtest ${FILE} TEST_FULLNAME)
set_test_config(Bugs ${TEST_FULLNAME})
endforeach()
# Examples
@ -1309,6 +1324,7 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake ${TMP})
# o stlpngtest: Export to STL, Re-import and render to PNG (--render=cgal)
# o offpngtest: Export to OFF, Re-import and render to PNG (--render=cgal)
# o dxfpngtest: Export to DXF, Re-import and render to PNG (--render=cgal)
# o stlcsgpngtest: Export to STL, Re-import and render to PNG (--render)
#
add_cmdline_test(moduledumptest EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX ast FILES
@ -1352,6 +1368,7 @@ add_cmdline_test(monotonepngtest EXE ${OPENSCAD_BINPATH} ARGS --colorscheme=Mono
add_cmdline_test(stlpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES})
add_cmdline_test(offpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=OFF --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES})
add_cmdline_test(dxfpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=DXF --render=cgal EXPECTEDDIR cgalpngtest SUFFIX png FILES ${FILES_2D})
add_cmdline_test(stlcsgpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORTCSG_TEST_FILES})
#

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -0,0 +1,6 @@
group() {
difference() {
cube(size = [1, 1, 1], center = true);
cube(size = [2, 2, 2], center = true);
}
}

View File

@ -0,0 +1,10 @@
group() {
intersection() {
multmatrix([[1, 0, 0, -2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cube(size = [1, 1, 1], center = false);
}
multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cube(size = [1, 1, 1], center = false);
}
}
}

View File

@ -0,0 +1,13 @@
group() {
minkowski(convexity = 0) {
intersection() {
multmatrix([[1, 0, 0, -2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cube(size = [1, 1, 1], center = false);
}
multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cube(size = [1, 1, 1], center = false);
}
}
cube(size = [1, 1, 1], center = false);
}
}

View File

@ -0,0 +1,16 @@
group() {
intersection() {
minkowski(convexity = 0) {
intersection() {
multmatrix([[1, 0, 0, -2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cube(size = [1, 1, 1], center = false);
}
multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
cube(size = [1, 1, 1], center = false);
}
}
cube(size = [1, 1, 1], center = false);
}
cube(size = [1, 1, 1], center = false);
}
}

View File

@ -0,0 +1,36 @@
group() {
linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1);
}
}
}
multmatrix([[1, 0, 0, 3], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[-1, 0, 0, 0], [0, -0.5, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1);
}
}
}
}
multmatrix([[1, 0, 0, 0], [0, 1, 0, 3], [0, 0, 1, 0], [0, 0, 0, 1]]) {
linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1);
}
}
}
}
multmatrix([[1, 0, 0, 2], [0, 1, 0, 3], [0, 0, 1, 0], [0, 0, 0, 1]]) {
linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1);
}
}
}
}
}

View File

@ -18,17 +18,21 @@ group() {
}
}
}
linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
square(size = [2, 3], center = true);
multmatrix([[1, 0, 0, -5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
square(size = [2, 3], center = true);
}
}
}
}
linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
square(size = [2, 3], center = true);
multmatrix([[1, 0, 0, -5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {
multmatrix([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
square(size = [2, 3], center = true);
}
}
}
}

View File

@ -8,9 +8,6 @@ WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf".
ECHO: ordinateX = -49.17542445724
WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf".
ECHO: ordinateY = 30.86974532565
WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf".
ECHO: radius = 60
WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf".
ECHO: diameter = 120
WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf".
ECHO: arc = 59.03624346792

View File

@ -0,0 +1,361 @@
ECHO: v = undef, op = "not v", result = true
ECHO: v = undef, op = "-v", result = undef
ECHO: v = undef, op = "v *", result = undef
ECHO: v = undef, op = "* v", result = undef
ECHO: v = undef, op = "v /", result = undef
ECHO: v = undef, op = "/ v", result = undef
ECHO: v = undef, op = "v %", result = undef
ECHO: v = undef, op = "% v", result = undef
ECHO: v = undef, op = "v +", result = undef
ECHO: v = undef, op = "+ v", result = undef
ECHO: v = undef, op = "v -", result = undef
ECHO: v = undef, op = "- v", result = undef
ECHO: v = undef, op = "v and true", result = false
ECHO: v = undef, op = "v and false", result = false
ECHO: v = undef, op = "v or true", result = true
ECHO: v = undef, op = "v or false", result = false
ECHO: v = undef, op = "[v]", result = undef
ECHO: v = undef, op = "v[0]", result = undef
ECHO: v = undef, op = "v[4]", result = undef
ECHO: v = inf, op = "not v", result = false
ECHO: v = inf, op = "-v", result = -inf
ECHO: v = inf, op = "v *", result = inf
ECHO: v = inf, op = "* v", result = inf
ECHO: v = inf, op = "v /", result = inf
ECHO: v = inf, op = "/ v", result = 0
ECHO: v = inf, op = "v %", result = nan
ECHO: v = inf, op = "% v", result = 2
ECHO: v = inf, op = "v +", result = inf
ECHO: v = inf, op = "+ v", result = inf
ECHO: v = inf, op = "v -", result = inf
ECHO: v = inf, op = "- v", result = -inf
ECHO: v = inf, op = "v and true", result = true
ECHO: v = inf, op = "v and false", result = false
ECHO: v = inf, op = "v or true", result = true
ECHO: v = inf, op = "v or false", result = true
ECHO: v = inf, op = "[v]", result = undef
ECHO: v = inf, op = "v[0]", result = undef
ECHO: v = inf, op = "v[4]", result = undef
ECHO: v = -inf, op = "not v", result = false
ECHO: v = -inf, op = "-v", result = inf
ECHO: v = -inf, op = "v *", result = -inf
ECHO: v = -inf, op = "* v", result = -inf
ECHO: v = -inf, op = "v /", result = -inf
ECHO: v = -inf, op = "/ v", result = 0
ECHO: v = -inf, op = "v %", result = nan
ECHO: v = -inf, op = "% v", result = 2
ECHO: v = -inf, op = "v +", result = -inf
ECHO: v = -inf, op = "+ v", result = -inf
ECHO: v = -inf, op = "v -", result = -inf
ECHO: v = -inf, op = "- v", result = inf
ECHO: v = -inf, op = "v and true", result = true
ECHO: v = -inf, op = "v and false", result = false
ECHO: v = -inf, op = "v or true", result = true
ECHO: v = -inf, op = "v or false", result = true
ECHO: v = -inf, op = "[v]", result = undef
ECHO: v = -inf, op = "v[0]", result = undef
ECHO: v = -inf, op = "v[4]", result = undef
ECHO: v = nan, op = "not v", result = false
ECHO: v = nan, op = "-v", result = nan
ECHO: v = nan, op = "v *", result = nan
ECHO: v = nan, op = "* v", result = nan
ECHO: v = nan, op = "v /", result = nan
ECHO: v = nan, op = "/ v", result = nan
ECHO: v = nan, op = "v %", result = nan
ECHO: v = nan, op = "% v", result = nan
ECHO: v = nan, op = "v +", result = nan
ECHO: v = nan, op = "+ v", result = nan
ECHO: v = nan, op = "v -", result = nan
ECHO: v = nan, op = "- v", result = nan
ECHO: v = nan, op = "v and true", result = true
ECHO: v = nan, op = "v and false", result = false
ECHO: v = nan, op = "v or true", result = true
ECHO: v = nan, op = "v or false", result = true
ECHO: v = nan, op = "[v]", result = undef
ECHO: v = nan, op = "v[0]", result = undef
ECHO: v = nan, op = "v[4]", result = undef
ECHO: v = 0, op = "not v", result = true
ECHO: v = 0, op = "-v", result = 0
ECHO: v = 0, op = "v *", result = 0
ECHO: v = 0, op = "* v", result = 0
ECHO: v = 0, op = "v /", result = 0
ECHO: v = 0, op = "/ v", result = inf
ECHO: v = 0, op = "v %", result = 0
ECHO: v = 0, op = "% v", result = nan
ECHO: v = 0, op = "v +", result = 3
ECHO: v = 0, op = "+ v", result = 2
ECHO: v = 0, op = "v -", result = -3
ECHO: v = 0, op = "- v", result = 2
ECHO: v = 0, op = "v and true", result = false
ECHO: v = 0, op = "v and false", result = false
ECHO: v = 0, op = "v or true", result = true
ECHO: v = 0, op = "v or false", result = false
ECHO: v = 0, op = "[v]", result = "a"
ECHO: v = 0, op = "v[0]", result = undef
ECHO: v = 0, op = "v[4]", result = undef
ECHO: v = -4.2, op = "not v", result = false
ECHO: v = -4.2, op = "-v", result = 4.2
ECHO: v = -4.2, op = "v *", result = -12.6
ECHO: v = -4.2, op = "* v", result = -8.4
ECHO: v = -4.2, op = "v /", result = -1.4
ECHO: v = -4.2, op = "/ v", result = -0.47619047619
ECHO: v = -4.2, op = "v %", result = -1.2
ECHO: v = -4.2, op = "% v", result = 2
ECHO: v = -4.2, op = "v +", result = -1.2
ECHO: v = -4.2, op = "+ v", result = -2.2
ECHO: v = -4.2, op = "v -", result = -7.2
ECHO: v = -4.2, op = "- v", result = 6.2
ECHO: v = -4.2, op = "v and true", result = true
ECHO: v = -4.2, op = "v and false", result = false
ECHO: v = -4.2, op = "v or true", result = true
ECHO: v = -4.2, op = "v or false", result = true
ECHO: v = -4.2, op = "[v]", result = undef
ECHO: v = -4.2, op = "v[0]", result = undef
ECHO: v = -4.2, op = "v[4]", result = undef
ECHO: v = -2, op = "not v", result = false
ECHO: v = -2, op = "-v", result = 2
ECHO: v = -2, op = "v *", result = -6
ECHO: v = -2, op = "* v", result = -4
ECHO: v = -2, op = "v /", result = -0.66666666666
ECHO: v = -2, op = "/ v", result = -1
ECHO: v = -2, op = "v %", result = -2
ECHO: v = -2, op = "% v", result = 0
ECHO: v = -2, op = "v +", result = 1
ECHO: v = -2, op = "+ v", result = 0
ECHO: v = -2, op = "v -", result = -5
ECHO: v = -2, op = "- v", result = 4
ECHO: v = -2, op = "v and true", result = true
ECHO: v = -2, op = "v and false", result = false
ECHO: v = -2, op = "v or true", result = true
ECHO: v = -2, op = "v or false", result = true
ECHO: v = -2, op = "[v]", result = undef
ECHO: v = -2, op = "v[0]", result = undef
ECHO: v = -2, op = "v[4]", result = undef
ECHO: v = 3, op = "not v", result = false
ECHO: v = 3, op = "-v", result = -3
ECHO: v = 3, op = "v *", result = 9
ECHO: v = 3, op = "* v", result = 6
ECHO: v = 3, op = "v /", result = 1
ECHO: v = 3, op = "/ v", result = 0.66666666666
ECHO: v = 3, op = "v %", result = 0
ECHO: v = 3, op = "% v", result = 2
ECHO: v = 3, op = "v +", result = 6
ECHO: v = 3, op = "+ v", result = 5
ECHO: v = 3, op = "v -", result = 0
ECHO: v = 3, op = "- v", result = -1
ECHO: v = 3, op = "v and true", result = true
ECHO: v = 3, op = "v and false", result = false
ECHO: v = 3, op = "v or true", result = true
ECHO: v = 3, op = "v or false", result = true
ECHO: v = 3, op = "[v]", result = "d"
ECHO: v = 3, op = "v[0]", result = undef
ECHO: v = 3, op = "v[4]", result = undef
ECHO: v = 42.42, op = "not v", result = false
ECHO: v = 42.42, op = "-v", result = -42.42
ECHO: v = 42.42, op = "v *", result = 127.26
ECHO: v = 42.42, op = "* v", result = 84.84
ECHO: v = 42.42, op = "v /", result = 14.14
ECHO: v = 42.42, op = "/ v", result = 0.0471475719
ECHO: v = 42.42, op = "v %", result = 0.42
ECHO: v = 42.42, op = "% v", result = 2
ECHO: v = 42.42, op = "v +", result = 45.42
ECHO: v = 42.42, op = "+ v", result = 44.42
ECHO: v = 42.42, op = "v -", result = 39.42
ECHO: v = 42.42, op = "- v", result = -40.42
ECHO: v = 42.42, op = "v and true", result = true
ECHO: v = 42.42, op = "v and false", result = false
ECHO: v = 42.42, op = "v or true", result = true
ECHO: v = 42.42, op = "v or false", result = true
ECHO: v = 42.42, op = "[v]", result = undef
ECHO: v = 42.42, op = "v[0]", result = undef
ECHO: v = 42.42, op = "v[4]", result = undef
ECHO: v = 242, op = "not v", result = false
ECHO: v = 242, op = "-v", result = -242
ECHO: v = 242, op = "v *", result = 726
ECHO: v = 242, op = "* v", result = 484
ECHO: v = 242, op = "v /", result = 80.66666666666
ECHO: v = 242, op = "/ v", result = 0.00826446281
ECHO: v = 242, op = "v %", result = 2
ECHO: v = 242, op = "% v", result = 2
ECHO: v = 242, op = "v +", result = 245
ECHO: v = 242, op = "+ v", result = 244
ECHO: v = 242, op = "v -", result = 239
ECHO: v = 242, op = "- v", result = -240
ECHO: v = 242, op = "v and true", result = true
ECHO: v = 242, op = "v and false", result = false
ECHO: v = 242, op = "v or true", result = true
ECHO: v = 242, op = "v or false", result = true
ECHO: v = 242, op = "[v]", result = undef
ECHO: v = 242, op = "v[0]", result = undef
ECHO: v = 242, op = "v[4]", result = undef
ECHO: v = true, op = "not v", result = false
ECHO: v = true, op = "-v", result = undef
ECHO: v = true, op = "v *", result = undef
ECHO: v = true, op = "* v", result = undef
ECHO: v = true, op = "v /", result = undef
ECHO: v = true, op = "/ v", result = undef
ECHO: v = true, op = "v %", result = undef
ECHO: v = true, op = "% v", result = undef
ECHO: v = true, op = "v +", result = undef
ECHO: v = true, op = "+ v", result = undef
ECHO: v = true, op = "v -", result = undef
ECHO: v = true, op = "- v", result = undef
ECHO: v = true, op = "v and true", result = true
ECHO: v = true, op = "v and false", result = false
ECHO: v = true, op = "v or true", result = true
ECHO: v = true, op = "v or false", result = true
ECHO: v = true, op = "[v]", result = undef
ECHO: v = true, op = "v[0]", result = undef
ECHO: v = true, op = "v[4]", result = undef
ECHO: v = false, op = "not v", result = true
ECHO: v = false, op = "-v", result = undef
ECHO: v = false, op = "v *", result = undef
ECHO: v = false, op = "* v", result = undef
ECHO: v = false, op = "v /", result = undef
ECHO: v = false, op = "/ v", result = undef
ECHO: v = false, op = "v %", result = undef
ECHO: v = false, op = "% v", result = undef
ECHO: v = false, op = "v +", result = undef
ECHO: v = false, op = "+ v", result = undef
ECHO: v = false, op = "v -", result = undef
ECHO: v = false, op = "- v", result = undef
ECHO: v = false, op = "v and true", result = false
ECHO: v = false, op = "v and false", result = false
ECHO: v = false, op = "v or true", result = true
ECHO: v = false, op = "v or false", result = false
ECHO: v = false, op = "[v]", result = undef
ECHO: v = false, op = "v[0]", result = undef
ECHO: v = false, op = "v[4]", result = undef
ECHO: v = "", op = "not v", result = true
ECHO: v = "", op = "-v", result = undef
ECHO: v = "", op = "v *", result = undef
ECHO: v = "", op = "* v", result = undef
ECHO: v = "", op = "v /", result = undef
ECHO: v = "", op = "/ v", result = undef
ECHO: v = "", op = "v %", result = undef
ECHO: v = "", op = "% v", result = undef
ECHO: v = "", op = "v +", result = undef
ECHO: v = "", op = "+ v", result = undef
ECHO: v = "", op = "v -", result = undef
ECHO: v = "", op = "- v", result = undef
ECHO: v = "", op = "v and true", result = false
ECHO: v = "", op = "v and false", result = false
ECHO: v = "", op = "v or true", result = true
ECHO: v = "", op = "v or false", result = false
ECHO: v = "", op = "[v]", result = undef
ECHO: v = "", op = "v[0]", result = undef
ECHO: v = "", op = "v[4]", result = undef
ECHO: v = "text", op = "not v", result = false
ECHO: v = "text", op = "-v", result = undef
ECHO: v = "text", op = "v *", result = undef
ECHO: v = "text", op = "* v", result = undef
ECHO: v = "text", op = "v /", result = undef
ECHO: v = "text", op = "/ v", result = undef
ECHO: v = "text", op = "v %", result = undef
ECHO: v = "text", op = "% v", result = undef
ECHO: v = "text", op = "v +", result = undef
ECHO: v = "text", op = "+ v", result = undef
ECHO: v = "text", op = "v -", result = undef
ECHO: v = "text", op = "- v", result = undef
ECHO: v = "text", op = "v and true", result = true
ECHO: v = "text", op = "v and false", result = false
ECHO: v = "text", op = "v or true", result = true
ECHO: v = "text", op = "v or false", result = true
ECHO: v = "text", op = "[v]", result = undef
ECHO: v = "text", op = "v[0]", result = "t"
ECHO: v = "text", op = "v[4]", result = undef
ECHO: v = [], op = "not v", result = true
ECHO: v = [], op = "-v", result = []
ECHO: v = [], op = "v *", result = []
ECHO: v = [], op = "* v", result = []
ECHO: v = [], op = "v /", result = []
ECHO: v = [], op = "/ v", result = []
ECHO: v = [], op = "v %", result = undef
ECHO: v = [], op = "% v", result = undef
ECHO: v = [], op = "v +", result = undef
ECHO: v = [], op = "+ v", result = undef
ECHO: v = [], op = "v -", result = undef
ECHO: v = [], op = "- v", result = undef
ECHO: v = [], op = "v and true", result = false
ECHO: v = [], op = "v and false", result = false
ECHO: v = [], op = "v or true", result = true
ECHO: v = [], op = "v or false", result = false
ECHO: v = [], op = "[v]", result = undef
ECHO: v = [], op = "v[0]", result = undef
ECHO: v = [], op = "v[4]", result = undef
ECHO: v = [0], op = "not v", result = false
ECHO: v = [0], op = "-v", result = [0]
ECHO: v = [0], op = "v *", result = [0]
ECHO: v = [0], op = "* v", result = [0]
ECHO: v = [0], op = "v /", result = [0]
ECHO: v = [0], op = "/ v", result = [inf]
ECHO: v = [0], op = "v %", result = undef
ECHO: v = [0], op = "% v", result = undef
ECHO: v = [0], op = "v +", result = undef
ECHO: v = [0], op = "+ v", result = undef
ECHO: v = [0], op = "v -", result = undef
ECHO: v = [0], op = "- v", result = undef
ECHO: v = [0], op = "v and true", result = true
ECHO: v = [0], op = "v and false", result = false
ECHO: v = [0], op = "v or true", result = true
ECHO: v = [0], op = "v or false", result = true
ECHO: v = [0], op = "[v]", result = undef
ECHO: v = [0], op = "v[0]", result = 0
ECHO: v = [0], op = "v[4]", result = undef
ECHO: v = [1], op = "not v", result = false
ECHO: v = [1], op = "-v", result = [-1]
ECHO: v = [1], op = "v *", result = [3]
ECHO: v = [1], op = "* v", result = [2]
ECHO: v = [1], op = "v /", result = [0.33333333333]
ECHO: v = [1], op = "/ v", result = [2]
ECHO: v = [1], op = "v %", result = undef
ECHO: v = [1], op = "% v", result = undef
ECHO: v = [1], op = "v +", result = undef
ECHO: v = [1], op = "+ v", result = undef
ECHO: v = [1], op = "v -", result = undef
ECHO: v = [1], op = "- v", result = undef
ECHO: v = [1], op = "v and true", result = true
ECHO: v = [1], op = "v and false", result = false
ECHO: v = [1], op = "v or true", result = true
ECHO: v = [1], op = "v or false", result = true
ECHO: v = [1], op = "[v]", result = undef
ECHO: v = [1], op = "v[0]", result = 1
ECHO: v = [1], op = "v[4]", result = undef
ECHO: v = [0 : 1 : 0], op = "not v", result = false
ECHO: v = [0 : 1 : 0], op = "-v", result = undef
ECHO: v = [0 : 1 : 0], op = "v *", result = undef
ECHO: v = [0 : 1 : 0], op = "* v", result = undef
ECHO: v = [0 : 1 : 0], op = "v /", result = undef
ECHO: v = [0 : 1 : 0], op = "/ v", result = undef
ECHO: v = [0 : 1 : 0], op = "v %", result = undef
ECHO: v = [0 : 1 : 0], op = "% v", result = undef
ECHO: v = [0 : 1 : 0], op = "v +", result = undef
ECHO: v = [0 : 1 : 0], op = "+ v", result = undef
ECHO: v = [0 : 1 : 0], op = "v -", result = undef
ECHO: v = [0 : 1 : 0], op = "- v", result = undef
ECHO: v = [0 : 1 : 0], op = "v and true", result = true
ECHO: v = [0 : 1 : 0], op = "v and false", result = false
ECHO: v = [0 : 1 : 0], op = "v or true", result = true
ECHO: v = [0 : 1 : 0], op = "v or false", result = true
ECHO: v = [0 : 1 : 0], op = "[v]", result = undef
ECHO: v = [0 : 1 : 0], op = "v[0]", result = 0
ECHO: v = [0 : 1 : 0], op = "v[4]", result = undef
ECHO: v = [1 : 1 : 2], op = "not v", result = false
ECHO: v = [1 : 1 : 2], op = "-v", result = undef
ECHO: v = [1 : 1 : 2], op = "v *", result = undef
ECHO: v = [1 : 1 : 2], op = "* v", result = undef
ECHO: v = [1 : 1 : 2], op = "v /", result = undef
ECHO: v = [1 : 1 : 2], op = "/ v", result = undef
ECHO: v = [1 : 1 : 2], op = "v %", result = undef
ECHO: v = [1 : 1 : 2], op = "% v", result = undef
ECHO: v = [1 : 1 : 2], op = "v +", result = undef
ECHO: v = [1 : 1 : 2], op = "+ v", result = undef
ECHO: v = [1 : 1 : 2], op = "v -", result = undef
ECHO: v = [1 : 1 : 2], op = "- v", result = undef
ECHO: v = [1 : 1 : 2], op = "v and true", result = true
ECHO: v = [1 : 1 : 2], op = "v and false", result = false
ECHO: v = [1 : 1 : 2], op = "v or true", result = true
ECHO: v = [1 : 1 : 2], op = "v or false", result = true
ECHO: v = [1 : 1 : 2], op = "[v]", result = undef
ECHO: v = [1 : 1 : 2], op = "v[0]", result = 1
ECHO: v = [1 : 1 : 2], op = "v[4]", result = undef

View File

@ -11,14 +11,3 @@ ECHO: "INF", 0
WARNING: Bad range parameter in for statement: too many elements (4294967295).
ECHO: "-INF", 1
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).
WARNING: Bad range parameter in for statement: too many elements (4294967295).

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB