From ab3b10e889477e20966c6387d6dc2f0542049509 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Aug 2011 02:42:24 +0200 Subject: mixed-case filename fixes diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fb86448..ae5c496 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -149,7 +149,7 @@ target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_ # opencsgtest # add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm - ../src/opencsgrenderer.cc ../src/throwntogetherrenderer.cc ../src/CSGTermEvaluator.cc ../src/cgal.cc ../src/CGALEvaluator.cc + ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/CSGTermEvaluator.cc ../src/cgal.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/nef2dxf.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_minkowski3.cc ${COMMON_SOURCES}) -- cgit v0.10.1 From 3e558d44463a3b79ccce1e90d9bb97007bdcc6d9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Aug 2011 02:42:37 +0200 Subject: Linux build fix diff --git a/tests/FindGLEW.cmake b/tests/FindGLEW.cmake index bccb20a..e058e8c 100644 --- a/tests/FindGLEW.cmake +++ b/tests/FindGLEW.cmake @@ -20,16 +20,14 @@ IF (WIN32) ${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib DOC "The GLEW library") ELSE (WIN32) - message(${GLEW_DIR}) + message("GLEW_DIR: " ${GLEW_DIR}) FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h - PATHS - ${GLEW_DIR}/include + PATHS ${GLEW_DIR}/include /usr/include /usr/local/include NO_DEFAULT_PATH DOC "The directory where GL/glew.h resides") FIND_LIBRARY( GLEW_LIBRARY NAMES GLEW glew - PATHS - ${GLEW_DIR}/lib + PATHS ${GLEW_DIR}/lib /usr/lib /usr/local/lib NO_DEFAULT_PATH DOC "The GLEW library") ENDIF (WIN32) @@ -40,5 +38,3 @@ IF (GLEW_INCLUDE_PATH) ELSE (GLEW_INCLUDE_PATH) SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise") ENDIF (GLEW_INCLUDE_PATH) - -MARK_AS_ADVANCED( GLEW_FOUND ) -- cgit v0.10.1 From 2fe2f37fbc51321ffe8b4f1e85e3ad3921e2c5e5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Aug 2011 04:34:46 +0200 Subject: bugfix: -x option didn't work diff --git a/src/openscad.cc b/src/openscad.cc index f3aee76..a948c5a 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -358,9 +358,9 @@ int main(int argc, char **argv) } if (dxf_output_file) { - QFile file(stl_output_file); + QFile file(dxf_output_file); if (!file.open(QIODevice::ReadWrite)) { - PRINTA("Can't open file \"%1\" for export", stl_output_file); + PRINTA("Can't open file \"%1\" for export", dxf_output_file); } else { QTextStream fstream(&file); -- cgit v0.10.1 From 79efff37fedec1d0e19004eec26267a462b15eb5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Aug 2011 04:35:08 +0200 Subject: bugfix: Importing all layers was broken diff --git a/src/dxfdata.cc b/src/dxfdata.cc index 78ab454..7bf4364 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -48,7 +48,7 @@ DxfData::DxfData() } /*! - Reads a layer from the given file, or all layers if layename.isNull() + Reads a layer from the given file, or all layers if layername.isEmpty() */ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString layername, double xorigin, double yorigin, double scale) { @@ -74,7 +74,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye if (!in_entities_section && !in_blocks_section) \ break; \ if (in_entities_section && \ - !(layername.isNull() || layername == layer)) \ + !(layername.isEmpty() || layername == layer)) \ break; \ grid.align(_p1x, _p1y); \ grid.align(_p2x, _p2y); \ @@ -249,7 +249,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye } } else if (mode == "DIMENSION" && - (layername.isNull() || layername == layer)) { + (layername.isEmpty() || layername == layer)) { this->dims.append(Dim()); this->dims.last().type = dimtype; for (int i = 0; i < 7; i++) @@ -268,7 +268,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye else if (mode == "ENDSEC") { } else if (in_blocks_section || (in_entities_section && - (layername.isNull() || layername == layer))) { + (layername.isEmpty() || layername == layer))) { unsupported_entities_list[mode]++; } mode = data; @@ -357,7 +357,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye QHashIterator i(unsupported_entities_list); while (i.hasNext()) { i.next(); - if (layername.isNull()) { + if (layername.isEmpty()) { PRINTA("WARNING: Unsupported DXF Entity `%1' (%2x) in `%3'.", i.key(), QString::number(i.value()), filename); } else { -- cgit v0.10.1 From c86630c297da202188cbcc0d35566339e0607d60 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Aug 2011 04:43:40 +0200 Subject: keep track of changes in visitor branch diff --git a/doc/visitor-changes.txt b/doc/visitor-changes.txt new file mode 100644 index 0000000..e39cd2e --- /dev/null +++ b/doc/visitor-changes.txt @@ -0,0 +1,2 @@ +Changes in visitor branch: +o import_dxf(): layername="" imports all layers. Importing a single layer with a zero-length name is no longer supported. -- cgit v0.10.1 From 22a2583c700fc33314d2566767df7bc32fcaddb0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Aug 2011 05:01:04 +0200 Subject: test cases diff --git a/testdata/scad/features/background-modifier.scad b/testdata/scad/features/background-modifier.scad new file mode 100644 index 0000000..ec7b28d --- /dev/null +++ b/testdata/scad/features/background-modifier.scad @@ -0,0 +1,4 @@ +difference() { + sphere(r=10); + %cylinder(h=30, r=6, center=true); +} diff --git a/testdata/scad/features/highlight-modifier.scad b/testdata/scad/features/highlight-modifier.scad new file mode 100644 index 0000000..1156a88 --- /dev/null +++ b/testdata/scad/features/highlight-modifier.scad @@ -0,0 +1,4 @@ +difference() { + sphere(r=10); + #cylinder(h=30, r=6, center=true); +} diff --git a/testdata/scad/features/square-tests.scad b/testdata/scad/features/square-tests.scad new file mode 100644 index 0000000..57ec1c4 --- /dev/null +++ b/testdata/scad/features/square-tests.scad @@ -0,0 +1,8 @@ +square(); +translate([2,0,0]) square([1,1], true); +translate([4,0,0]) square(size=[1,1], center=true); +translate([6,0,0]) square([0,0], true); +translate([0,2,0]) square([1,0], true); +translate([2,2,0]) square([0,1], true); +translate([4,2,0]) square([1,2], true); +translate([6,2,0]) square([2,1], true); -- cgit v0.10.1 From d4dfe51118d2f92d08fec927145247288498f6bd Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Aug 2011 05:01:59 +0200 Subject: Camera handling fixes diff --git a/tests/OffscreenView.cc b/tests/OffscreenView.cc index f137041..a5eb371 100644 --- a/tests/OffscreenView.cc +++ b/tests/OffscreenView.cc @@ -7,10 +7,8 @@ #define FAR_FAR_AWAY 100000.0 OffscreenView::OffscreenView(size_t width, size_t height) - : orthomode(false), showaxes(true), showfaces(true), showedges(false), - object_rot_x(35), object_rot_y(0), object_rot_z(25), - camera_eye_x(0), camera_eye_y(0), camera_eye_z(0), - camera_center_x(0), camera_center_y(0), camera_center_z(0) + : orthomode(false), showaxes(false), showfaces(true), showedges(false), + object_rot(35, 0, 25), camera_eye(0, 0, 0), camera_center(0, 0, 0) { for (int i = 0; i < 10; i++) this->shaderinfo[i] = 0; this->ctx = create_offscreen_context(width, height); @@ -160,8 +158,8 @@ void OffscreenView::setupPerspective() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(90, w_h_ratio, 0.1*(this->camera_center_y - this->camera_eye_y), - 3*(this->camera_center_y - this->camera_eye_y)); + double dist = (this->camera_center - this->camera_eye).norm(); + gluPerspective(90, w_h_ratio, 0.1*dist, 10*dist); } void OffscreenView::setupOrtho(bool offset) @@ -169,7 +167,7 @@ void OffscreenView::setupOrtho(bool offset) glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (offset) glTranslated(-0.8, -0.8, 0); - double l = (this->camera_eye_y - this->camera_center_y)/10; + double l = (this->camera_center - this->camera_eye).norm() / 10; glOrtho(-w_h_ratio*l, +w_h_ratio*l, -(1/w_h_ratio)*l, +(1/w_h_ratio)*l, -FAR_FAR_AWAY, +FAR_FAR_AWAY); @@ -189,13 +187,13 @@ void OffscreenView::paintGL() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - gluLookAt(this->camera_eye_x, this->camera_eye_y, this->camera_eye_z, - this->camera_center_x, this->camera_center_y, this->camera_center_z, + gluLookAt(this->camera_eye[0], this->camera_eye[1], this->camera_eye[2], + this->camera_center[0], this->camera_center[1], this->camera_center[2], 0.0, 0.0, 1.0); - glRotated(object_rot_x, 1.0, 0.0, 0.0); - glRotated(object_rot_y, 0.0, 1.0, 0.0); - glRotated(object_rot_z, 0.0, 0.0, 1.0); + // glRotated(object_rot[0], 1.0, 0.0, 0.0); + // glRotated(object_rot[1], 0.0, 1.0, 0.0); + // glRotated(object_rot[2], 0.0, 0.0, 1.0); // Large gray axis cross inline with the model // FIXME: This is always gray - adjust color to keep contrast with background @@ -204,7 +202,7 @@ void OffscreenView::paintGL() glLineWidth(1); glColor3d(0.5, 0.5, 0.5); glBegin(GL_LINES); - double l = 3*(this->camera_eye_y - this->camera_center_y); + double l = 3*(this->camera_center - this->camera_eye).norm(); glVertex3d(-l, 0, 0); glVertex3d(+l, 0, 0); glVertex3d(0, -l, 0); @@ -234,14 +232,9 @@ bool OffscreenView::save(const char *filename) return save_framebuffer(this->ctx, filename); } -void OffscreenView::setCamera(double xpos, double ypos, double zpos, - double xcenter, double ycenter, double zcenter) +void OffscreenView::setCamera(const Eigen::Vector3d &pos, const Eigen::Vector3d ¢er) { - this->camera_eye_x = xpos; - this->camera_eye_y = ypos; - this->camera_eye_z = zpos; - this->camera_center_x = xcenter; - this->camera_center_y = ycenter; - this->camera_center_z = zcenter; + this->camera_eye = pos; + this->camera_center = center; } diff --git a/tests/OffscreenView.h b/tests/OffscreenView.h index d71ea2f..587255a 100644 --- a/tests/OffscreenView.h +++ b/tests/OffscreenView.h @@ -2,6 +2,8 @@ #define OFFSCREENVIEW_H_ #include "OffscreenContext.h" +#include +#include #include class OffscreenView @@ -11,8 +13,7 @@ public: ~OffscreenView(); void setRenderer(class Renderer* r); - void setCamera(double xpos, double ypos, double zpos, - double xcenter, double ycenter, double zcenter); + void setCamera(const Eigen::Vector3d &pos, const Eigen::Vector3d ¢er); void initializeGL(); void resizeGL(int w, int h); void setupPerspective(); @@ -25,15 +26,9 @@ public: private: Renderer *renderer; double w_h_ratio; - double object_rot_x; - double object_rot_y; - double object_rot_z; - double camera_eye_x; - double camera_eye_y; - double camera_eye_z; - double camera_center_x; - double camera_center_y; - double camera_center_z; + Eigen::Vector3d object_rot; + Eigen::Vector3d camera_eye; + Eigen::Vector3d camera_center; bool orthomode; bool showaxes; diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index 026978d..cbf07e8 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -217,8 +217,11 @@ int main(int argc, char *argv[]) Vector3d center = (bbox.min() + bbox.max()) / 2; double radius = (bbox.max() - bbox.min()).norm() / 2; - csgInfo.glview->setCamera(center[0], center[1] - 2 * radius, center[2], - center[0], center[1], center[2]); + + + Vector3d cameradir(1, 1, -0.5); + Vector3d camerapos = center - radius*1.5*cameradir; + csgInfo.glview->setCamera(camerapos, center); glewInit(); #ifdef DEBUG -- cgit v0.10.1 From 7c391a24c1e9e7b313909fa49124a1c3ced42153 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Aug 2011 05:03:35 +0200 Subject: Updated camera settings diff --git a/tests/regression/opencsgtest/background-modifier-expected.png b/tests/regression/opencsgtest/background-modifier-expected.png index f1d48d9..12ba8a1 100644 Binary files a/tests/regression/opencsgtest/background-modifier-expected.png and b/tests/regression/opencsgtest/background-modifier-expected.png differ diff --git a/tests/regression/opencsgtest/example001-expected.png b/tests/regression/opencsgtest/example001-expected.png index 48509b2..6086195 100644 Binary files a/tests/regression/opencsgtest/example001-expected.png and b/tests/regression/opencsgtest/example001-expected.png differ diff --git a/tests/regression/opencsgtest/highlight-modifier-expected.png b/tests/regression/opencsgtest/highlight-modifier-expected.png index 7a117fa..042923f 100644 Binary files a/tests/regression/opencsgtest/highlight-modifier-expected.png and b/tests/regression/opencsgtest/highlight-modifier-expected.png differ -- cgit v0.10.1 From 573a78c3c34b53bc1dc9750cd8b297d00c9b58c2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Aug 2011 05:06:46 +0200 Subject: Added square-tests diff --git a/tests/regression/opencsgtest/square-tests-expected.png b/tests/regression/opencsgtest/square-tests-expected.png new file mode 100644 index 0000000..d5106e9 Binary files /dev/null and b/tests/regression/opencsgtest/square-tests-expected.png differ -- cgit v0.10.1 From 3f58ca2ddd8464713aff254f084f0aeb47ba5085 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Aug 2011 05:07:59 +0200 Subject: bugfix: bbox calculation didn't take transformation matrix into account diff --git a/src/csgterm.cc b/src/csgterm.cc index 411cb12..db9525a 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -234,7 +234,18 @@ BoundingBox CSGChain::getBoundingBox() const BoundingBox bbox; for (size_t i=0;igetBoundingBox()); + BoundingBox psbox = polysets[i]->getBoundingBox(); + if (!psbox.isNull()) { + Eigen::Transform3d t; + // Column-major vs. Row-major + t.matrix() << + matrices[i][0], matrices[i][4], matrices[i][8], matrices[i][12], + matrices[i][1], matrices[i][5], matrices[i][9], matrices[i][13], + matrices[i][2], matrices[i][6], matrices[i][10], matrices[i][14], + matrices[i][3], matrices[i][7], matrices[i][11], matrices[i][15]; + bbox.extend(t * psbox.min()); + bbox.extend(t * psbox.max()); + } } } return bbox; -- cgit v0.10.1 From 05bd59846a095f07b8ba079bb65c982ed36a367e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Aug 2011 17:43:33 +0200 Subject: cosmetics diff --git a/src/cgal.h b/src/cgal.h index 911ee55..d015559 100644 --- a/src/cgal.h +++ b/src/cgal.h @@ -14,23 +14,23 @@ #include #include -typedef CGAL::Extended_cartesian CGAL_Kernel2; +typedef CGAL::Gmpq NT; +typedef CGAL::Extended_cartesian CGAL_Kernel2; typedef CGAL::Nef_polyhedron_2 CGAL_Nef_polyhedron2; typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2; -typedef CGAL::Cartesian CGAL_Kernel3; -typedef CGAL::Polyhedron_3 CGAL_Polyhedron; -typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; -typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; -typedef CGAL::Nef_polyhedron_3 CGAL_Nef_polyhedron3; -typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation; -typedef CGAL_Nef_polyhedron3::Vector_3 CGAL_Vector; -typedef CGAL_Nef_polyhedron3::Plane_3 CGAL_Plane; -typedef CGAL_Nef_polyhedron3::Point_3 CGAL_Point; typedef CGAL::Exact_predicates_exact_constructions_kernel CGAL_ExactKernel2; typedef CGAL::Polygon_2 CGAL_Poly2; typedef CGAL::Polygon_with_holes_2 CGAL_Poly2h; +typedef CGAL::Cartesian CGAL_Kernel3; +typedef CGAL::Nef_polyhedron_3 CGAL_Nef_polyhedron3; +typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation; + +typedef CGAL::Polyhedron_3 CGAL_Polyhedron; +typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; +typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; + struct CGAL_Nef_polyhedron { int dim; -- cgit v0.10.1 From 9e6445320699c259d30f3075faca0140462d2f6b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Aug 2011 19:14:35 +0200 Subject: Added circle-tests diff --git a/testdata/scad/features/circle-tests.scad b/testdata/scad/features/circle-tests.scad new file mode 100644 index 0000000..edf93a4 --- /dev/null +++ b/testdata/scad/features/circle-tests.scad @@ -0,0 +1,10 @@ +circle(); +translate([0,3,0]) circle(1, true); +translate([5,1,0]) circle(r=3, center=true); +translate([0,-1,0]) circle(r=0, center=true); +translate([0,-3,0]) circle(1, true, $fn=4); +translate([3,-3,0]) circle(1, true, $fn=8); +translate([6,-3,0]) circle(1, true, $fn=12); +translate([0,-6,0]) circle(1, true, $fa=20, $fs=0.3); +translate([3,-6,0]) circle(1, true, $fa=30, $fs=0.3); +translate([6,-6,0]) circle(1, true, $fa=40, $fs=0.3); diff --git a/tests/regression/opencsgtest/circle-tests-expected.png b/tests/regression/opencsgtest/circle-tests-expected.png new file mode 100644 index 0000000..6a826c9 Binary files /dev/null and b/tests/regression/opencsgtest/circle-tests-expected.png differ -- cgit v0.10.1 From 1633fb0344c92631562c2a802e8deddf2ce4637f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 04:09:06 +0200 Subject: Refactoring of CGAL functionality to allow for forward-declaration of CGAL classes in header files, reducing coupling and thus compilation times diff --git a/openscad.pro b/openscad.pro index deda4d0..8e43102 100644 --- a/openscad.pro +++ b/openscad.pro @@ -119,7 +119,6 @@ FORMS += src/MainWindow.ui \ src/Preferences.ui HEADERS += src/renderer.h \ - src/cgalrenderer.h \ src/ThrownTogetherRenderer.h \ src/CGAL_renderer.h \ src/OGL_helper.h \ @@ -127,7 +126,6 @@ HEADERS += src/renderer.h \ src/MainWindow.h \ src/Preferences.h \ src/builtin.h \ - src/cgal.h \ src/context.h \ src/csgterm.h \ src/dxfdata.h \ @@ -158,9 +156,7 @@ HEADERS += src/renderer.h \ src/traverser.h \ src/nodecache.h \ src/nodedumper.h \ - src/CGALEvaluator.h \ src/PolySetEvaluator.h \ - src/PolySetCGALEvaluator.h \ src/CSGTermEvaluator.h \ src/myqhash.h \ src/Tree.h \ @@ -169,8 +165,6 @@ HEADERS += src/renderer.h \ SOURCES += src/openscad.cc \ src/mainwin.cc \ - src/cgalrenderer.cc \ - src/cgal.cc \ src/ThrownTogetherRenderer.cc \ src/glview.cc \ src/export.cc \ @@ -187,9 +181,6 @@ SOURCES += src/openscad.cc \ src/primitives.cc \ src/projection.cc \ src/cgaladv.cc \ - src/cgaladv_convexhull2.cc \ - src/cgaladv_minkowski3.cc \ - src/cgaladv_minkowski2.cc \ src/surface.cc \ src/control.cc \ src/render.cc \ @@ -203,19 +194,33 @@ SOURCES += src/openscad.cc \ src/dxfrotextrude.cc \ src/highlighter.cc \ src/printutils.cc \ - src/nef2dxf.cc \ src/Preferences.cc \ src/progress.cc \ src/editor.cc \ src/traverser.cc \ src/nodedumper.cc \ - src/CGALEvaluator.cc \ - src/PolySetEvaluator.cc \ - src/PolySetCGALEvaluator.cc \ src/CSGTermEvaluator.cc \ src/qhash.cc \ src/Tree.cc \ - src/mathc99.cc + src/mathc99.cc \ + src/PolySetEvaluator.cc + +cgal { +HEADERS += src/cgal.h \ + src/cgalfwd.h \ + src/CGALEvaluator.h \ + src/PolySetCGALEvaluator.h \ + src/cgalrenderer.h \ + src/CGAL_Nef_polyhedron.h + +SOURCES += src/CGALEvaluator.cc \ + src/PolySetCGALEvaluator.cc \ + src/cgalrenderer.cc \ + src/CGAL_Nef_polyhedron.cc \ + src/CGAL_Nef_polyhedron_DxfData.cc \ + src/cgaladv_convexhull2.cc \ + src/cgaladv_minkowski2.cc +} macx { HEADERS += src/AppleEvents.h \ diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 22583a7..c67e1f5 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -10,6 +10,7 @@ #include "dxfdata.h" #include "dxftess.h" +#include "cgal.h" #include #include @@ -46,45 +47,25 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr assert(false && "Dimension of Nef polyhedron must be 2 or 3"); } - if (target.dim == 2) { - switch (op) { - case CGE_UNION: - target.p2 += src.p2; - break; - case CGE_INTERSECTION: - target.p2 *= src.p2; - break; - case CGE_DIFFERENCE: - target.p2 -= src.p2; - break; - case CGE_MINKOWSKI: - target.p2 = minkowski2(target.p2, src.p2); - break; - case CGE_HULL: - //FIXME: Port convex hull to a binary operator or process it all in the end somehow - // target.p2 = convexhull2(target.p2, src.p2); - // target.p2 = convexhull2(polys); - break; - } - } - else if (target.dim == 3) { - switch (op) { - case CGE_UNION: - target.p3 += src.p3; - break; - case CGE_INTERSECTION: - target.p3 *= src.p3; - break; - case CGE_DIFFERENCE: - target.p3 -= src.p3; - break; - case CGE_MINKOWSKI: - target.p3 = minkowski3(target.p3, src.p3); - break; - case CGE_HULL: - // FIXME: Print warning: hull() not supported in 3D - break; - } + switch (op) { + case CGE_UNION: + target += src; + break; + case CGE_INTERSECTION: + target *= src; + break; + case CGE_DIFFERENCE: + target -= src; + break; + case CGE_MINKOWSKI: + target = target.minkowski(src); + break; + case CGE_HULL: + //FIXME: Port convex hull to a binary operator or process it all in the end somehow + // target.p2 = convexhull2(target.p2, src.p2); + // target.p2 = convexhull2(polys); + // FIXME: Print warning: hull() not supported in 3D + break; } } @@ -191,27 +172,28 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) node.matrix[0], node.matrix[4], node.matrix[12], node.matrix[1], node.matrix[5], node.matrix[13], node.matrix[15]); - DxfData dd(N); - for (int i=0; i < dd.points.size(); i++) { - CGAL_Kernel2::Point_2 p = CGAL_Kernel2::Point_2(dd.points[i][0], dd.points[i][1]); + DxfData *dd = N.convertToDxfData(); + for (int i=0; i < dd->points.size(); i++) { + CGAL_Kernel2::Point_2 p = CGAL_Kernel2::Point_2(dd->points[i][0], dd->points[i][1]); p = t.transform(p); - dd.points[i][0] = to_double(p.x()); - dd.points[i][1] = to_double(p.y()); + dd->points[i][0] = to_double(p.x()); + dd->points[i][1] = to_double(p.y()); } PolySet ps; ps.is2d = true; - dxf_tesselate(&ps, &dd, 0, true, false, 0); + dxf_tesselate(&ps, dd, 0, true, false, 0); N = evaluateCGALMesh(ps); ps.refcount = 0; + delete dd; } else if (N.dim == 3) { CGAL_Aff_transformation t( node.matrix[0], node.matrix[4], node.matrix[ 8], node.matrix[12], node.matrix[1], node.matrix[5], node.matrix[ 9], node.matrix[13], node.matrix[2], node.matrix[6], node.matrix[10], node.matrix[14], node.matrix[15]); - N.p3.transform(t); + N.p3->transform(t); } this->cache.insert(this->tree.getString(node), N); } @@ -574,9 +556,9 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) } } - CGAL_Nef_polyhedron2 toNef() + CGAL_Nef_polyhedron2 *toNef() { - CGAL_Nef_polyhedron2 N; + CGAL_Nef_polyhedron2 *N = new CGAL_Nef_polyhedron2; QHashIterator< int, QList > it(polygons); while (it.hasNext()) { @@ -586,7 +568,7 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) int p = it.value()[j]; plist.push_back(points[p]); } - N += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + *N += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); } return N; @@ -642,7 +624,7 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) #if 0 std::cout << P; #endif - CGAL_Nef_polyhedron3 N(P); + CGAL_Nef_polyhedron3 *N = new CGAL_Nef_polyhedron3(P); return CGAL_Nef_polyhedron(N); } catch (CGAL::Assertion_exception e) { diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index 9a1c88c..85d09c4 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -4,7 +4,7 @@ #include "myqhash.h" #include "visitor.h" #include "Tree.h" -#include "cgal.h" +#include "CGAL_Nef_polyhedron.h" #include "PolySetCGALEvaluator.h" #include diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc new file mode 100644 index 0000000..09368da --- /dev/null +++ b/src/CGAL_Nef_polyhedron.cc @@ -0,0 +1,111 @@ +#include "CGAL_Nef_polyhedron.h" +#include "cgal.h" +#include "polyset.h" +#include + +CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other) +{ + if (other.dim == 2) { + (*this->p2) += (*other.p2); + this->dim = 2; + } + if (other.dim == 3) { + (*this->p3) += (*other.p3); + this->dim = 3; + } + return *this; +} + +CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator*=(const CGAL_Nef_polyhedron &other) +{ + if (other.dim == 2) { + (*this->p2) *= (*other.p2); + this->dim = 2; + } + if (other.dim == 3) { + (*this->p3) *= (*other.p3); + this->dim = 3; + } + return *this; +} + +CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator-=(const CGAL_Nef_polyhedron &other) +{ + if (other.dim == 2) { + (*this->p2) -= (*other.p2); + this->dim = 2; + } + if (other.dim == 3) { + (*this->p3) -= (*other.p3); + this->dim = 3; + } + return *this; +} + +int CGAL_Nef_polyhedron::weight() const +{ + if (dim == 2) + return p2->explorer().number_of_vertices(); + if (dim == 3) + return p3->number_of_vertices(); + return 0; +} + +/*! + Creates a new PolySet and initializes it with the data from this polyhedron + + This method is not const since convert_to_Polyhedron() wasn't const + in earlier versions of CGAL. +*/ +PolySet *CGAL_Nef_polyhedron::convertToPolyset() +{ + PolySet *ps = new PolySet(); + CGAL_Polyhedron P; + this->p3->convert_to_Polyhedron(P); + + typedef CGAL_Polyhedron::Vertex Vertex; + typedef CGAL_Polyhedron::Vertex_const_iterator VCI; + typedef CGAL_Polyhedron::Facet_const_iterator FCI; + typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; + + for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { + HFCC hc = fi->facet_begin(); + HFCC hc_end = hc; + Vertex v1, v2, v3; + v1 = *VCI((hc++)->vertex()); + v3 = *VCI((hc++)->vertex()); + do { + v2 = v3; + v3 = *VCI((hc++)->vertex()); + double x1 = CGAL::to_double(v1.point().x()); + double y1 = CGAL::to_double(v1.point().y()); + double z1 = CGAL::to_double(v1.point().z()); + double x2 = CGAL::to_double(v2.point().x()); + double y2 = CGAL::to_double(v2.point().y()); + double z2 = CGAL::to_double(v2.point().z()); + double x3 = CGAL::to_double(v3.point().x()); + double y3 = CGAL::to_double(v3.point().y()); + double z3 = CGAL::to_double(v3.point().z()); + ps->append_poly(); + ps->append_vertex(x1, y1, z1); + ps->append_vertex(x2, y2, z2); + ps->append_vertex(x3, y3, z3); + } while (hc != hc_end); + } + return ps; +} + +extern CGAL_Nef_polyhedron2 minkowski2(const CGAL_Nef_polyhedron2 &a, const CGAL_Nef_polyhedron2 &b); + +CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &other) +{ + if (other.dim == 2) { + (*this->p2) = minkowski2(*this->p2, *other.p2); + this->dim = 2; + } + if (other.dim == 3) { + (*this->p3) = CGAL::minkowski_sum_3(*this->p3, *other.p3); + this->dim = 3; + } + return *this; +} diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h new file mode 100644 index 0000000..0ab72d7 --- /dev/null +++ b/src/CGAL_Nef_polyhedron.h @@ -0,0 +1,31 @@ +#ifndef CGAL_NEF_POLYHEDRON_H_ +#define CGAL_NEF_POLYHEDRON_H_ + +#ifdef ENABLE_CGAL + +#include "cgalfwd.h" + +class CGAL_Nef_polyhedron +{ +public: + CGAL_Nef_polyhedron() : dim(0) {} + CGAL_Nef_polyhedron(CGAL_Nef_polyhedron2 *p) : dim(2), p2(p) {} + CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) : dim(3), p3(p) { } + ~CGAL_Nef_polyhedron() {} + + CGAL_Nef_polyhedron &operator+=(const CGAL_Nef_polyhedron &other); + CGAL_Nef_polyhedron &operator*=(const CGAL_Nef_polyhedron &other); + CGAL_Nef_polyhedron &operator-=(const CGAL_Nef_polyhedron &other); + CGAL_Nef_polyhedron &minkowski(const CGAL_Nef_polyhedron &other); + int weight() const; + class PolySet *convertToPolyset(); + class DxfData *convertToDxfData() const; + + int dim; + CGAL_Nef_polyhedron2 *p2; + CGAL_Nef_polyhedron3 *p3; +}; + +#endif /* ENABLE_CGAL */ + +#endif diff --git a/src/CGAL_Nef_polyhedron_DxfData.cc b/src/CGAL_Nef_polyhedron_DxfData.cc new file mode 100644 index 0000000..4bfb205 --- /dev/null +++ b/src/CGAL_Nef_polyhedron_DxfData.cc @@ -0,0 +1,80 @@ +/* + * OpenSCAD (www.openscad.org) + * Copyright (C) 2009-2011 Clifford Wolf and + * Marius Kintel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * As a special exception, you have permission to link this program + * with the CGAL library and distribute executables, as long as you + * follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from CGAL. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "dxfdata.h" +#include "grid.h" +#include "CGAL_Nef_polyhedron.h" +#include "cgal.h" + +#ifdef ENABLE_CGAL + +DxfData *CGAL_Nef_polyhedron::convertToDxfData() const +{ + assert(this->dim == 2); + DxfData *dxfdata = new DxfData(); + Grid2d grid(GRID_COARSE); + + typedef CGAL_Nef_polyhedron2::Explorer Explorer; + typedef Explorer::Face_const_iterator fci_t; + typedef Explorer::Halfedge_around_face_const_circulator heafcc_t; + Explorer E = this->p2->explorer(); + + for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit) + { + heafcc_t fcirc(E.halfedge(fit)), fend(fcirc); + int first_point = -1, last_point = -1; + CGAL_For_all(fcirc, fend) { + if (E.is_standard(E.target(fcirc))) { + Explorer::Point ep = E.point(E.target(fcirc)); + double x = to_double(ep.x()), y = to_double(ep.y()); + int this_point = -1; + if (grid.has(x, y)) { + this_point = grid.align(x, y); + } else { + this_point = grid.align(x, y) = dxfdata->points.size(); + dxfdata->points.append(Vector2d(x, y)); + } + if (first_point < 0) { + dxfdata->paths.append(DxfData::Path()); + first_point = this_point; + } + if (this_point != last_point) { + dxfdata->paths.last().points.append(&dxfdata->points[this_point]); + last_point = this_point; + } + } + } + if (first_point >= 0) { + dxfdata->paths.last().is_closed = 1; + dxfdata->paths.last().points.append(&dxfdata->points[first_point]); + } + } + + dxfdata->fixup_path_direction(); + return dxfdata; +} + +#endif // ENABLE_CGAL diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index a914a62..7e7e528 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -1,4 +1,5 @@ #include "PolySetCGALEvaluator.h" +#include "cgal.h" #include "polyset.h" #include "CGALEvaluator.h" #include "projectionnode.h" @@ -67,8 +68,8 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr cube->unlink(); // N.p3 *= CGAL_Nef_polyhedron3(CGAL_Plane(0, 0, 1, 0), CGAL_Nef_polyhedron3::INCLUDED); - N.p3 *= Ncube.p3; - if (!N.p3.is_simple()) { + N *= Ncube; + if (!N.p3->is_simple()) { PRINTF("WARNING: Body of projection(cut = true) isn't valid 2-manifold! Modify your design.."); goto cant_project_non_simple_polyhedron; } @@ -99,7 +100,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr } else { - if (!N.p3.is_simple()) { + if (!N.p3->is_simple()) { PRINTF("WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your design.."); goto cant_project_non_simple_polyhedron; } @@ -144,13 +145,13 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr else plist.push_back(p); } - np.p2 += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), - CGAL_Nef_polyhedron2::INCLUDED); + (*np.p2) += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); } - DxfData dxf(np); - dxf_tesselate(ps, &dxf, 0, true, false, 0); - dxf_border_to_ps(ps, &dxf); + DxfData *dxf = np.convertToDxfData(); + dxf_tesselate(ps, dxf, 0, true, false, 0); + dxf_border_to_ps(ps, dxf); ps3->unlink(); + delete dxf; } cant_project_non_simple_polyhedron: @@ -246,10 +247,10 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, N.dim = 2; foreach (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; - N.p2 += this->cgalevaluator.evaluateCGALMesh(*v).p2; + N += this->cgalevaluator.evaluateCGALMesh(*v); } - dxf = new DxfData(N); + dxf = N.convertToDxfData();; } else { dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } @@ -337,10 +338,10 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, N.dim = 2; foreach (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; - N.p2 += this->cgalevaluator.evaluateCGALMesh(*v).p2; + N += this->cgalevaluator.evaluateCGALMesh(*v); } - dxf = new DxfData(N); + dxf = N.convertToDxfData(); } else { dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } diff --git a/src/cgal.cc b/src/cgal.cc deleted file mode 100644 index 190ebd0..0000000 --- a/src/cgal.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "cgal.h" -#include "polyset.h" - -/*! - Creates a new PolySet and initializes it with the data from this polyhedron - - This method is not const since convert_to_Polyhedron() wasn't const - in earlier versions of CGAL. -*/ -PolySet *CGAL_Nef_polyhedron::convertToPolyset() -{ - PolySet *ps = new PolySet(); - CGAL_Polyhedron P; - this->p3.convert_to_Polyhedron(P); - - typedef CGAL_Polyhedron::Vertex Vertex; - typedef CGAL_Polyhedron::Vertex_const_iterator VCI; - typedef CGAL_Polyhedron::Facet_const_iterator FCI; - typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; - - for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { - HFCC hc = fi->facet_begin(); - HFCC hc_end = hc; - Vertex v1, v2, v3; - v1 = *VCI((hc++)->vertex()); - v3 = *VCI((hc++)->vertex()); - do { - v2 = v3; - v3 = *VCI((hc++)->vertex()); - double x1 = CGAL::to_double(v1.point().x()); - double y1 = CGAL::to_double(v1.point().y()); - double z1 = CGAL::to_double(v1.point().z()); - double x2 = CGAL::to_double(v2.point().x()); - double y2 = CGAL::to_double(v2.point().y()); - double z2 = CGAL::to_double(v2.point().z()); - double x3 = CGAL::to_double(v3.point().x()); - double y3 = CGAL::to_double(v3.point().y()); - double z3 = CGAL::to_double(v3.point().z()); - ps->append_poly(); - ps->append_vertex(x1, y1, z1); - ps->append_vertex(x2, y2, z2); - ps->append_vertex(x3, y3, z3); - } while (hc != hc_end); - } - return ps; -} diff --git a/src/cgal.h b/src/cgal.h index d015559..e0e246c 100644 --- a/src/cgal.h +++ b/src/cgal.h @@ -31,73 +31,6 @@ typedef CGAL::Polyhedron_3 CGAL_Polyhedron; typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; -struct CGAL_Nef_polyhedron -{ - int dim; - CGAL_Nef_polyhedron2 p2; - CGAL_Nef_polyhedron3 p3; - - CGAL_Nef_polyhedron() { - dim = 0; - } - - CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron2 &p) { - dim = 2; - p2 = p; - } - - CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron3 &p) { - dim = 3; - p3 = p; - } - - CGAL_Nef_polyhedron& operator+=(const CGAL_Nef_polyhedron &other) { - if (other.dim == 2) { - this->p2 += other.p2; - this->dim = 2; - } - if (other.dim == 3) { - this->p3 += other.p3; - this->dim = 3; - } - return *this; - } - - CGAL_Nef_polyhedron& operator*=(const CGAL_Nef_polyhedron &other) { - if (other.dim == 2) { - this->p2 *= other.p2; - this->dim = 2; - } - if (other.dim == 3) { - this->p3 *= other.p3; - this->dim = 3; - } - return *this; - } - - CGAL_Nef_polyhedron& operator-=(const CGAL_Nef_polyhedron &other) { - if (other.dim == 2) { - this->p2 -= other.p2; - this->dim = 2; - } - if (other.dim == 3) { - this->p3 -= other.p3; - this->dim = 3; - } - return *this; - } - - int weight() { - if (dim == 2) - return p2.explorer().number_of_vertices(); - if (dim == 3) - return p3.number_of_vertices(); - return 0; - } - - class PolySet *convertToPolyset(); -}; - #endif /* ENABLE_CGAL */ #endif diff --git a/src/cgaladv.cc b/src/cgaladv.cc index 6e26713..5b2e5df 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -29,17 +29,10 @@ #include "context.h" #include "builtin.h" #include "printutils.h" -#include "cgal.h" #include "visitor.h" #include #include -#ifdef ENABLE_CGAL -extern CGAL_Nef_polyhedron3 minkowski3(CGAL_Nef_polyhedron3 a, CGAL_Nef_polyhedron3 b); -extern CGAL_Nef_polyhedron2 minkowski2(CGAL_Nef_polyhedron2 a, CGAL_Nef_polyhedron2 b); -extern CGAL_Nef_polyhedron2 convexhull2(std::list a); -#endif - enum cgaladv_type_e { MINKOWSKI, GLIDE, diff --git a/src/cgaladv_minkowski2.cc b/src/cgaladv_minkowski2.cc index b722708..2d64d16 100644 --- a/src/cgaladv_minkowski2.cc +++ b/src/cgaladv_minkowski2.cc @@ -34,7 +34,6 @@ #include -extern CGAL_Nef_polyhedron2 minkowski2(CGAL_Nef_polyhedron2 a, CGAL_Nef_polyhedron2 b); extern CGAL_Poly2 nef2p2(CGAL_Nef_polyhedron2 p); //----------------------------------------------------------------------------- @@ -120,7 +119,7 @@ static CGAL_Nef_polyhedron2 p2nef2(CGAL_Poly2 p2) { return CGAL_Nef_polyhedron2(points.begin(), points.end(), CGAL_Nef_polyhedron2::INCLUDED); } -CGAL_Nef_polyhedron2 minkowski2(CGAL_Nef_polyhedron2 a, CGAL_Nef_polyhedron2 b) +CGAL_Nef_polyhedron2 minkowski2(const CGAL_Nef_polyhedron2 &a, const CGAL_Nef_polyhedron2 &b) { CGAL_Poly2 ap = nef2p2(a), bp = nef2p2(b); diff --git a/src/cgaladv_minkowski3.cc b/src/cgaladv_minkowski3.cc deleted file mode 100644 index f12ce21..0000000 --- a/src/cgaladv_minkowski3.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* - * OpenSCAD (www.openscad.org) - * Copyright (C) 2009-2011 Clifford Wolf and - * Marius Kintel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * As a special exception, you have permission to link this program - * with the CGAL library and distribute executables, as long as you - * follow the requirements of the GNU GPL in regard to all of the - * software in the executable aside from CGAL. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifdef ENABLE_CGAL - -#include "cgal.h" -#include - -extern CGAL_Nef_polyhedron3 minkowski3(CGAL_Nef_polyhedron3 a, CGAL_Nef_polyhedron3 b); - -CGAL_Nef_polyhedron3 minkowski3(CGAL_Nef_polyhedron3 a, CGAL_Nef_polyhedron3 b) -{ - return CGAL::minkowski_sum_3(a, b); -} - -#endif diff --git a/src/cgalfwd.h b/src/cgalfwd.h new file mode 100644 index 0000000..df9b9e2 --- /dev/null +++ b/src/cgalfwd.h @@ -0,0 +1,27 @@ +#ifndef CGALFWD_H_ +#define CGALFWD_H_ + +#ifdef ENABLE_CGAL + +namespace CGAL { + class Gmpq; + template class Extended_cartesian; + class HDS_items; + template class Nef_polyhedron_2; +} +typedef CGAL::Gmpq NT; +typedef CGAL::Extended_cartesian CGAL_Kernel2; +typedef CGAL::Nef_polyhedron_2 CGAL_Nef_polyhedron2; + +namespace CGAL { + template class Cartesian; + template struct Default_items; + class SNC_indexed_items; + template class Nef_polyhedron_3; +} +typedef CGAL::Cartesian CGAL_Kernel3; +typedef CGAL::Nef_polyhedron_3 CGAL_Nef_polyhedron3; + +#endif /* ENABLE_CGAL */ + +#endif diff --git a/src/cgalrenderer.cc b/src/cgalrenderer.cc index 7a31747..aa55c57 100644 --- a/src/cgalrenderer.cc +++ b/src/cgalrenderer.cc @@ -29,17 +29,20 @@ #include "CGAL_renderer.h" #include "dxfdata.h" #include "dxftess.h" +#include "CGAL_Nef_polyhedron.h" +#include "cgal.h" #include "Preferences.h" CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) { if (root.dim == 2) { - DxfData dd(root); + DxfData *dd = root.convertToDxfData(); this->polyhedron = NULL; this->polyset = new PolySet(); this->polyset->is2d = true; - dxf_tesselate(this->polyset, &dd, 0, true, false, 0); + dxf_tesselate(this->polyset, dd, 0, true, false, 0); + delete dd; } else if (root.dim == 3) { this->polyset = NULL; @@ -54,7 +57,7 @@ CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(), Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue()); - CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(this->root.p3, this->polyhedron); + CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(*this->root.p3, this->polyhedron); this->polyhedron->init(); } } @@ -86,7 +89,7 @@ void CGALRenderer::draw(bool showfaces, bool showedges) const typedef Explorer::Face_const_iterator fci_t; typedef Explorer::Halfedge_around_face_const_circulator heafcc_t; typedef Explorer::Point Point; - Explorer E = this->root.p2.explorer(); + Explorer E = this->root.p2->explorer(); // Draw 2D edges glDisable(GL_DEPTH_TEST); diff --git a/src/cgalrenderer.h b/src/cgalrenderer.h index b3c1638..4e8039a 100644 --- a/src/cgalrenderer.h +++ b/src/cgalrenderer.h @@ -2,7 +2,7 @@ #define CGALRENDERER_H_ #include "renderer.h" -#include "cgal.h" +#include "CGAL_Nef_polyhedron.h" class CGALRenderer : public Renderer { diff --git a/src/dxfdata.h b/src/dxfdata.h index e71a740..a513edf 100644 --- a/src/dxfdata.h +++ b/src/dxfdata.h @@ -37,13 +37,9 @@ public: DxfData(); DxfData(double fn, double fs, double fa, QString filename, QString layername = QString(), double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); -#ifdef ENABLE_CGAL - DxfData(const struct CGAL_Nef_polyhedron &N); -#endif Vector2d *addPoint(double x, double y); -private: void fixup_path_direction(); }; diff --git a/src/export.cc b/src/export.cc index e46a14f..17a14c8 100644 --- a/src/export.cc +++ b/src/export.cc @@ -24,6 +24,7 @@ * */ +#include "export.h" #include "printutils.h" #include "polyset.h" #include "dxfdata.h" @@ -34,6 +35,7 @@ #include #ifdef ENABLE_CGAL +#include "CGAL_Nef_polyhedron.h" #include "cgal.h" /*! @@ -43,7 +45,7 @@ void export_stl(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialog *pd) { CGAL_Polyhedron P; - root_N->p3.convert_to_Polyhedron(P); + root_N->p3->convert_to_Polyhedron(P); typedef CGAL_Polyhedron::Vertex Vertex; typedef CGAL_Polyhedron::Vertex_const_iterator VCI; @@ -131,12 +133,12 @@ void export_dxf(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialo << " 2\n" << "ENTITIES\n"; - DxfData dd(*root_N); - for (int i=0; iconvertToDxfData(); + for (int i=0; ipaths.size(); i++) { - for (int j=1; jpaths[i].points.size(); j++) { + const Vector2d &p1 = *dd->paths[i].points[j-1]; + const Vector2d &p2 = *dd->paths[i].points[j]; double x1 = p1[0]; double y1 = p1[1]; double x2 = p2[0]; @@ -173,6 +175,7 @@ void export_dxf(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialo output << " 0\n" <<"EOF\n"; + delete dd; setlocale(LC_NUMERIC, ""); // Set default locale } diff --git a/src/export.h b/src/export.h index d35246c..0298611 100644 --- a/src/export.h +++ b/src/export.h @@ -2,9 +2,9 @@ #define EXPORT_H_ #ifdef ENABLE_CGAL -#include "cgal.h" -void cgal_nef3_to_polyset(PolySet *ps, CGAL_Nef_polyhedron *root_N); -void export_stl(class CGAL_Nef_polyhedron *root_N, class QTextStream &output, class QProgressDialog *pd); + +void cgal_nef3_to_polyset(class PolySet *ps, class CGAL_Nef_polyhedron *root_N); +void export_stl(CGAL_Nef_polyhedron *root_N, class QTextStream &output, class QProgressDialog *pd); void export_off(CGAL_Nef_polyhedron *root_N, class QTextStream &output, QProgressDialog *pd); void export_dxf(CGAL_Nef_polyhedron *root_N, class QTextStream &output, QProgressDialog *pd); #endif diff --git a/src/mainwin.cc b/src/mainwin.cc index 89d17c5..4faed34 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -46,8 +46,6 @@ #ifdef USE_PROGRESSWIDGET #include "ProgressWidget.h" #endif -#include "CGALEvaluator.h" -#include "PolySetCGALEvaluator.h" #include "ThrownTogetherRenderer.h" #include @@ -84,7 +82,11 @@ using namespace boost::lambda; #ifdef ENABLE_CGAL +#include "CGALEvaluator.h" +#include "PolySetCGALEvaluator.h" #include "cgalrenderer.h" +#include "CGAL_Nef_polyhedron.h" +#include "cgal.h" #endif // ENABLE_CGAL @@ -1232,41 +1234,41 @@ void MainWindow::actionRenderCGAL() if (this->root_N->dim == 2) { PRINTF(" Top level object is a 2D object:"); QApplication::processEvents(); - PRINTF(" Empty: %6s", this->root_N->p2.is_empty() ? "yes" : "no"); + PRINTF(" Empty: %6s", this->root_N->p2->is_empty() ? "yes" : "no"); QApplication::processEvents(); - PRINTF(" Plane: %6s", this->root_N->p2.is_plane() ? "yes" : "no"); + PRINTF(" Plane: %6s", this->root_N->p2->is_plane() ? "yes" : "no"); QApplication::processEvents(); - PRINTF(" Vertices: %6d", (int)this->root_N->p2.explorer().number_of_vertices()); + PRINTF(" Vertices: %6d", (int)this->root_N->p2->explorer().number_of_vertices()); QApplication::processEvents(); - PRINTF(" Halfedges: %6d", (int)this->root_N->p2.explorer().number_of_halfedges()); + PRINTF(" Halfedges: %6d", (int)this->root_N->p2->explorer().number_of_halfedges()); QApplication::processEvents(); - PRINTF(" Edges: %6d", (int)this->root_N->p2.explorer().number_of_edges()); + PRINTF(" Edges: %6d", (int)this->root_N->p2->explorer().number_of_edges()); QApplication::processEvents(); - PRINTF(" Faces: %6d", (int)this->root_N->p2.explorer().number_of_faces()); + PRINTF(" Faces: %6d", (int)this->root_N->p2->explorer().number_of_faces()); QApplication::processEvents(); - PRINTF(" FaceCycles: %6d", (int)this->root_N->p2.explorer().number_of_face_cycles()); + PRINTF(" FaceCycles: %6d", (int)this->root_N->p2->explorer().number_of_face_cycles()); QApplication::processEvents(); - PRINTF(" ConnComp: %6d", (int)this->root_N->p2.explorer().number_of_connected_components()); + PRINTF(" ConnComp: %6d", (int)this->root_N->p2->explorer().number_of_connected_components()); QApplication::processEvents(); } if (this->root_N->dim == 3) { PRINTF(" Top level object is a 3D object:"); - PRINTF(" Simple: %6s", this->root_N->p3.is_simple() ? "yes" : "no"); + PRINTF(" Simple: %6s", this->root_N->p3->is_simple() ? "yes" : "no"); QApplication::processEvents(); - PRINTF(" Valid: %6s", this->root_N->p3.is_valid() ? "yes" : "no"); + PRINTF(" Valid: %6s", this->root_N->p3->is_valid() ? "yes" : "no"); QApplication::processEvents(); - PRINTF(" Vertices: %6d", (int)this->root_N->p3.number_of_vertices()); + PRINTF(" Vertices: %6d", (int)this->root_N->p3->number_of_vertices()); QApplication::processEvents(); - PRINTF(" Halfedges: %6d", (int)this->root_N->p3.number_of_halfedges()); + PRINTF(" Halfedges: %6d", (int)this->root_N->p3->number_of_halfedges()); QApplication::processEvents(); - PRINTF(" Edges: %6d", (int)this->root_N->p3.number_of_edges()); + PRINTF(" Edges: %6d", (int)this->root_N->p3->number_of_edges()); QApplication::processEvents(); - PRINTF(" Halffacets: %6d", (int)this->root_N->p3.number_of_halffacets()); + PRINTF(" Halffacets: %6d", (int)this->root_N->p3->number_of_halffacets()); QApplication::processEvents(); - PRINTF(" Facets: %6d", (int)this->root_N->p3.number_of_facets()); + PRINTF(" Facets: %6d", (int)this->root_N->p3->number_of_facets()); QApplication::processEvents(); - PRINTF(" Volumes: %6d", (int)this->root_N->p3.number_of_volumes()); + PRINTF(" Volumes: %6d", (int)this->root_N->p3->number_of_volumes()); QApplication::processEvents(); } @@ -1367,7 +1369,7 @@ void MainWindow::actionExportSTLorOFF(bool) return; } - if (!this->root_N->p3.is_simple()) { + if (!this->root_N->p3->is_simple()) { PRINT("Object isn't a valid 2-manifold! Modify your design.."); clearCurrentOutput(); return; @@ -1386,7 +1388,7 @@ void MainWindow::actionExportSTLorOFF(bool) QProgressDialog *pd = new QProgressDialog( stl_mode ? "Exporting object to STL file..." : "Exporting object to OFF file...", - QString(), 0, this->root_N->p3.number_of_facets() + 1); + QString(), 0, this->root_N->p3->number_of_facets() + 1); pd->setValue(0); pd->setAutoClose(false); pd->show(); diff --git a/src/nef2dxf.cc b/src/nef2dxf.cc deleted file mode 100644 index cbefa9c..0000000 --- a/src/nef2dxf.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* - * OpenSCAD (www.openscad.org) - * Copyright (C) 2009-2011 Clifford Wolf and - * Marius Kintel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * As a special exception, you have permission to link this program - * with the CGAL library and distribute executables, as long as you - * follow the requirements of the GNU GPL in regard to all of the - * software in the executable aside from CGAL. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "dxfdata.h" -#include "grid.h" -#include "cgal.h" - -#ifdef ENABLE_CGAL - -DxfData::DxfData(const struct CGAL_Nef_polyhedron &N) -{ - assert(N.dim == 2); - Grid2d grid(GRID_COARSE); - - typedef CGAL_Nef_polyhedron2::Explorer Explorer; - typedef Explorer::Face_const_iterator fci_t; - typedef Explorer::Halfedge_around_face_const_circulator heafcc_t; - Explorer E = N.p2.explorer(); - - for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit) - { - heafcc_t fcirc(E.halfedge(fit)), fend(fcirc); - int first_point = -1, last_point = -1; - CGAL_For_all(fcirc, fend) { - if (E.is_standard(E.target(fcirc))) { - Explorer::Point ep = E.point(E.target(fcirc)); - double x = to_double(ep.x()), y = to_double(ep.y()); - int this_point = -1; - if (grid.has(x, y)) { - this_point = grid.align(x, y); - } else { - this_point = grid.align(x, y) = points.size(); - points.append(Vector2d(x, y)); - } - if (first_point < 0) { - paths.append(Path()); - first_point = this_point; - } - if (this_point != last_point) { - paths.last().points.append(&points[this_point]); - last_point = this_point; - } - } - } - if (first_point >= 0) { - paths.last().is_closed = 1; - paths.last().points.append(&points[first_point]); - } - } - - fixup_path_direction(); -} - -#endif // ENABLE_CGAL diff --git a/src/openscad.cc b/src/openscad.cc index a948c5a..a13528e 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -41,7 +41,7 @@ #include #ifdef ENABLE_CGAL -#include "cgal.h" +#include "CGAL_Nef_polyhedron.h" #include #endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ae5c496..088871c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -139,9 +139,10 @@ include_directories(${CGAL_INCLUDE_DIRS}) # # cgaltest # -add_executable(cgaltest cgaltest.cc ../src/cgal.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc - ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/nef2dxf.cc - ../src/cgaladv_minkowski2.cc ../src/cgaladv_minkowski3.cc ${COMMON_SOURCES}) +add_executable(cgaltest cgaltest.cc ../src/CGAL_Nef_polyhedron.cc ../src/CSGTermEvaluator.cc + ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc + ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc + ${COMMON_SOURCES}) set_target_properties(cgaltest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARY}) @@ -149,9 +150,10 @@ target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_ # opencsgtest # add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm - ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/CSGTermEvaluator.cc ../src/cgal.cc ../src/CGALEvaluator.cc - ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/nef2dxf.cc - ../src/cgaladv_minkowski2.cc ../src/cgaladv_minkowski3.cc + ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc + ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc + ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc + ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ${COMMON_SOURCES}) set_target_properties(opencsgtest PROPERTIES COMPILE_FLAGS "-DENABLE_OPENCSG -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") target_link_libraries(opencsgtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENCSG_LIBRARY} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY}) diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc index df03a43..9d4ef5d 100644 --- a/tests/cgaltest.cc +++ b/tests/cgaltest.cc @@ -32,6 +32,7 @@ #include "export.h" #include "builtin.h" #include "Tree.h" +#include "CGAL_Nef_polyhedron.h" #include "CGALEvaluator.h" #include "PolySetCGALEvaluator.h" @@ -42,6 +43,7 @@ #include #include #include +#include QString commandline_commands; const char *make_command = NULL; -- cgit v0.10.1 From 44496b2816d147fc19211dc854c6823db09d1bc7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 04:38:35 +0200 Subject: sync diff --git a/doc/TODO.txt b/doc/TODO.txt index dd9932c..8913465 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -39,7 +39,6 @@ Using STL-imported models is tricky and triggers multiple issues: CRASH BUGS ---------- o Broken polyhedron() entities are not correctly detected and cause CGAL segfaults -o linear_extrude(50) square([5,0]); o union() { linear_extrude(height=10, twist=90) circle(5); translate([7,-5,0]) linear_extrude(height=10, twist=180) polygon(points = [[0,0], [10,0], [5,10]]); @@ -78,9 +77,11 @@ o 3D View - overlay indicator displaying current view mode - OpenCSG rendering: Coincident surfaces causes z-buffer fighting. Is this somehow avoidable tuning the depth tests in OpenCSG? - - Make the 10.000 element OpenCSG klimit configurable (Preferences) ? + - Make the 10.000 element OpenCSG limit configurable (Preferences) ? - Use OpenGL picking to facilitate ray-tracing like features like measuring thicknesses, distances, slot thicknesses etc. + - When specifying a transparency with the color() statement, + the object is not sorted and will be rendered wrongly o Editor wishlist - More infrastructure for external editor (allow communication from the outside) - Preferences GUI for the features below @@ -141,10 +142,6 @@ o Function-Module-Interface - Pass a module instanciation to a function (e.g. for a volume() function) - Pass a function to a module instanciation (e.g. for dynamic extrusion paths) o Language Frontend - - include statement doesn't support nesting. This can be fixed by - keeping a nested stack of current input files in the lexer. See - the "Flex & Bison" O'Reilly book, "Start States and Nested Input - Files", page 28, for an example. - Allow local variables and functions everywhere (not only on module level) - allow any expression to be evaluated as boolean (!0 = true, 0 = false) - Rethink for vs. intersection_for vs. group. Should for loops @@ -163,8 +160,6 @@ o Mesh optimization on STL export - Remove super small triangles (all sides are short) - Replace super thin triangles (one h is short) o Misc - - When specifying a transparency with the color() statement, - the object is not sorted and will be rendered wrongly - Go through default values of parameters (e.g. cube() has x,y,z=1 while linear_extrude() has height=100) - Add support for symbolic names to child() statement - Add 'lines' object type for non-solid 2d drawings @@ -223,11 +218,6 @@ o Caching and MDI looks suspicious when the code relies on external resources which might be loaded from difference locations in different documents -> we might get a false cache hit o Are contructs like "child(0)" cached? Could this give false cache hits? -o Write some cmd-line apps that dump an openscad file to misc. formats - (dump, stl, dxf) -o Write a simple test script that collects verified and current STL renderings - and displays them side-by-side or smth. -o Write simple driver scripts for comparing output of above command o Collect "all" available OpenSCAD scripts from the internets and run the integration tests on them all o dumptest tests: -- cgit v0.10.1 From 6392776e4e9452033b13bf0dc2f6f44f5ed7eb06 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 05:04:42 +0200 Subject: Initial implementation of cgalpngtest diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 088871c..533517a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -147,6 +147,18 @@ set_target_properties(cgaltest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CX target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARY}) # +# cgalpngtest +# +add_executable(cgalpngtest cgalpngtest.cc OffscreenView.cc OffscreenContext.mm + ../src/CGALRenderer.cc ../src/CGAL_Nef_polyhedron.cc + ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc + ../src/PolySetCGALEvaluator.cc ../src/qhash.cc + ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc + ${COMMON_SOURCES}) +set_target_properties(cgalpngtest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") +target_link_libraries(cgalpngtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY}) + +# # opencsgtest # add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm @@ -186,9 +198,12 @@ add_cmdline_test(csgtexttest txt ${MINIMAL_FILES}) add_cmdline_test(csgtermtest txt ${MINIMAL_FILES}) # Add cgaltest tests to CTest +add_cmdline_test(cgaltest stl ${CGALTEST_FILES}) + +# Add cgalpngtest tests to CTest LIST(APPEND CGALTEST_FILES ${FEATURES_FILES}) LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) -add_cmdline_test(cgaltest stl ${CGALTEST_FILES}) +add_cmdline_test(cgaltest stl ${CGALPNGTEST_FILES}) # Add opencsg tests to CTest LIST(APPEND OPENCSGTEST_FILES ${CGALTEST_FILES}) diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc new file mode 100644 index 0000000..e864090 --- /dev/null +++ b/tests/cgalpngtest.cc @@ -0,0 +1,224 @@ +/* + * OpenSCAD (www.openscad.at) + * Copyright (C) 2009 Clifford Wolf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * As a special exception, you have permission to link this program + * with the CGAL library and distribute executables, as long as you + * follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from CGAL. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "myqhash.h" +#include "openscad.h" +#include "node.h" +#include "module.h" +#include "polyset.h" +#include "context.h" +#include "value.h" +#include "export.h" +#include "builtin.h" +#include "Tree.h" +#include "CGAL_Nef_polyhedron.h" +#include "CGALEvaluator.h" +#include "PolySetCGALEvaluator.h" +#include "CGALRenderer.h" +#include "OffscreenView.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QString commandline_commands; +const char *make_command = NULL; +QSet dependencies; +QString currentdir; +QString examplesdir; +QString librarydir; + +using std::string; + +void handle_dep(QString filename) +{ + if (filename.startsWith("/")) + dependencies.insert(filename); + else + dependencies.insert(QDir::currentPath() + QString("/") + filename); + if (!QFile(filename).exists() && make_command) { + char buffer[4096]; + snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); + system(buffer); // FIXME: Handle error + } +} + +// FIXME: enforce some maximum cache size (old version had 100K vertices as limit) +QHash cache; + +void cgalTree(Tree &tree) +{ + assert(tree.root()); + + CGALEvaluator evaluator(cache, tree); + Traverser evaluate(evaluator, *tree.root(), Traverser::PRE_AND_POSTFIX); + evaluate.execute(); +} + +struct CsgInfo +{ + OffscreenView *glview; +}; + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + const char *filename = argv[1]; + + initialize_builtin_functions(); + initialize_builtin_modules(); + + QApplication app(argc, argv, false); + QDir original_path = QDir::current(); + + currentdir = QDir::currentPath(); + + QDir libdir(QApplication::instance()->applicationDirPath()); +#ifdef Q_WS_MAC + libdir.cd("../Resources"); // Libraries can be bundled + if (!libdir.exists("libraries")) libdir.cd("../../.."); +#elif defined(Q_OS_UNIX) + if (libdir.cd("../share/openscad/libraries")) { + librarydir = libdir.path(); + } else + if (libdir.cd("../../share/openscad/libraries")) { + librarydir = libdir.path(); + } else + if (libdir.cd("../../libraries")) { + librarydir = libdir.path(); + } else +#endif + if (libdir.cd("libraries")) { + librarydir = libdir.path(); + } + + Context root_ctx; + root_ctx.functions_p = &builtin_functions; + root_ctx.modules_p = &builtin_modules; + root_ctx.set_variable("$fn", Value(0.0)); + root_ctx.set_variable("$fs", Value(1.0)); + root_ctx.set_variable("$fa", Value(12.0)); + root_ctx.set_variable("$t", Value(0.0)); + + Value zero3; + zero3.type = Value::VECTOR; + zero3.append(new Value(0.0)); + zero3.append(new Value(0.0)); + zero3.append(new Value(0.0)); + root_ctx.set_variable("$vpt", zero3); + root_ctx.set_variable("$vpr", zero3); + + + AbstractModule *root_module; + ModuleInstantiation root_inst; + AbstractNode *root_node; + + QFileInfo fileInfo(filename); + handle_dep(filename); + FILE *fp = fopen(filename, "rt"); + if (!fp) { + fprintf(stderr, "Can't open input file `%s'!\n", filename); + exit(1); + } else { + QString text; + char buffer[513]; + int ret; + while ((ret = fread(buffer, 1, 512, fp)) > 0) { + buffer[ret] = 0; + text += buffer; + } + fclose(fp); + root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + if (!root_module) { + exit(1); + } + } + + QDir::setCurrent(fileInfo.absolutePath()); + + AbstractNode::resetIndexCounter(); + root_node = root_module->evaluate(&root_ctx, &root_inst); + + Tree tree(root_node); + + CsgInfo csgInfo; + QHash cache; + CGALEvaluator cgalevaluator(cache, tree); + PolySetCGALEvaluator psevaluator(cgalevaluator); + + CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node); + + QDir::setCurrent(original_path.absolutePath()); + + csgInfo.glview = new OffscreenView(512,512); +// FIXME: Get bbox from CGAL mesh BoundingBox bbox = csgInfo.root_chain->getBoundingBox(); + BoundingBox bbox; + + Vector3d center = (bbox.min() + bbox.max()) / 2; + double radius = (bbox.max() - bbox.min()).norm() / 2; + + + Vector3d cameradir(1, 1, -0.5); + Vector3d camerapos = center - radius*1.5*cameradir; + csgInfo.glview->setCamera(camerapos, center); + + glewInit(); +#ifdef DEBUG + cout << "GLEW version " << glewGetString(GLEW_VERSION) << "\n"; + cout << (const char *)glGetString(GL_RENDERER) << "(" << (const char *)glGetString(GL_VENDOR) << ")\n" + << "OpenGL version " << (const char *)glGetString(GL_VERSION) << "\n"; + cout << "Extensions: " << (const char *)glGetString(GL_EXTENSIONS) << "\n"; + + + if (GLEW_ARB_framebuffer_object) { + cout << "ARB_FBO supported\n"; + } + if (GLEW_EXT_framebuffer_object) { + cout << "EXT_FBO supported\n"; + } + if (GLEW_EXT_packed_depth_stencil) { + cout << "EXT_packed_depth_stencil\n"; + } +#endif + + CGALRenderer cgalRenderer(N); + csgInfo.glview->setRenderer(&cgalRenderer); + csgInfo.glview->paintGL(); + csgInfo.glview->save("/dev/stdout"); + + destroy_builtin_functions(); + destroy_builtin_modules(); + + return 0; +} -- cgit v0.10.1 From e87ba3ada1a2dbd94a60058c663c48b9e0f681c0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 05:05:09 +0200 Subject: Removed old cruft diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index 85d09c4..8af64e3 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -11,9 +11,6 @@ #include #include -extern CGAL_Nef_polyhedron3 minkowski3(CGAL_Nef_polyhedron3 a, CGAL_Nef_polyhedron3 b); -extern CGAL_Nef_polyhedron2 minkowski2(CGAL_Nef_polyhedron2 a, CGAL_Nef_polyhedron2 b); - using std::string; using std::map; using std::list; -- cgit v0.10.1 From 24d81b5732c178998f640e86b336196272f31bc5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 05:05:35 +0200 Subject: Temporarily disabled Preferences handling in CGALRenderer to allow for cmd-line operation diff --git a/src/cgalrenderer.cc b/src/cgalrenderer.cc index aa55c57..352c03c 100644 --- a/src/cgalrenderer.cc +++ b/src/cgalrenderer.cc @@ -32,7 +32,7 @@ #include "CGAL_Nef_polyhedron.h" #include "cgal.h" -#include "Preferences.h" +//#include "Preferences.h" CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) { @@ -48,14 +48,14 @@ CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) this->polyset = NULL; this->polyhedron = new Polyhedron(); // FIXME: Make independent of Preferences - this->polyhedron->setColor(Polyhedron::CGAL_NEF3_MARKED_FACET_COLOR, - Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).red(), - Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).green(), - Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).blue()); - this->polyhedron->setColor(Polyhedron::CGAL_NEF3_UNMARKED_FACET_COLOR, - Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).red(), - Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(), - Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue()); + // this->polyhedron->setColor(Polyhedron::CGAL_NEF3_MARKED_FACET_COLOR, + // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).red(), + // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).green(), + // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).blue()); + // this->polyhedron->setColor(Polyhedron::CGAL_NEF3_UNMARKED_FACET_COLOR, + // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).red(), + // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(), + // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue()); CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(*this->root.p3, this->polyhedron); this->polyhedron->init(); @@ -73,7 +73,8 @@ void CGALRenderer::draw(bool showfaces, bool showedges) const if (this->root.dim == 2) { // Draw 2D polygons glDisable(GL_LIGHTING); - const QColor &col = Preferences::inst()->color(Preferences::CGAL_FACE_2D_COLOR); +// FIXME: const QColor &col = Preferences::inst()->color(Preferences::CGAL_FACE_2D_COLOR); + const QColor &col = QColor(0x00, 0xbf, 0x99); glColor3f(col.redF(), col.greenF(), col.blueF()); for (int i=0; i < this->polyset->polygons.size(); i++) { @@ -95,7 +96,8 @@ void CGALRenderer::draw(bool showfaces, bool showedges) const glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glLineWidth(2); - const QColor &col2 = Preferences::inst()->color(Preferences::CGAL_EDGE_2D_COLOR); +// FIXME: const QColor &col2 = Preferences::inst()->color(Preferences::CGAL_EDGE_2D_COLOR); + const QColor &col2 = QColor(0xff, 0x00, 0x00); glColor3f(col2.redF(), col2.greenF(), col2.blueF()); // Extract the boundary, including inner boundaries of the polygons -- cgit v0.10.1 From fee63ab7aec661ea3fe5890e79df752f1af10690 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 17:02:50 +0200 Subject: added bbox calculation diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc index e864090..2680752 100644 --- a/tests/cgalpngtest.cc +++ b/tests/cgalpngtest.cc @@ -36,7 +36,9 @@ #include "CGAL_Nef_polyhedron.h" #include "CGALEvaluator.h" #include "PolySetCGALEvaluator.h" -#include "CGALRenderer.h" +#include "cgalrenderer.h" +#include "CGAL_renderer.h" +#include "cgal.h" #include "OffscreenView.h" #include @@ -182,16 +184,6 @@ int main(int argc, char **argv) QDir::setCurrent(original_path.absolutePath()); csgInfo.glview = new OffscreenView(512,512); -// FIXME: Get bbox from CGAL mesh BoundingBox bbox = csgInfo.root_chain->getBoundingBox(); - BoundingBox bbox; - - Vector3d center = (bbox.min() + bbox.max()) / 2; - double radius = (bbox.max() - bbox.min()).norm() / 2; - - - Vector3d cameradir(1, 1, -0.5); - Vector3d camerapos = center - radius*1.5*cameradir; - csgInfo.glview->setCamera(camerapos, center); glewInit(); #ifdef DEBUG @@ -213,6 +205,22 @@ int main(int argc, char **argv) #endif CGALRenderer cgalRenderer(N); + + BoundingBox bbox; + if (cgalRenderer.polyhedron) { + CGAL::Bbox_3 cgalbbox = cgalRenderer.polyhedron->bbox(); + bbox = BoundingBox(Vector3d(cgalbbox.xmin(), cgalbbox.ymin(), cgalbbox.zmin()), + Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax())); + } + Vector3d center = (bbox.min() + bbox.max()) / 2; + double radius = (bbox.max() - bbox.min()).norm() / 2; + + + Vector3d cameradir(1, 1, -0.5); + Vector3d camerapos = center - radius*1.5*cameradir; + csgInfo.glview->setCamera(camerapos, center); + + csgInfo.glview->setRenderer(&cgalRenderer); csgInfo.glview->paintGL(); csgInfo.glview->save("/dev/stdout"); -- cgit v0.10.1 From 6041c34f0b458b3cb791a0e15b0f01bf3142981c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 17:03:34 +0200 Subject: Refactored some non-CGAL functionality into separate functions in PolySetCGALEvaluator diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index c67e1f5..31e5bcf 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -182,7 +182,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) PolySet ps; ps.is2d = true; - dxf_tesselate(&ps, dd, 0, true, false, 0); + dxf_tesselate(&ps, *dd, 0, true, false, 0); N = evaluateCGALMesh(ps); ps.refcount = 0; diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 451929c..b3cc88e 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -263,7 +263,7 @@ CSGTerm *AbstractNode::evaluate_csg_term_from_nef(double m[20], QVectoris2d = true; - dxf_tesselate(ps, &dd, 0, true, false, 0); + dxf_tesselate(ps, dd, 0, true, false, 0); dxf_border_to_ps(ps, &dd); } diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 7e7e528..f556bcb 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -148,7 +148,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr (*np.p2) += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); } DxfData *dxf = np.convertToDxfData(); - dxf_tesselate(ps, dxf, 0, true, false, 0); + dxf_tesselate(ps, *dxf, 0, true, false, 0); dxf_border_to_ps(ps, dxf); ps3->unlink(); delete dxf; @@ -160,23 +160,23 @@ cant_project_non_simple_polyhedron: return ps; } -static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, double h1, double h2) +static void add_slice(PolySet *ps, DxfData::Path &pt, double rot1, double rot2, double h1, double h2) { - for (int j = 1; j < pt->points.count(); j++) + for (int j = 1; j < pt.points.count(); j++) { int k = j - 1; - double jx1 = (*pt->points[j])[0] * cos(rot1*M_PI/180) + (*pt->points[j])[1] * sin(rot1*M_PI/180); - double jy1 = (*pt->points[j])[0] * -sin(rot1*M_PI/180) + (*pt->points[j])[1] * cos(rot1*M_PI/180); + double jx1 = (*pt.points[j])[0] * cos(rot1*M_PI/180) + (*pt.points[j])[1] * sin(rot1*M_PI/180); + double jy1 = (*pt.points[j])[0] * -sin(rot1*M_PI/180) + (*pt.points[j])[1] * cos(rot1*M_PI/180); - double jx2 = (*pt->points[j])[0] * cos(rot2*M_PI/180) + (*pt->points[j])[1] * sin(rot2*M_PI/180); - double jy2 = (*pt->points[j])[0] * -sin(rot2*M_PI/180) + (*pt->points[j])[1] * cos(rot2*M_PI/180); + double jx2 = (*pt.points[j])[0] * cos(rot2*M_PI/180) + (*pt.points[j])[1] * sin(rot2*M_PI/180); + double jy2 = (*pt.points[j])[0] * -sin(rot2*M_PI/180) + (*pt.points[j])[1] * cos(rot2*M_PI/180); - double kx1 = (*pt->points[k])[0] * cos(rot1*M_PI/180) + (*pt->points[k])[1] * sin(rot1*M_PI/180); - double ky1 = (*pt->points[k])[0] * -sin(rot1*M_PI/180) + (*pt->points[k])[1] * cos(rot1*M_PI/180); + double kx1 = (*pt.points[k])[0] * cos(rot1*M_PI/180) + (*pt.points[k])[1] * sin(rot1*M_PI/180); + double ky1 = (*pt.points[k])[0] * -sin(rot1*M_PI/180) + (*pt.points[k])[1] * cos(rot1*M_PI/180); - double kx2 = (*pt->points[k])[0] * cos(rot2*M_PI/180) + (*pt->points[k])[1] * sin(rot2*M_PI/180); - double ky2 = (*pt->points[k])[0] * -sin(rot2*M_PI/180) + (*pt->points[k])[1] * cos(rot2*M_PI/180); + double kx2 = (*pt.points[k])[0] * cos(rot2*M_PI/180) + (*pt.points[k])[1] * sin(rot2*M_PI/180); + double ky2 = (*pt.points[k])[0] * -sin(rot2*M_PI/180) + (*pt.points[k])[1] * cos(rot2*M_PI/180); double dia1_len_sq = (jy1-ky2)*(jy1-ky2) + (jx1-kx2)*(jx1-kx2); double dia2_len_sq = (jy2-ky1)*(jy2-ky1) + (jx2-kx1)*(jx2-kx1); @@ -184,7 +184,7 @@ static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, if (dia1_len_sq > dia2_len_sq) { ps->append_poly(); - if (pt->is_inner) { + if (pt.is_inner) { ps->append_vertex(kx1, ky1, h1); ps->append_vertex(jx1, jy1, h1); ps->append_vertex(jx2, jy2, h2); @@ -195,7 +195,7 @@ static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, } ps->append_poly(); - if (pt->is_inner) { + if (pt.is_inner) { ps->append_vertex(kx2, ky2, h2); ps->append_vertex(kx1, ky1, h1); ps->append_vertex(jx2, jy2, h2); @@ -208,7 +208,7 @@ static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, else { ps->append_poly(); - if (pt->is_inner) { + if (pt.is_inner) { ps->append_vertex(kx1, ky1, h1); ps->append_vertex(jx1, jy1, h1); ps->append_vertex(kx2, ky2, h2); @@ -219,7 +219,7 @@ static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, } ps->append_poly(); - if (pt->is_inner) { + if (pt.is_inner) { ps->append_vertex(jx2, jy2, h2); ps->append_vertex(kx2, ky2, h2); ps->append_vertex(jx1, jy1, h1); @@ -232,7 +232,8 @@ static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, } } -PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, AbstractPolyNode::render_mode_e) +PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, + AbstractPolyNode::render_mode_e) { const string &cacheid = this->cgalevaluator.getTree().getString(node); if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps->link(); @@ -255,6 +256,14 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } + PolySet *ps = extrudeDxfData(node, *dxf); + this->cache.insert(cacheid, new cache_entry(ps->link())); + delete dxf; + return ps; +} + +PolySet *PolySetCGALEvaluator::extrudeDxfData(const DxfLinearExtrudeNode &node, DxfData &dxf) +{ PolySet *ps = new PolySet(); ps->convexity = node.convexity; @@ -269,9 +278,9 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, } bool first_open_path = true; - for (int i = 0; i < dxf->paths.count(); i++) + for (int i = 0; i < dxf.paths.count(); i++) { - if (dxf->paths[i].is_closed) + if (dxf.paths[i].is_closed) continue; if (first_open_path) { PRINTF("WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):", @@ -279,10 +288,10 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, first_open_path = false; } PRINTF(" %9.5f %10.5f ... %10.5f %10.5f", - (*dxf->paths[i].points.first())[0] / node.scale + node.origin_x, - (*dxf->paths[i].points.first())[1] / node.scale + node.origin_y, - (*dxf->paths[i].points.last())[0] / node.scale + node.origin_x, - (*dxf->paths[i].points.last())[1] / node.scale + node.origin_y); + (*dxf.paths[i].points.first())[0] / node.scale + node.origin_x, + (*dxf.paths[i].points.first())[1] / node.scale + node.origin_y, + (*dxf.paths[i].points.last())[0] / node.scale + node.origin_x, + (*dxf.paths[i].points.last())[1] / node.scale + node.origin_y); } @@ -296,11 +305,11 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, double t2 = node.twist*(j+1) / node.slices; double g1 = h1 + (h2-h1)*j / node.slices; double g2 = h1 + (h2-h1)*(j+1) / node.slices; - for (int i = 0; i < dxf->paths.count(); i++) + for (int i = 0; i < dxf.paths.count(); i++) { - if (!dxf->paths[i].is_closed) + if (!dxf.paths[i].is_closed) continue; - add_slice(ps, &dxf->paths[i], t1, t2, g1, g2); + add_slice(ps, dxf.paths[i], t1, t2, g1, g2); } } } @@ -308,22 +317,19 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, { dxf_tesselate(ps, dxf, 0, false, true, h1); dxf_tesselate(ps, dxf, 0, true, true, h2); - for (int i = 0; i < dxf->paths.count(); i++) + for (int i = 0; i < dxf.paths.count(); i++) { - if (!dxf->paths[i].is_closed) + if (!dxf.paths[i].is_closed) continue; - add_slice(ps, &dxf->paths[i], 0, 0, h1, h2); + add_slice(ps, dxf.paths[i], 0, 0, h1, h2); } } - delete dxf; - - this->cache.insert(cacheid, new cache_entry(ps->link())); return ps; } PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, - AbstractPolyNode::render_mode_e) + AbstractPolyNode::render_mode_e) { const string &cacheid = this->cgalevaluator.getTree().getString(node); if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps->link(); @@ -346,14 +352,22 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } + PolySet *ps = rotateDxfData(node, *dxf); + this->cache.insert(cacheid, new cache_entry(ps->link())); + delete dxf; + return ps; +} + +PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, DxfData &dxf) +{ PolySet *ps = new PolySet(); ps->convexity = node.convexity; - for (int i = 0; i < dxf->paths.count(); i++) + for (int i = 0; i < dxf.paths.count(); i++) { double max_x = 0; - for (int j = 0; j < dxf->paths[i].points.count(); j++) { - max_x = fmax(max_x, (*dxf->paths[i].points[j])[0]); + for (int j = 0; j < dxf.paths[i].points.count(); j++) { + max_x = fmax(max_x, (*dxf.paths[i].points[j])[0]); } int fragments = get_fragments_from_r(max_x, node.fn, node.fs, node.fa); @@ -361,29 +375,29 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, double ***points; points = new double**[fragments]; for (int j=0; j < fragments; j++) { - points[j] = new double*[dxf->paths[i].points.count()]; - for (int k=0; k < dxf->paths[i].points.count(); k++) + points[j] = new double*[dxf.paths[i].points.count()]; + for (int k=0; k < dxf.paths[i].points.count(); k++) points[j][k] = new double[3]; } for (int j = 0; j < fragments; j++) { double a = (j*2*M_PI) / fragments; - for (int k = 0; k < dxf->paths[i].points.count(); k++) { - if ((*dxf->paths[i].points[k])[0] == 0) { + for (int k = 0; k < dxf.paths[i].points.count(); k++) { + if ((*dxf.paths[i].points[k])[0] == 0) { points[j][k][0] = 0; points[j][k][1] = 0; } else { - points[j][k][0] = (*dxf->paths[i].points[k])[0] * sin(a); - points[j][k][1] = (*dxf->paths[i].points[k])[0] * cos(a); + points[j][k][0] = (*dxf.paths[i].points[k])[0] * sin(a); + points[j][k][1] = (*dxf.paths[i].points[k])[0] * cos(a); } - points[j][k][2] = (*dxf->paths[i].points[k])[1]; + points[j][k][2] = (*dxf.paths[i].points[k])[1]; } } for (int j = 0; j < fragments; j++) { int j1 = j + 1 < fragments ? j + 1 : 0; - for (int k = 0; k < dxf->paths[i].points.count(); k++) { - int k1 = k + 1 < dxf->paths[i].points.count() ? k + 1 : 0; + for (int k = 0; k < dxf.paths[i].points.count(); k++) { + int k1 = k + 1 < dxf.paths[i].points.count() ? k + 1 : 0; if (points[j][k][0] != points[j1][k][0] || points[j][k][1] != points[j1][k][1] || points[j][k][2] != points[j1][k][2]) { @@ -410,15 +424,12 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, } for (int j=0; j < fragments; j++) { - for (int k=0; k < dxf->paths[i].points.count(); k++) + for (int k=0; k < dxf.paths[i].points.count(); k++) delete[] points[j][k]; delete[] points[j]; } delete[] points; } - delete dxf; - - this->cache.insert(cacheid, new cache_entry(ps->link())); return ps; } diff --git a/src/PolySetCGALEvaluator.h b/src/PolySetCGALEvaluator.h index 5089e0e..a39e4ff 100644 --- a/src/PolySetCGALEvaluator.h +++ b/src/PolySetCGALEvaluator.h @@ -17,7 +17,10 @@ public: virtual PolySet *evaluatePolySet(const DxfLinearExtrudeNode &node, AbstractPolyNode::render_mode_e); virtual PolySet *evaluatePolySet(const DxfRotateExtrudeNode &node, AbstractPolyNode::render_mode_e); -private: +protected: + PolySet *extrudeDxfData(const DxfLinearExtrudeNode &node, class DxfData &dxf); + PolySet *rotateDxfData(const DxfRotateExtrudeNode &node, class DxfData &dxf); + CGALEvaluator &cgalevaluator; }; diff --git a/src/cgalrenderer.cc b/src/cgalrenderer.cc index 352c03c..da5d859 100644 --- a/src/cgalrenderer.cc +++ b/src/cgalrenderer.cc @@ -41,7 +41,7 @@ CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) this->polyhedron = NULL; this->polyset = new PolySet(); this->polyset->is2d = true; - dxf_tesselate(this->polyset, dd, 0, true, false, 0); + dxf_tesselate(this->polyset, *dd, 0, true, false, 0); delete dd; } else if (root.dim == 3) { diff --git a/src/cgalrenderer.h b/src/cgalrenderer.h index 4e8039a..5f854ea 100644 --- a/src/cgalrenderer.h +++ b/src/cgalrenderer.h @@ -11,7 +11,7 @@ public: ~CGALRenderer(); void draw(bool showfaces, bool showedges) const; -private: +public: const CGAL_Nef_polyhedron &root; class Polyhedron *polyhedron; class PolySet *polyset; diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc index 754d161..825132f 100644 --- a/src/dxftess-cgal.cc +++ b/src/dxftess-cgal.cc @@ -93,7 +93,7 @@ void mark_inner_outer(QList &tri, Grid2d &point_i } } -void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool /* do_triangle_splitting */, double h) +void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool /* do_triangle_splitting */, double h) { CDT cdt; @@ -106,17 +106,17 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool /* do_tr try { // read path data and copy all relevant infos - for (int i = 0; i < dxf->paths.count(); i++) + for (int i = 0; i < dxf.paths.count(); i++) { - if (!dxf->paths[i].is_closed) + if (!dxf.paths[i].is_closed) continue; Vertex_handle first, prev; struct point_info_t *first_pi = NULL, *prev_pi = NULL; - for (int j = 1; j < dxf->paths[i].points.count(); j++) + for (int j = 1; j < dxf.paths[i].points.count(); j++) { - double x = (*dxf->paths[i].points[j])[0]; - double y = (*dxf->paths[i].points[j])[1]; + double x = (*dxf.paths[i].points[j])[0]; + double y = (*dxf.paths[i].points[j])[1]; if (point_info.has(x, y)) { // FIXME: How can the same path set contain the same point twice? @@ -127,7 +127,7 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool /* do_tr } struct point_info_t *pi = &point_info.align(x, y); - *pi = point_info_t(x, y, i, j, dxf->paths[i].points.count()-1); + *pi = point_info_t(x, y, i, j, dxf.paths[i].points.count()-1); Vertex_handle vh = cdt.insert(CDTPoint(x, y)); if (first_pi == NULL) { @@ -306,17 +306,17 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool /* do_tr } if (path[0] == path[1] && point[0] == 1 && point[1] == 2) - dxf->paths[path[0]].is_inner = up; + dxf.paths[path[0]].is_inner = up; if (path[0] == path[1] && point[0] == 2 && point[1] == 1) - dxf->paths[path[0]].is_inner = !up; + dxf.paths[path[0]].is_inner = !up; if (path[1] == path[2] && point[1] == 1 && point[2] == 2) - dxf->paths[path[1]].is_inner = up; + dxf.paths[path[1]].is_inner = up; if (path[1] == path[2] && point[1] == 2 && point[2] == 1) - dxf->paths[path[1]].is_inner = !up; + dxf.paths[path[1]].is_inner = !up; if (path[2] == path[0] && point[2] == 1 && point[0] == 2) - dxf->paths[path[2]].is_inner = up; + dxf.paths[path[2]].is_inner = up; if (path[2] == path[0] && point[2] == 2 && point[0] == 1) - dxf->paths[path[2]].is_inner = !up; + dxf.paths[path[2]].is_inner = !up; } } diff --git a/src/dxftess.h b/src/dxftess.h index 19fca7d..4aa47c2 100644 --- a/src/dxftess.h +++ b/src/dxftess.h @@ -3,7 +3,7 @@ class DxfData; class PolySet; -void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_triangle_splitting, double h); +void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_triangle_splitting, double h); void dxf_border_to_ps(PolySet *ps, DxfData *dxf); #endif diff --git a/src/import.cc b/src/import.cc index 7435d4d..737ab31 100644 --- a/src/import.cc +++ b/src/import.cc @@ -198,7 +198,7 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c { DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale); p->is2d = true; - dxf_tesselate(p, &dd, 0, true, false, 0); + dxf_tesselate(p, dd, 0, true, false, 0); dxf_border_to_ps(p, &dd); } diff --git a/src/openscad.cc b/src/openscad.cc index a13528e..5ec0659 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -33,8 +33,6 @@ #include "export.h" #include "builtin.h" #include "nodedumper.h" -#include "CGALEvaluator.h" -#include "PolySetCGALEvaluator.h" #include "printutils.h" #include @@ -43,6 +41,8 @@ #ifdef ENABLE_CGAL #include "CGAL_Nef_polyhedron.h" #include +#include "CGALEvaluator.h" +#include "PolySetCGALEvaluator.h" #endif #include @@ -259,10 +259,12 @@ int main(int argc, char **argv) NodeCache nodecache; NodeDumper dumper(nodecache); Tree tree; +#ifdef ENABLE_CGAL // FIXME: enforce some maximum cache size (old version had 100K vertices as limit) QHash cache; CGALEvaluator cgalevaluator(cache, tree); PolySetCGALEvaluator psevaluator(cgalevaluator); +#endif if (stl_output_file || off_output_file || dxf_output_file) { diff --git a/src/primitives.cc b/src/primitives.cc index 4210e15..5502192 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -559,7 +559,7 @@ sphere_next_r2: p->is2d = true; p->convexity = convexity; - dxf_tesselate(p, &dd, 0, true, false, 0); + dxf_tesselate(p, dd, 0, true, false, 0); dxf_border_to_ps(p, &dd); } -- cgit v0.10.1 From c5758fbbfc13f3cf098bc74acdd1154bcab55cb7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 20:03:35 +0200 Subject: bugfixes after refactoring diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 31e5bcf..4bc5fc2 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -46,6 +46,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr if (target.dim != 2 && target.dim != 3) { assert(false && "Dimension of Nef polyhedron must be 2 or 3"); } + assert(target.dim == src.dim); switch (op) { case CGE_UNION: @@ -58,7 +59,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr target -= src; break; case CGE_MINKOWSKI: - target = target.minkowski(src); + target.minkowski(src); break; case CGE_HULL: //FIXME: Port convex hull to a binary operator or process it all in the end somehow @@ -87,7 +88,7 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg if (chnode->modinst->tag_background) continue; assert(isCached(*chnode)); if (first) { - N = this->cache[chcacheid]; + N = this->cache[chcacheid].copy(); // If the first child(ren) are empty (e.g. echo) nodes, // ignore them (reset first flag) if (N.dim != 0) first = false; @@ -97,7 +98,8 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg chnode->progress_report(); } } - this->cache.insert(this->tree.getString(node), N); + const std::string &cacheid = this->tree.getString(node); + this->cache.insert(cacheid, N); } /* @@ -195,7 +197,8 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) node.matrix[2], node.matrix[6], node.matrix[10], node.matrix[14], node.matrix[15]); N.p3->transform(t); } - this->cache.insert(this->tree.getString(node), N); + const std::string &cacheid = this->tree.getString(node); + this->cache.insert(cacheid, N); } addToParent(state, node); } @@ -228,7 +231,8 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) node.progress_report(); ps->unlink(); - this->cache.insert(this->tree.getString(node), N); + const std::string &cacheid = this->tree.getString(node); + this->cache.insert(cacheid, N); } catch (...) { // Don't leak the PolySet on ProgressCancelException ps->unlink(); diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index 09368da..0c8c627 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -5,49 +5,38 @@ CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other) { - if (other.dim == 2) { - (*this->p2) += (*other.p2); - this->dim = 2; - } - if (other.dim == 3) { - (*this->p3) += (*other.p3); - this->dim = 3; - } + if (this->dim == 2) (*this->p2) += (*other.p2); + else if (this->dim == 3) (*this->p3) += (*other.p3); return *this; } CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator*=(const CGAL_Nef_polyhedron &other) { - if (other.dim == 2) { - (*this->p2) *= (*other.p2); - this->dim = 2; - } - if (other.dim == 3) { - (*this->p3) *= (*other.p3); - this->dim = 3; - } + if (this->dim == 2) (*this->p2) *= (*other.p2); + else if (this->dim == 3) (*this->p3) *= (*other.p3); return *this; } CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator-=(const CGAL_Nef_polyhedron &other) { - if (other.dim == 2) { - (*this->p2) -= (*other.p2); - this->dim = 2; - } - if (other.dim == 3) { - (*this->p3) -= (*other.p3); - this->dim = 3; - } + if (this->dim == 2) (*this->p2) -= (*other.p2); + else if (this->dim == 3) (*this->p3) -= (*other.p3); + return *this; +} + +extern CGAL_Nef_polyhedron2 minkowski2(const CGAL_Nef_polyhedron2 &a, const CGAL_Nef_polyhedron2 &b); + +CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &other) +{ + if (this->dim == 2) (*this->p2) = minkowski2(*this->p2, *other.p2); + else if (this->dim == 3) (*this->p3) = CGAL::minkowski_sum_3(*this->p3, *other.p3); return *this; } int CGAL_Nef_polyhedron::weight() const { - if (dim == 2) - return p2->explorer().number_of_vertices(); - if (dim == 3) - return p3->number_of_vertices(); + if (this->dim == 2) return this->p2->explorer().number_of_vertices(); + if (this->dim == 3) return this->p3->number_of_vertices(); return 0; } @@ -95,17 +84,13 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() return ps; } -extern CGAL_Nef_polyhedron2 minkowski2(const CGAL_Nef_polyhedron2 &a, const CGAL_Nef_polyhedron2 &b); - -CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &other) +/*! + Deep copy +*/ +CGAL_Nef_polyhedron CGAL_Nef_polyhedron::copy() const { - if (other.dim == 2) { - (*this->p2) = minkowski2(*this->p2, *other.p2); - this->dim = 2; - } - if (other.dim == 3) { - (*this->p3) = CGAL::minkowski_sum_3(*this->p3, *other.p3); - this->dim = 3; - } - return *this; + CGAL_Nef_polyhedron copy = *this; + if (copy.p2) copy.p2 = new CGAL_Nef_polyhedron2(*copy.p2); + else if (copy.p3) copy.p3 = new CGAL_Nef_polyhedron3(*copy.p3); + return copy; } diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h index 0ab72d7..9cac629 100644 --- a/src/CGAL_Nef_polyhedron.h +++ b/src/CGAL_Nef_polyhedron.h @@ -8,20 +8,22 @@ class CGAL_Nef_polyhedron { public: - CGAL_Nef_polyhedron() : dim(0) {} - CGAL_Nef_polyhedron(CGAL_Nef_polyhedron2 *p) : dim(2), p2(p) {} - CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) : dim(3), p3(p) { } + CGAL_Nef_polyhedron() : dim(0), p2(0), p3(0) {} + CGAL_Nef_polyhedron(CGAL_Nef_polyhedron2 *p) : dim(2), p2(p), p3(0) {} + CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) : dim(3), p2(0), p3(p) {} ~CGAL_Nef_polyhedron() {} CGAL_Nef_polyhedron &operator+=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &operator*=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &operator-=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &minkowski(const CGAL_Nef_polyhedron &other); + CGAL_Nef_polyhedron copy() const; int weight() const; class PolySet *convertToPolyset(); class DxfData *convertToDxfData() const; int dim; + // FIXME: Define ownership of the CGAL objects, e.g. use reference-counted smart pointers CGAL_Nef_polyhedron2 *p2; CGAL_Nef_polyhedron3 *p3; }; diff --git a/src/dxftess-glu.cc b/src/dxftess-glu.cc index 691872d..3132fe9 100644 --- a/src/dxftess-glu.cc +++ b/src/dxftess-glu.cc @@ -193,7 +193,7 @@ static bool point_on_line(double *p1, double *p2, double *p3) rot: CLOCKWISE rotation around positive Z axis */ -void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_triangle_splitting, double h) +void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_triangle_splitting, double h) { GLUtesselator *tobj = gluNewTess(); @@ -227,17 +227,17 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_trian Grid3d< QPair > point_to_path(GRID_COARSE); - for (int i = 0; i < dxf->paths.count(); i++) { - if (!dxf->paths[i].is_closed) + for (int i = 0; i < dxf.paths.count(); i++) { + if (!dxf.paths[i].is_closed) continue; gluTessBeginContour(tobj); - for (int j = 1; j < dxf->paths[i].points.count(); j++) { - point_to_path.data((*dxf->paths[i].points[j])[0], - (*dxf->paths[i].points[j])[1], + for (int j = 1; j < dxf.paths[i].points.count(); j++) { + point_to_path.data((*dxf.paths[i].points[j])[0], + (*dxf.paths[i].points[j])[1], h) = QPair(i, j); vl.append(tess_vdata()); - vl.last().v[0] = (*dxf->paths[i].points[j])[0]; - vl.last().v[1] = (*dxf->paths[i].points[j])[1]; + vl.last().v[0] = (*dxf.paths[i].points[j])[0]; + vl.last().v[1] = (*dxf.paths[i].points[j])[1]; vl.last().v[2] = h; gluTessVertex(tobj, vl.last().v, vl.last().v); } @@ -370,19 +370,19 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_trian int j2 = point_to_path.data(tess_tri[i].p[2][0], tess_tri[i].p[2][1], tess_tri[i].p[2][2]).second; if (i0 == i1 && j0 == 1 && j1 == 2) - dxf->paths[i0].is_inner = !up; + dxf.paths[i0].is_inner = !up; if (i0 == i1 && j0 == 2 && j1 == 1) - dxf->paths[i0].is_inner = up; + dxf.paths[i0].is_inner = up; if (i1 == i2 && j1 == 1 && j2 == 2) - dxf->paths[i1].is_inner = !up; + dxf.paths[i1].is_inner = !up; if (i1 == i2 && j1 == 2 && j2 == 1) - dxf->paths[i1].is_inner = up; + dxf.paths[i1].is_inner = up; if (i2 == i0 && j2 == 1 && j0 == 2) - dxf->paths[i2].is_inner = !up; + dxf.paths[i2].is_inner = !up; if (i2 == i0 && j2 == 2 && j0 == 1) - dxf->paths[i2].is_inner = up; + dxf.paths[i2].is_inner = up; } tess_tri.clear(); -- cgit v0.10.1 From 0d4329d0599000b0dc63740e0dff0d66598a18a4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 20:04:01 +0200 Subject: Configure cgalpngtest diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 533517a..7da873a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -201,9 +201,9 @@ add_cmdline_test(csgtermtest txt ${MINIMAL_FILES}) add_cmdline_test(cgaltest stl ${CGALTEST_FILES}) # Add cgalpngtest tests to CTest -LIST(APPEND CGALTEST_FILES ${FEATURES_FILES}) -LIST(APPEND CGALTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) -add_cmdline_test(cgaltest stl ${CGALPNGTEST_FILES}) +LIST(APPEND CGALPNGTEST_FILES ${FEATURES_FILES}) +LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) +add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) # Add opencsg tests to CTest LIST(APPEND OPENCSGTEST_FILES ${CGALTEST_FILES}) -- cgit v0.10.1 From 3f863ae4594190a94f9944e093b971cbfcff52b3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 22:42:46 +0200 Subject: Added isempty() diff --git a/src/polyset.h b/src/polyset.h index 8f23130..e80d182 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -24,6 +24,7 @@ public: PolySet(); ~PolySet(); + bool empty() const { return polygons.size() == 0; } void append_poly(); void append_vertex(double x, double y, double z = 0.0); void insert_vertex(double x, double y, double z = 0.0); -- cgit v0.10.1 From 5fee135293b7b55f5a28ab673481abeef1374a61 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 22:43:14 +0200 Subject: bugfix: Ignore empty polyhedrons when doing CSG ops diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 4bc5fc2..1336cf5 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -46,6 +46,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr if (target.dim != 2 && target.dim != 3) { assert(false && "Dimension of Nef polyhedron must be 2 or 3"); } + if (src.dim == 0) { return; } // Empty polyhedron. This can happen for e.g. square([0,0]) assert(target.dim == src.dim); switch (op) { @@ -377,6 +378,8 @@ public: CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) { + if (ps.empty()) return CGAL_Nef_polyhedron(); + if (ps.is2d) { #if 0 -- cgit v0.10.1 From 915c530ac40c3c8b4f9021720ee594b840b1ce2b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 22:43:56 +0200 Subject: Support for 2D designs diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc index 2680752..a93d564 100644 --- a/tests/cgalpngtest.cc +++ b/tests/cgalpngtest.cc @@ -212,12 +212,15 @@ int main(int argc, char **argv) bbox = BoundingBox(Vector3d(cgalbbox.xmin(), cgalbbox.ymin(), cgalbbox.zmin()), Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax())); } + else if (cgalRenderer.polyset) { + bbox = cgalRenderer.polyset->getBoundingBox(); + } Vector3d center = (bbox.min() + bbox.max()) / 2; double radius = (bbox.max() - bbox.min()).norm() / 2; Vector3d cameradir(1, 1, -0.5); - Vector3d camerapos = center - radius*1.5*cameradir; + Vector3d camerapos = center - radius*2*cameradir; csgInfo.glview->setCamera(camerapos, center); -- cgit v0.10.1 From 7599b30f864803186fd6dc68f50e9253986a5acc Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 22:44:16 +0200 Subject: Reinstate opencsg tests diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7da873a..aff746b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -206,7 +206,7 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) # Add opencsg tests to CTest -LIST(APPEND OPENCSGTEST_FILES ${CGALTEST_FILES}) +LIST(APPEND OPENCSGTEST_FILES ${CGALPNGTEST_FILES}) add_cmdline_test(opencsgtest png ${OPENCSGTEST_FILES}) # Add dxfexport tests to CTest -- cgit v0.10.1 From 8fb9ab4843018bcc9c33ba7ed5a2ac0336ca6ec9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Sep 2011 22:44:51 +0200 Subject: Make field of view narrower to look better diff --git a/tests/OffscreenView.cc b/tests/OffscreenView.cc index a5eb371..447a78c 100644 --- a/tests/OffscreenView.cc +++ b/tests/OffscreenView.cc @@ -151,7 +151,6 @@ void OffscreenView::resizeGL(int w, int h) #endif glViewport(0, 0, w, h); w_h_ratio = sqrt((double)w / (double)h); - setupPerspective(); } void OffscreenView::setupPerspective() @@ -159,7 +158,7 @@ void OffscreenView::setupPerspective() glMatrixMode(GL_PROJECTION); glLoadIdentity(); double dist = (this->camera_center - this->camera_eye).norm(); - gluPerspective(90, w_h_ratio, 0.1*dist, 10*dist); + gluPerspective(45, w_h_ratio, 0.1*dist, 100*dist); } void OffscreenView::setupOrtho(bool offset) -- cgit v0.10.1 From 0f2ce4ca75fb2359aac72c3f9f07da96b419244b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 01:49:05 +0200 Subject: center parameter is not defined for circle diff --git a/testdata/scad/features/circle-tests.scad b/testdata/scad/features/circle-tests.scad index edf93a4..6b54d55 100644 --- a/testdata/scad/features/circle-tests.scad +++ b/testdata/scad/features/circle-tests.scad @@ -1,10 +1,10 @@ circle(); -translate([0,3,0]) circle(1, true); -translate([5,1,0]) circle(r=3, center=true); -translate([0,-1,0]) circle(r=0, center=true); -translate([0,-3,0]) circle(1, true, $fn=4); -translate([3,-3,0]) circle(1, true, $fn=8); -translate([6,-3,0]) circle(1, true, $fn=12); -translate([0,-6,0]) circle(1, true, $fa=20, $fs=0.3); -translate([3,-6,0]) circle(1, true, $fa=30, $fs=0.3); -translate([6,-6,0]) circle(1, true, $fa=40, $fs=0.3); +translate([0,3,0]) circle(1); +translate([5,1,0]) circle(r=3); +translate([0,-1,0]) circle(r=0); +translate([0,-3,0]) circle(1, $fn=4); +translate([3,-3,0]) circle(1, $fn=8); +translate([6,-3,0]) circle(1, $fn=12); +translate([0,-6,0]) circle(1, $fa=20, $fs=0.3); +translate([3,-6,0]) circle(1, $fa=30, $fs=0.3); +translate([6,-6,0]) circle(1, $fa=40, $fs=0.3); -- cgit v0.10.1 From 29cfbe6f62cd3041ca0b9fad8902b17d308322c2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 01:49:22 +0200 Subject: improved sphere test diff --git a/testdata/scad/features/sphere-tests.scad b/testdata/scad/features/sphere-tests.scad index f87aa26..e666c1b 100644 --- a/testdata/scad/features/sphere-tests.scad +++ b/testdata/scad/features/sphere-tests.scad @@ -1,4 +1,10 @@ -sphere(5); -translate([0,12,0]) sphere(5, $fa=5, $fs=0.5); -translate([12,0,0]) sphere(r=6); -translate([12,12,0]) sphere(r=6, $fn=5); +sphere(); +translate([2,0,0]) sphere(r=0); +translate([0,11,0]) sphere(5); +translate([0,-11,0]) sphere(r=5); +translate([11,-11,0]) sphere(5, $fn=5); +translate([11,0,0]) sphere(5, $fn=10); +translate([11,11,0]) sphere(5, $fn=15); +translate([22,-11, 0]) sphere(5, $fa=20, $fs=0.3); +translate([22, 0, 0]) sphere(5, $fa=30, $fs=0.3); +translate([22, 11, 0]) sphere(5, $fa=40, $fs=0.3); -- cgit v0.10.1 From b0667057164d2710adad28613d4597374e60180a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 01:50:30 +0200 Subject: added expected files diff --git a/tests/regression/cgalpngtest/circle-tests-expected.png b/tests/regression/cgalpngtest/circle-tests-expected.png new file mode 100644 index 0000000..0736af5 Binary files /dev/null and b/tests/regression/cgalpngtest/circle-tests-expected.png differ diff --git a/tests/regression/cgalpngtest/sphere-tests-expected.png b/tests/regression/cgalpngtest/sphere-tests-expected.png new file mode 100644 index 0000000..6ad650f Binary files /dev/null and b/tests/regression/cgalpngtest/sphere-tests-expected.png differ diff --git a/tests/regression/cgalpngtest/square-tests-expected.png b/tests/regression/cgalpngtest/square-tests-expected.png new file mode 100644 index 0000000..8c9bc60 Binary files /dev/null and b/tests/regression/cgalpngtest/square-tests-expected.png differ -- cgit v0.10.1 From c48d12a3524d5de99fb60e00dba23213c35642bb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 02:14:24 +0200 Subject: bugfix: center vector was uninitialized diff --git a/src/polyset.cc b/src/polyset.cc index 19b0bba..e29563f 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -209,7 +209,7 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m } } else { - Vector3d center; + Vector3d center = Vector3d::Zero(); for (int j = 0; j < poly->size(); j++) { center[0] += poly->at(j)[0]; center[1] += poly->at(j)[1]; @@ -255,7 +255,7 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m gl_draw_triangle(shaderinfo, poly->at(2), poly->at(3), poly->at(1), true, false, true, 0, mirrored); } else { - Vector3d center; + Vector3d center = Vector3d::Zero(); for (int j = 0; j < poly->size(); j++) { center[0] += poly->at(j)[0]; center[1] += poly->at(j)[1]; -- cgit v0.10.1 From c555a9646a68e823c8261e905fc4c3a11855c5c6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 02:32:07 +0200 Subject: change: Always use r as fallback variable if either of r1 or r2 are missing diff --git a/src/primitives.cc b/src/primitives.cc index 5502192..0da8fba 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -180,8 +180,7 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstanti Value r, r1, r2; r1 = c.lookup_variable("r1"); r2 = c.lookup_variable("r2"); - if (r1.type != Value::NUMBER && r2.type != Value::NUMBER) - r = c.lookup_variable("r", true); // silence warning since r has no default value + r = c.lookup_variable("r", true); // silence warning since r has no default value Value center = c.lookup_variable("center"); if (h.type == Value::NUMBER) { node->h = h.num; -- cgit v0.10.1 From 6759d80cf4f4a1397ee058765dae3ffe14c4cf6a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 02:34:42 +0200 Subject: Added cylinder-tests diff --git a/testdata/scad/features/cylinder-tests.scad b/testdata/scad/features/cylinder-tests.scad new file mode 100644 index 0000000..54e88cd --- /dev/null +++ b/testdata/scad/features/cylinder-tests.scad @@ -0,0 +1,15 @@ +cylinder(); +translate([1,0,0]) cylinder(r=0); +translate([2,0,0]) cylinder(r1=0, r2=0); +translate([0,-11,0]) cylinder(r=5); +translate([0,11,0]) cylinder(r=5, h=10, center=true); + +translate([11,-11,0]) cylinder(h=5, r1=5); +translate([11,0,0]) cylinder(h=5, r1=5, r2=0); +translate([11,11,0]) cylinder(h=8, r1=5, r2=5); + +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); + +// FIXME: We could test $fs, $fa, $fn as well diff --git a/tests/regression/cgalpngtest/cylinder-tests-expected.png b/tests/regression/cgalpngtest/cylinder-tests-expected.png new file mode 100644 index 0000000..9d96df2 Binary files /dev/null and b/tests/regression/cgalpngtest/cylinder-tests-expected.png differ -- cgit v0.10.1 From f7bc79f349095ceaccd8de94878c2608ddfd178c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 02:40:29 +0200 Subject: Added cube-tests diff --git a/testdata/scad/features/cube-tests.scad b/testdata/scad/features/cube-tests.scad new file mode 100644 index 0000000..ae2ead1 --- /dev/null +++ b/testdata/scad/features/cube-tests.scad @@ -0,0 +1,4 @@ +cube(); +cube([1,1,0]); cube([1,0,1]); cube([0,1,1]); cube([0,0,0]); +translate([2,0,0]) cube([2,3,1]); +translate([6,0,0]) cube([2,4,2], center=true); diff --git a/tests/regression/cgalpngtest/cube-tests-expected.png b/tests/regression/cgalpngtest/cube-tests-expected.png new file mode 100644 index 0000000..536f220 Binary files /dev/null and b/tests/regression/cgalpngtest/cube-tests-expected.png differ -- cgit v0.10.1 From ac1ce87f19afd930ae252cea85023f4e1239abc7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 02:48:22 +0200 Subject: Only enable verified tests diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index aff746b..bb346a4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -201,13 +201,18 @@ add_cmdline_test(csgtermtest txt ${MINIMAL_FILES}) add_cmdline_test(cgaltest stl ${CGALTEST_FILES}) # Add cgalpngtest tests to CTest -LIST(APPEND CGALPNGTEST_FILES ${FEATURES_FILES}) -LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) +LIST(APPEND CGALPNGTEST_FILES + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/circle-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/square-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cube-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/sphere-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad) +#LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) # Add opencsg tests to CTest LIST(APPEND OPENCSGTEST_FILES ${CGALPNGTEST_FILES}) -add_cmdline_test(opencsgtest png ${OPENCSGTEST_FILES}) +#add_cmdline_test(opencsgtest png ${OPENCSGTEST_FILES}) # Add dxfexport tests to CTest #add_cmdline_test(${CMAKE_SOURCE_DIR}/../test-code/exportdxf dxf ${SCAD_FILES}) -- cgit v0.10.1 From e2da24871de1e77668a723baee81bd8022b10025 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 02:49:54 +0200 Subject: cylinder update diff --git a/doc/visitor-changes.txt b/doc/visitor-changes.txt index e39cd2e..1e05cee 100644 --- a/doc/visitor-changes.txt +++ b/doc/visitor-changes.txt @@ -1,2 +1,3 @@ Changes in visitor branch: o import_dxf(): layername="" imports all layers. Importing a single layer with a zero-length name is no longer supported. +o cylinder(): the r parameter will now always be used in place of a missing r1 or r2 -- cgit v0.10.1 From 8e0651afd456612dc0cbcec83e11f27dcf216a02 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 14:31:56 +0200 Subject: Added union-tests diff --git a/testdata/scad/features/union-tests.scad b/testdata/scad/features/union-tests.scad new file mode 100644 index 0000000..718aa8c --- /dev/null +++ b/testdata/scad/features/union-tests.scad @@ -0,0 +1,29 @@ +translate([-12,0,0]) union() { + cube([10,10,10]); + translate([4,4,8]) cube([2,2,10]); +} + +union() { + cube([10,10,10]); + translate([0,0,10]) cube([2,2,10]); +} + +translate([12,0,0]) union() { + cube([10,10,10]); + translate([0,0,11]) cube([2,2,10]); +} + +translate([24,0,0]) union() { + cube([10,10,10]); + translate([4,4,10]) cube([2,2,10]); +} + +translate([-12,12,0]) union() { + cube([10,10,10]); + translate([-2,10,10]) cube([2,2,10]); +} + +translate([0,12,0]) union() { + cube([10,10,10]); + translate([0,10,10]) cube([2,2,10]); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bb346a4..109b69f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -206,7 +206,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/square-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cube-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/sphere-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/union-tests-expected.png b/tests/regression/cgalpngtest/union-tests-expected.png new file mode 100644 index 0000000..c390f42 Binary files /dev/null and b/tests/regression/cgalpngtest/union-tests-expected.png differ -- cgit v0.10.1 From a20c08b8cea3832a8c99eeecc8d3f66cdbb6c85d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 14:38:27 +0200 Subject: Added difference-tests diff --git a/testdata/scad/features/difference-tests.scad b/testdata/scad/features/difference-tests.scad index f945246..cc508a5 100644 --- a/testdata/scad/features/difference-tests.scad +++ b/testdata/scad/features/difference-tests.scad @@ -1,4 +1,25 @@ difference() { - sphere(3); - cube([3,3,8], center=true); + cube([10,10,10], center=true); + cylinder(r=4, h=20, center=true); +} + +translate([12,0,0]) difference() { + cube([10,10,10], center=true); + cylinder(r=4, h=10, center=true); +} + +translate([0,12,0]) difference() { + cube([10,10,10], center=true); + cylinder(r=4, h=11, center=true); + rotate([0,90,0]) cylinder(r=4, h=11, center=true); +} + +translate([12,12,0]) difference() { + cube([10,10,10], center=true); + translate([0,0,7]) cylinder(r=4, h=4, center=true); +} + +translate([24,0,0]) difference() { + cube([10,10,10], center=true); + translate([0,0,6.99]) cylinder(r=4, h=4, center=true); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 109b69f..26533af 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -207,7 +207,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cube-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/sphere-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/difference-tests-expected.png b/tests/regression/cgalpngtest/difference-tests-expected.png new file mode 100644 index 0000000..e672c48 Binary files /dev/null and b/tests/regression/cgalpngtest/difference-tests-expected.png differ -- cgit v0.10.1 From a1e452472a8cc71c8a8337ed1a8f54e517b48a04 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 14:46:45 +0200 Subject: Added intersection-tests diff --git a/testdata/scad/features/intersection-tests.scad b/testdata/scad/features/intersection-tests.scad index 4101b03..f673b35 100644 --- a/testdata/scad/features/intersection-tests.scad +++ b/testdata/scad/features/intersection-tests.scad @@ -1,4 +1,35 @@ intersection() { - sphere(3); - cube([3,3,8], center=true); + sphere(r=5); + translate([0,0,3]) cube([4,4,6], center=true); +} + +translate([0,12,0]) intersection() { + cube([10,10,10], center=true); + cylinder(r=4, h=12, center=true); +} + +translate([12,0,0]) intersection() { + cube([10,10,10], center=true); + cylinder(r=4, h=12, center=true); + rotate([0,90,0]) cylinder(r=4, h=12, center=true); +} + +translate([12,12,0]) intersection() { + cube([10,10,10], center=true); + translate([0,0,7]) cylinder(r=4, h=4, center=true); +} + +translate([24,0,0]) intersection() { + cube([10,10,10], center=true); + translate([0,0,6.99]) cylinder(r=4, h=4, center=true); +} + +translate([-12,0,0]) intersection() { + cube([10,10,10], center=true); + translate([0,-10,-10]) cube([10,10,10], center=true); +} + +translate([-12,12,0]) intersection() { + cube([10,10,10], center=true); + translate([0,-9.99,-9.99]) cube([10,10,10], center=true); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 26533af..161eade 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -208,7 +208,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/sphere-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/intersection-tests-expected.png b/tests/regression/cgalpngtest/intersection-tests-expected.png new file mode 100644 index 0000000..6d004b0 Binary files /dev/null and b/tests/regression/cgalpngtest/intersection-tests-expected.png differ -- cgit v0.10.1 From 53725500e52725b2559444cc4b8abb2c803a49d0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 16:22:01 +0200 Subject: Better warning for unimplemented render() diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index b3cc88e..5bc4257 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -163,10 +163,10 @@ Response CSGTermEvaluator::visit(State &state, const TransformNode &node) return ContinueTraversal; } -// FIXME: Find out how to best call into CGAL from this visitor +// FIXME: If we've got CGAL support, render this node as a CGAL union into a PolySet Response CSGTermEvaluator::visit(State &state, const RenderNode &node) { - PRINT("WARNING: Found render() statement but compiled without CGAL support!"); + PRINT("WARNING: render() statement not implemented"); if (state.isPostfix()) { applyToChildren(node, CSGT_UNION); addToParent(state, node); -- cgit v0.10.1 From f1c17e791f9510111db535fd8d55699cbcff7210 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 20:06:03 +0200 Subject: Added empty() diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h index 9cac629..616ba23 100644 --- a/src/CGAL_Nef_polyhedron.h +++ b/src/CGAL_Nef_polyhedron.h @@ -13,6 +13,7 @@ public: CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) : dim(3), p2(0), p3(p) {} ~CGAL_Nef_polyhedron() {} + bool empty() const { return (dim == 0 || !p2 && !p3); } CGAL_Nef_polyhedron &operator+=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &operator*=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &operator-=(const CGAL_Nef_polyhedron &other); -- cgit v0.10.1 From 2f4582eeba31dae4ec07133e348c4938e106a930 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 20:18:27 +0200 Subject: bugfix: Don't try to render empty polyhedrons diff --git a/src/mainwin.cc b/src/mainwin.cc index 4faed34..a2c845d 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1275,16 +1275,21 @@ void MainWindow::actionRenderCGAL() int s = t.elapsed() / 1000; PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60); - this->cgalRenderer = new CGALRenderer(*this->root_N); - // Go to CGAL view mode - if (viewActionCGALGrid->isChecked()) { - viewModeCGALGrid(); + if (!this->root_N->empty()) { + this->cgalRenderer = new CGALRenderer(*this->root_N); + // Go to CGAL view mode + if (viewActionCGALGrid->isChecked()) { + viewModeCGALGrid(); + } + else { + viewModeCGALSurface(); + } + + PRINT("Rendering finished."); } else { - viewModeCGALSurface(); + PRINT("WARNING: No top level geometry to render"); } - - PRINT("Rendering finished."); } #ifdef USE_PROGRESSWIDGET -- cgit v0.10.1 From f2d3621470b116255adf0510828b06903a0fc1eb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 20:19:17 +0200 Subject: bugfix: extrude nodes were broken for OpenCSG rendering diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index f556bcb..bfcd8f8 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -244,14 +244,15 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, { // Before extruding, union all (2D) children nodes // to a single DxfData, then tesselate this into a PolySet - CGAL_Nef_polyhedron N; - N.dim = 2; + CGAL_Nef_polyhedron sum; foreach (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; - N += this->cgalevaluator.evaluateCGALMesh(*v); + CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); + if (sum.empty()) sum = N.copy(); + else sum += N; } - dxf = N.convertToDxfData();; + dxf = sum.convertToDxfData();; } else { dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } @@ -340,14 +341,15 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, { // Before extruding, union all (2D) children nodes // to a single DxfData, then tesselate this into a PolySet - CGAL_Nef_polyhedron N; - N.dim = 2; + CGAL_Nef_polyhedron sum; foreach (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; - N += this->cgalevaluator.evaluateCGALMesh(*v); + CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); + if (sum.empty()) sum = N.copy(); + else sum += N; } - dxf = N.convertToDxfData(); + dxf = sum.convertToDxfData(); } else { dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } -- cgit v0.10.1 From 20e5c373c24afe405ecd982a69d22eb38de192f7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 20:19:34 +0200 Subject: Use new empty() method of CGAL_Nef_polyhedron diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 1336cf5..4915bf8 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -46,7 +46,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr if (target.dim != 2 && target.dim != 3) { assert(false && "Dimension of Nef polyhedron must be 2 or 3"); } - if (src.dim == 0) { return; } // Empty polyhedron. This can happen for e.g. square([0,0]) + if (src.empty()) return; // Empty polyhedron. This can happen for e.g. square([0,0]) assert(target.dim == src.dim); switch (op) { @@ -79,7 +79,6 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg { CGAL_Nef_polyhedron N; if (this->visitedchildren[node.index()].size() > 0) { - bool first = true; for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin(); iter != this->visitedchildren[node.index()].end(); iter++) { @@ -88,11 +87,8 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg // FIXME: Don't use deep access to modinst members if (chnode->modinst->tag_background) continue; assert(isCached(*chnode)); - if (first) { + if (N.empty()) { N = this->cache[chcacheid].copy(); - // If the first child(ren) are empty (e.g. echo) nodes, - // ignore them (reset first flag) - if (N.dim != 0) first = false; } else { process(N, this->cache[chcacheid], op); } @@ -635,7 +631,7 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) return CGAL_Nef_polyhedron(N); } catch (CGAL::Assertion_exception e) { - PRINTF("ERROR: Illegal polygonal object - make sure all polygons are defined with the same winding order. Skipping affected object."); + PRINTF("CGAL error: %s", e.what()); CGAL::set_error_behaviour(old_behaviour); return CGAL_Nef_polyhedron(); } -- cgit v0.10.1 From 5cc06832a173b0078cf12fffe530cdf303b033b2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 20:19:59 +0200 Subject: Added note about almost planar polygons diff --git a/doc/TODO.txt b/doc/TODO.txt index 8913465..dd46b7b 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -179,7 +179,8 @@ o Hollow donut problem extrusions, this has only a minor visual impact, but for rotate extrusion, the resulting CGAL models will lose the hole. The OpenCSG rendering keeps the hole, but renders slightly incorrect. - +o CGAL issues + - CGAL doesn't handle almost planar polygons. Consider splitting into triangles ourselves. See WillamAdams/dodec.scad IDEAS FOR LANGUAGE CHANGES -- cgit v0.10.1 From 818af2bcfc92f1b1d7cccb6937a481afb7517086 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 21:37:43 +0200 Subject: minor fix for projection node, but doesn't fix it all diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index bfcd8f8..500c87d 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -107,7 +107,6 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr PolySet *ps3 = N.convertToPolyset(); CGAL_Nef_polyhedron np; - np.dim = 2; for (size_t i = 0; i < ps3->polygons.size(); i++) { int min_x_p = -1; @@ -145,7 +144,14 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr else plist.push_back(p); } - (*np.p2) += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + // FIXME: Should the CGAL_Nef_polyhedron2 be cached? + if (np.empty()) { + np.dim = 2; + np.p2 = new CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + } + else { + (*np.p2) += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + } } DxfData *dxf = np.convertToDxfData(); dxf_tesselate(ps, *dxf, 0, true, false, 0); -- cgit v0.10.1 From 287c20d2ff1f737acb414b3eda4969356c02c4fe Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 23:33:18 +0200 Subject: Added color-tests diff --git a/testdata/scad/features/color-tests.scad b/testdata/scad/features/color-tests.scad new file mode 100644 index 0000000..a87dad3 --- /dev/null +++ b/testdata/scad/features/color-tests.scad @@ -0,0 +1,10 @@ +module object() cube([10,10,10]); + +translate([12,12,0]) object(); +color([1,0,0]) translate([24,12,0]) object(); +translate([0,12,0]) color([0,1,1]) object(); +color([0,0,1,0.5]) object(); +translate([12,0,0]) color([0,0,1],0.5) object(); +translate([24,0,0]) color(c="Green",alpha=0.2) object(); +translate([-12,12,0]) color() object(); +translate([-12,0,0]) color(alpha=0.5) object(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 161eade..a985ce7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -209,7 +209,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/color-tests-expected.png b/tests/regression/cgalpngtest/color-tests-expected.png new file mode 100644 index 0000000..207fc5b Binary files /dev/null and b/tests/regression/cgalpngtest/color-tests-expected.png differ -- cgit v0.10.1 From ed8a99ed55d5d1ad043608ed471bb7564403bde9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 23:35:10 +0200 Subject: Refactoring: Moved color functionality into separate module and node diff --git a/openscad.pro b/openscad.pro index 8e43102..bd2215e 100644 --- a/openscad.pro +++ b/openscad.pro @@ -144,6 +144,7 @@ HEADERS += src/renderer.h \ src/projectionnode.h \ src/importnode.h \ src/transformnode.h \ + src/colornode.h \ src/rendernode.h \ src/openscad.h \ src/polyset.h \ @@ -178,6 +179,7 @@ SOURCES += src/openscad.cc \ src/polyset.cc \ src/csgops.cc \ src/transform.cc \ + src/color.cc \ src/primitives.cc \ src/projection.cc \ src/cgaladv.cc \ diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 5bc4257..aaf96ef 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -5,6 +5,7 @@ #include "module.h" #include "csgnode.h" #include "transformnode.h" +#include "colornode.h" #include "rendernode.h" #include "printutils.h" @@ -82,14 +83,14 @@ Response CSGTermEvaluator::visit(State &state, const AbstractIntersectionNode &n return ContinueTraversal; } -static CSGTerm *evaluate_csg_term_from_ps(const double m[20], +static CSGTerm *evaluate_csg_term_from_ps(const State &state, vector &highlights, vector &background, PolySet *ps, const ModuleInstantiation *modinst, const AbstractPolyNode &node) { - CSGTerm *t = new CSGTerm(ps, m, QString("%1%2").arg(node.name().c_str()).arg(node.index())); + CSGTerm *t = new CSGTerm(ps, state.matrix(), state.color(), QString("%1%2").arg(node.name().c_str()).arg(node.index())); if (modinst->tag_highlight) highlights.push_back(t->link()); if (modinst->tag_background) { @@ -105,7 +106,7 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node) CSGTerm *t1 = NULL; PolySet *ps = node.evaluate_polyset(AbstractPolyNode::RENDER_OPENCSG, this->psevaluator); if (ps) { - t1 = evaluate_csg_term_from_ps(state.matrix(), this->highlights, this->background, + t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, ps, node.modinst, node); } this->stored_term[node.index()] = t1; @@ -138,7 +139,7 @@ Response CSGTermEvaluator::visit(State &state, const CsgNode &node) Response CSGTermEvaluator::visit(State &state, const TransformNode &node) { if (state.isPrefix()) { - double m[20]; + double m[16]; for (int i = 0; i < 16; i++) { @@ -149,11 +150,6 @@ Response CSGTermEvaluator::visit(State &state, const TransformNode &node) m[i] += state.matrix()[c_row + j*4] * node.matrix[m_col*4 + j]; } } - - for (int i = 16; i < 20; i++) { - m[i] = node.matrix[i] < 0 ? state.matrix()[i] : node.matrix[i]; - } - state.setMatrix(m); } if (state.isPostfix()) { @@ -163,6 +159,18 @@ Response CSGTermEvaluator::visit(State &state, const TransformNode &node) return ContinueTraversal; } +Response CSGTermEvaluator::visit(State &state, const ColorNode &node) +{ + if (state.isPrefix()) { + state.setColor(node.color); + } + if (state.isPostfix()) { + applyToChildren(node, CSGT_UNION); + addToParent(state, node); + } + return ContinueTraversal; +} + // FIXME: If we've got CGAL support, render this node as a CGAL union into a PolySet Response CSGTermEvaluator::visit(State &state, const RenderNode &node) { @@ -186,168 +194,3 @@ void CSGTermEvaluator::addToParent(const State &state, const AbstractNode &node) this->visitedchildren[state.parent()->index()].push_back(&node); } } - - -#if 0 - -// FIXME: #ifdef ENABLE_CGAL -#if 0 -CSGTerm *CgaladvNode::evaluate_csg_term(double m[20], QVector &highlights, QVector &background) const -{ - if (type == MINKOWSKI) - return evaluate_csg_term_from_nef(m, highlights, background, "minkowski", this->convexity); - - if (type == GLIDE) - return evaluate_csg_term_from_nef(m, highlights, background, "glide", this->convexity); - - if (type == SUBDIV) - return evaluate_csg_term_from_nef(m, highlights, background, "subdiv", this->convexity); - - if (type == HULL) - return evaluate_csg_term_from_nef(m, highlights, background, "hull", this->convexity); - - return NULL; -} - -#else // ENABLE_CGAL - -CSGTerm *CgaladvNode::evaluate_csg_term(double m[20], QVector &highlights, QVector &background) const -{ - PRINT("WARNING: Found minkowski(), glide(), subdiv() or hull() statement but compiled without CGAL support!"); - return NULL; -} - -#endif // ENABLE_CGAL - - - -// FIXME: #ifdef ENABLE_CGAL -#if 0 -CSGTerm *AbstractNode::evaluate_csg_term_from_nef(double m[20], QVector &highlights, QVector &background, const char *statement, int convexity) const -{ - QString key = mk_cache_id(); - if (PolySet::ps_cache.contains(key)) { - PRINT(PolySet::ps_cache[key]->msg); - return AbstractPolyNode::evaluate_csg_term_from_ps(m, highlights, background, - PolySet::ps_cache[key]->ps->link(), modinst, idx); - } - - print_messages_push(); - CGAL_Nef_polyhedron N; - - QString cache_id = mk_cache_id(); - if (cgal_nef_cache.contains(cache_id)) - { - PRINT(cgal_nef_cache[cache_id]->msg); - N = cgal_nef_cache[cache_id]->N; - } - else - { - PRINTF_NOCACHE("Processing uncached %s statement...", statement); - // PRINTA("Cache ID: %1", cache_id); - QApplication::processEvents(); - - QTime t; - t.start(); - - N = this->evaluateCSGMesh(); - - int s = t.elapsed() / 1000; - PRINTF_NOCACHE("..processing time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60); - } - - PolySet *ps = NULL; - - if (N.dim == 2) - { - DxfData dd(N); - ps = new PolySet(); - ps->is2d = true; - dxf_tesselate(ps, dd, 0, true, false, 0); - dxf_border_to_ps(ps, &dd); - } - - if (N.dim == 3) - { - if (!N.p3.is_simple()) { - PRINTF("WARNING: Result of %s() isn't valid 2-manifold! Modify your design..", statement); - return NULL; - } - - ps = new PolySet(); - - CGAL_Polyhedron P; - N.p3.convert_to_Polyhedron(P); - - typedef CGAL_Polyhedron::Vertex Vertex; - typedef CGAL_Polyhedron::Vertex_const_iterator VCI; - typedef CGAL_Polyhedron::Facet_const_iterator FCI; - typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; - - for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { - HFCC hc = fi->facet_begin(); - HFCC hc_end = hc; - ps->append_poly(); - do { - Vertex v = *VCI((hc++)->vertex()); - double x = CGAL::to_double(v.point().x()); - double y = CGAL::to_double(v.point().y()); - double z = CGAL::to_double(v.point().z()); - ps->append_vertex(x, y, z); - } while (hc != hc_end); - } - } - - if (ps) - { - ps->convexity = convexity; - PolySet::ps_cache.insert(key, new PolySet::ps_cache_entry(ps->link())); - - CSGTerm *term = new CSGTerm(ps, m, QString("n%1").arg(idx)); - if (modinst->tag_highlight) - highlights.push_back(term->link()); - if (modinst->tag_background) { - background.push_back(term); - return NULL; - } - return term; - } - print_messages_pop(); - - return NULL; -} - -CSGTerm *RenderNode::evaluate_csg_term(double m[20], QVector &highlights, QVector &background) const -{ - return evaluate_csg_term_from_nef(m, highlights, background, "render", this->convexity); -} - -#else - -CSGTerm *RenderNode::evaluate_csg_term(double m[20], QVector &highlights, QVector &background) const -{ - CSGTerm *t1 = NULL; - PRINT("WARNING: Found render() statement but compiled without CGAL support!"); - foreach(AbstractNode * v, children) { - CSGTerm *t2 = v->evaluate_csg_term(m, highlights, background); - if (t2 && !t1) { - t1 = t2; - } else if (t2 && t1) { - t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2); - } - } - if (modinst->tag_highlight) - highlights.push_back(t1->link()); - if (t1 && modinst->tag_background) { - background.push_back(t1); - return NULL; - } - return t1; -} - -#endif - - - -#endif - diff --git a/src/CSGTermEvaluator.h b/src/CSGTermEvaluator.h index ff62cc1..6bff7f5 100644 --- a/src/CSGTermEvaluator.h +++ b/src/CSGTermEvaluator.h @@ -27,6 +27,7 @@ public: virtual Response visit(State &state, const AbstractPolyNode &node); virtual Response visit(State &state, const CsgNode &node); virtual Response visit(State &state, const TransformNode &node); + virtual Response visit(State &state, const ColorNode &node); virtual Response visit(State &state, const RenderNode &node); class CSGTerm *evaluateCSGTerm(const AbstractNode &node, diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index 6cbe849..d624a5f 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -85,6 +85,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, if (shaderinfo) glUseProgram(shaderinfo[0]); for (; j < i; j++) { double *m = chain->matrices[j]; + double *c = chain->colors[j]; glPushMatrix(); glMultMatrixd(m); int csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; @@ -92,12 +93,12 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m, shaderinfo); } else if (background) { chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m, shaderinfo); - } else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) { + } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { // User-defined color from source - glColor4d(m[16], m[17], m[18], m[19]); + glColor4dv(c); if (shaderinfo) { - glUniform4f(shaderinfo[1], m[16], m[17], m[18], m[19]); - glUniform4f(shaderinfo[2], (m[16]+1)/2, (m[17]+1)/2, (m[18]+1)/2, 1.0); + glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]); + glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); } chain->polysets[j]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m, shaderinfo); } else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) { diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 0a0c9c8..92a504a 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -66,6 +66,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, if (polySetVisitMark[QPair(chain->polysets[i], chain->matrices[i])]++ > 0) continue; double *m = chain->matrices[i]; + double *c = chain->colors[i]; glPushMatrix(); glMultMatrixd(m); int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; @@ -91,12 +92,12 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, } else { chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); } - } else if (m[16] >= 0 || m[17] >= 0 || m[18] >= 0 || m[19] >= 0) { - glColor4d(m[16], m[17], m[18], m[19]); + } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { + glColor4dv(c); chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); if (showedges) { glDisable(GL_LIGHTING); - glColor4d((m[16]+1)/2, (m[17]+1)/2, (m[18]+1)/2, 1.0); + glColor4d((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); chain->polysets[i]->render_edges(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode)); glEnable(GL_LIGHTING); } diff --git a/src/builtin.h b/src/builtin.h index d501a19..79debe0 100644 --- a/src/builtin.h +++ b/src/builtin.h @@ -13,6 +13,7 @@ extern void destroy_builtin_modules(); extern void register_builtin_csgops(); extern void register_builtin_transform(); +extern void register_builtin_color(); extern void register_builtin_primitives(); extern void register_builtin_surface(); extern void register_builtin_control(); diff --git a/src/color.cc b/src/color.cc new file mode 100644 index 0000000..a3c8101 --- /dev/null +++ b/src/color.cc @@ -0,0 +1,108 @@ +/* + * OpenSCAD (www.openscad.org) + * Copyright (C) 2009-2011 Clifford Wolf and + * Marius Kintel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * As a special exception, you have permission to link this program + * with the CGAL library and distribute executables, as long as you + * follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from CGAL. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "colornode.h" +#include "module.h" +#include "context.h" +#include "builtin.h" +#include "printutils.h" +#include "visitor.h" +#include +#include +#include + +class ColorModule : public AbstractModule +{ +public: + ColorModule() { } + virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; +}; + +using std::string; + +AbstractNode *ColorModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const +{ + ColorNode *node = new ColorNode(inst); + + for (int i = 0; i < 4; i++) node->color[i] = -1; + + QVector argnames; + QVector argexpr; + + argnames = QVector() << "c" << "alpha"; + + Context c(ctx); + c.args(argnames, argexpr, inst->argnames, inst->argvalues); + + Value v = c.lookup_variable("c"); + if (v.type == Value::VECTOR) { + for (int i = 0; i < 4; i++) + node->color[i] = i < v.vec.size() ? v.vec[i]->num : 1.0; + } else if (v.type == Value::STRING) { + QString colorname = QString::fromStdString(v.text); + QColor color; + color.setNamedColor(colorname); + if (color.isValid()) { + node->color[0] = color.redF(); + node->color[1] = color.greenF(); + node->color[2] = color.blueF(); + } else { + PRINTA_NOCACHE("WARNING: Color name \"%1\" unknown. Please see", colorname); + PRINTF_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors"); + } + } + Value alpha = c.lookup_variable("alpha"); + if (alpha.type == Value::NUMBER) { + node->color[3] = alpha.num; + } + + foreach (ModuleInstantiation *v, inst->children) { + AbstractNode *n = v->evaluate(inst->ctx); + if (n != NULL) + node->children.push_back(n); + } + + return node; +} + +string ColorNode::toString() const +{ + std::stringstream stream; + + stream << "color([" << this->color[0] << ", " << this->color[1] << ", " << this->color[2] << ", " << this->color[3] << "])"; + + return stream.str(); +} + +string ColorNode::name() const +{ + return "color"; +} + +void register_builtin_color() +{ + builtin_modules["color"] = new ColorModule(); +} diff --git a/src/colornode.h b/src/colornode.h new file mode 100644 index 0000000..b41e2a9 --- /dev/null +++ b/src/colornode.h @@ -0,0 +1,20 @@ +#ifndef COLORNODE_H_ +#define COLORNODE_H_ + +#include "node.h" +#include "visitor.h" + +class ColorNode : public AbstractNode +{ +public: + ColorNode(const ModuleInstantiation *mi) : AbstractNode(mi) { } + virtual Response accept(class State &state, Visitor &visitor) const { + return visitor.visit(state, *this); + } + virtual std::string toString() const; + virtual std::string name() const; + + double color[4]; +}; + +#endif diff --git a/src/csgterm.cc b/src/csgterm.cc index db9525a..179381e 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -46,15 +46,15 @@ */ -CSGTerm::CSGTerm(PolySet *polyset, const double m[20], QString label) +CSGTerm::CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], QString label) { this->type = TYPE_PRIMITIVE; this->polyset = polyset; this->label = label; this->left = NULL; this->right = NULL; - for (int i = 0; i < 20; i++) - this->m[i] = m[i]; + for (int i = 0; i < 16; i++) this->m[i] = matrix[i]; + for (int i = 0; i < 4; i++) this->color[i] = color[i]; refcounter = 1; } @@ -191,10 +191,11 @@ CSGChain::CSGChain() { } -void CSGChain::add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label) +void CSGChain::add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, QString label) { polysets.append(polyset); matrices.append(m); + colors.append(color); types.append(type); labels.append(label); } @@ -202,7 +203,7 @@ void CSGChain::add(PolySet *polyset, double *m, CSGTerm::type_e type, QString la void CSGChain::import(CSGTerm *term, CSGTerm::type_e type) { if (term->type == CSGTerm::TYPE_PRIMITIVE) { - add(term->polyset, term->m, type, term->label); + add(term->polyset, term->m, term->color, type, term->label); } else { import(term->left, type); import(term->right, term->type); diff --git a/src/csgterm.h b/src/csgterm.h index c1dc0fd..b0fffe4 100644 --- a/src/csgterm.h +++ b/src/csgterm.h @@ -20,10 +20,11 @@ public: QString label; CSGTerm *left; CSGTerm *right; - double m[20]; + double m[16]; + double color[4]; int refcounter; - CSGTerm(PolySet *polyset, const double m[20], QString label); + CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], QString label); CSGTerm(type_e type, CSGTerm *left, CSGTerm *right); CSGTerm *normalize(); @@ -39,12 +40,13 @@ class CSGChain public: QVector polysets; QVector matrices; + QVector colors; QVector types; QVector labels; CSGChain(); - void add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label); + void add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, QString label); void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); QString dump(); diff --git a/src/module.cc b/src/module.cc index 81dddf9..0f1b1aa 100644 --- a/src/module.cc +++ b/src/module.cc @@ -206,6 +206,7 @@ void initialize_builtin_modules() register_builtin_csgops(); register_builtin_transform(); + register_builtin_color(); register_builtin_primitives(); register_builtin_surface(); register_builtin_control(); diff --git a/src/state.h b/src/state.h index c81575a..69aee87 100644 --- a/src/state.h +++ b/src/state.h @@ -9,7 +9,7 @@ public: State(const class AbstractNode *parent) : parentnode(parent), isprefix(false), ispostfix(false), numchildren(0) { for (int i=0;i<16;i++) this->m[i] = i % 5 == 0 ? 1.0 : 0.0; - for (int i=16;i<20;i++) this->m[i] = -1.0; + for (int i=0;i<4;i++) this->c[i] = -1.0; } virtual ~State() {} @@ -17,13 +17,15 @@ public: void setPostfix(bool on) { this->ispostfix = on; } void setNumChildren(unsigned int numc) { this->numchildren = numc; } void setParent(const AbstractNode *parent) { this->parentnode = parent; } - void setMatrix(const double m[20]) { memcpy(this->m, m, 20*sizeof(m)); } + void setMatrix(const double m[16]) { memcpy(this->m, m, 16*sizeof(double)); } + void setColor(const double c[4]) { memcpy(this->c, c, 4*sizeof(double)); } bool isPrefix() const { return this->isprefix; } bool isPostfix() const { return this->ispostfix; } unsigned int numChildren() const { return this->numchildren; } const AbstractNode *parent() const { return this->parentnode; } const double *matrix() const { return this->m; } + const double *color() const { return this->c; } private: const AbstractNode * parentnode; @@ -31,8 +33,9 @@ private: bool ispostfix; unsigned int numchildren; - // Transformation matrix incl. color. FIXME: Generalize such state variables? - double m[20]; + // Transformation matrix and color. FIXME: Generalize such state variables? + double m[16]; + double c[4]; }; #endif diff --git a/src/transform.cc b/src/transform.cc index 7459765..07aaee8 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -43,8 +43,7 @@ enum transform_type_e { ROTATE, MIRROR, TRANSLATE, - MULTMATRIX, - COLOR + MULTMATRIX }; class TransformModule : public AbstractModule @@ -86,8 +85,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti for (int i = 0; i < 16; i++) node->matrix[i] = i % 5 == 0 ? 1.0 : 0.0; - for (int i = 16; i < 20; i++) - node->matrix[i] = -1; QVector argnames; QVector argexpr; @@ -108,9 +105,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti case MULTMATRIX: argnames = QVector() << "m"; break; - case COLOR: - argnames = QVector() << "c" << "alpha"; - break; default: assert(false); } @@ -242,36 +236,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti } } } - else if (this->type == COLOR) - { - Value v = c.lookup_variable("c"); - if (v.type == Value::VECTOR) { - for (int i = 0; i < 4; i++) - node->matrix[16+i] = i < v.vec.size() ? v.vec[i]->num : 1.0; -// FIXME: Port to non-Qt -#if 0 - } else if (v.type == Value::STRING) { - QString colorname = v.text; - QColor color; - color.setNamedColor(colorname); - if (color.isValid()) { - node->matrix[16+0] = color.redF(); - node->matrix[16+1] = color.greenF(); - node->matrix[16+2] = color.blueF(); - } else { - PRINTF_NOCACHE("WARNING: Color name \"%s\" unknown. Please see",v.text.toUtf8().data()); - PRINTF_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors"); - } -#endif - } - // FIXME: Only lookup alpha if color was set - Value alpha = c.lookup_variable("alpha"); - if (alpha.type == Value::NUMBER) { - node->matrix[16+3] = alpha.num; - } else { - node->matrix[16+3] = 1.0; - } - } foreach (ModuleInstantiation *v, inst->children) { AbstractNode *n = v->evaluate(inst->ctx); @@ -286,23 +250,18 @@ string TransformNode::toString() const { std::stringstream stream; - if (this->matrix[16] >= 0 || this->matrix[17] >= 0 || this->matrix[18] >= 0 || this->matrix[19] >= 0) { - stream << "color([" << this->matrix[16] << ", " << this->matrix[17] << ", " << this->matrix[18] << ", " << this->matrix[19] << "])"; - } - else { - stream << "multmatrix(["; - for (int j=0;j<4;j++) { - stream << "["; - for (int i=0;i<4;i++) { - // FIXME: The 0 test is to avoid a leading minus before a single 0 (cosmetics) - stream << ((this->matrix[i*4+j]==0)?0:this->matrix[i*4+j]); - if (i != 3) stream << ", "; - } - stream << "]"; - if (j != 3) stream << ", "; + stream << "multmatrix(["; + for (int j=0;j<4;j++) { + stream << "["; + for (int i=0;i<4;i++) { + // FIXME: The 0 test is to avoid a leading minus before a single 0 (cosmetics) + stream << ((this->matrix[i*4+j]==0)?0:this->matrix[i*4+j]); + if (i != 3) stream << ", "; } - stream << "])"; + stream << "]"; + if (j != 3) stream << ", "; } + stream << "])"; return stream.str(); } @@ -319,5 +278,4 @@ void register_builtin_transform() builtin_modules["mirror"] = new TransformModule(MIRROR); builtin_modules["translate"] = new TransformModule(TRANSLATE); builtin_modules["multmatrix"] = new TransformModule(MULTMATRIX); - builtin_modules["color"] = new TransformModule(COLOR); } diff --git a/src/transformnode.h b/src/transformnode.h index 9afa9be..9d822cb 100644 --- a/src/transformnode.h +++ b/src/transformnode.h @@ -14,7 +14,7 @@ public: virtual std::string toString() const; virtual std::string name() const; - double matrix[20]; + double matrix[16]; }; #endif diff --git a/src/visitor.h b/src/visitor.h index 63f5d08..f4846b8 100644 --- a/src/visitor.h +++ b/src/visitor.h @@ -46,6 +46,9 @@ public: virtual Response visit(class State &state, const class TransformNode &node) { return visit(state, (const class AbstractNode &)node); } + virtual Response visit(class State &state, const class ColorNode &node) { + return visit(state, (const class AbstractNode &)node); + } // Add visit() methods for new visitable subtypes of AbstractNode here }; -- cgit v0.10.1 From 21c5d879ff1c8f0dfb221d6010c610a364f1e858 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 23:39:39 +0200 Subject: Added expected files for csgtermtest diff --git a/tests/regression/csgtermtest/allmodules-expected.txt b/tests/regression/csgtermtest/allmodules-expected.txt new file mode 100644 index 0000000..fd366e0 --- /dev/null +++ b/tests/regression/csgtermtest/allmodules-expected.txt @@ -0,0 +1 @@ +(((((((((((((((linear_extrude14 + linear_extrude15) + rotate_extrude16) + rotate_extrude17) + import_stl18) + import_off19) + import_dxf20) + cube22) + sphere23) + cylinder24) + polyhedron25) + square26) + circle27) + polygon28) + projection29) + surface31) diff --git a/tests/regression/csgtermtest/assign-expected.txt b/tests/regression/csgtermtest/assign-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/assign-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/child-expected.txt b/tests/regression/csgtermtest/child-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/child-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/circle-expected.txt b/tests/regression/csgtermtest/circle-expected.txt new file mode 100644 index 0000000..b8c8161 --- /dev/null +++ b/tests/regression/csgtermtest/circle-expected.txt @@ -0,0 +1 @@ +circle2 diff --git a/tests/regression/csgtermtest/color-expected.txt b/tests/regression/csgtermtest/color-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/color-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/cube-expected.txt b/tests/regression/csgtermtest/cube-expected.txt new file mode 100644 index 0000000..3393bc4 --- /dev/null +++ b/tests/regression/csgtermtest/cube-expected.txt @@ -0,0 +1 @@ +cube2 diff --git a/tests/regression/csgtermtest/cylinder-expected.txt b/tests/regression/csgtermtest/cylinder-expected.txt new file mode 100644 index 0000000..f3dd1f9 --- /dev/null +++ b/tests/regression/csgtermtest/cylinder-expected.txt @@ -0,0 +1 @@ +cylinder2 diff --git a/tests/regression/csgtermtest/difference-expected.txt b/tests/regression/csgtermtest/difference-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/difference-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/dxf_linear_extrude-expected.txt b/tests/regression/csgtermtest/dxf_linear_extrude-expected.txt new file mode 100644 index 0000000..bebcc7a --- /dev/null +++ b/tests/regression/csgtermtest/dxf_linear_extrude-expected.txt @@ -0,0 +1 @@ +linear_extrude2 diff --git a/tests/regression/csgtermtest/dxf_rotate_extrude-expected.txt b/tests/regression/csgtermtest/dxf_rotate_extrude-expected.txt new file mode 100644 index 0000000..318aa70 --- /dev/null +++ b/tests/regression/csgtermtest/dxf_rotate_extrude-expected.txt @@ -0,0 +1 @@ +rotate_extrude2 diff --git a/tests/regression/csgtermtest/echo-expected.txt b/tests/regression/csgtermtest/echo-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/echo-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/for-expected.txt b/tests/regression/csgtermtest/for-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/for-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/glide-expected.txt b/tests/regression/csgtermtest/glide-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/glide-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/group-expected.txt b/tests/regression/csgtermtest/group-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/group-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/hull-expected.txt b/tests/regression/csgtermtest/hull-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/hull-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/if-expected.txt b/tests/regression/csgtermtest/if-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/if-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/import_dxf-expected.txt b/tests/regression/csgtermtest/import_dxf-expected.txt new file mode 100644 index 0000000..edf214d --- /dev/null +++ b/tests/regression/csgtermtest/import_dxf-expected.txt @@ -0,0 +1 @@ +import_dxf2 diff --git a/tests/regression/csgtermtest/import_off-expected.txt b/tests/regression/csgtermtest/import_off-expected.txt new file mode 100644 index 0000000..a8c4d8f --- /dev/null +++ b/tests/regression/csgtermtest/import_off-expected.txt @@ -0,0 +1 @@ +import_off2 diff --git a/tests/regression/csgtermtest/import_stl-expected.txt b/tests/regression/csgtermtest/import_stl-expected.txt new file mode 100644 index 0000000..fe69d31 --- /dev/null +++ b/tests/regression/csgtermtest/import_stl-expected.txt @@ -0,0 +1 @@ +import_stl2 diff --git a/tests/regression/csgtermtest/intersection-expected.txt b/tests/regression/csgtermtest/intersection-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/intersection-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/intersection_for-expected.txt b/tests/regression/csgtermtest/intersection_for-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/intersection_for-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/linear_extrude-expected.txt b/tests/regression/csgtermtest/linear_extrude-expected.txt new file mode 100644 index 0000000..bebcc7a --- /dev/null +++ b/tests/regression/csgtermtest/linear_extrude-expected.txt @@ -0,0 +1 @@ +linear_extrude2 diff --git a/tests/regression/csgtermtest/minkowski-expected.txt b/tests/regression/csgtermtest/minkowski-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/minkowski-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/mirror-expected.txt b/tests/regression/csgtermtest/mirror-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/mirror-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/multmatrix-expected.txt b/tests/regression/csgtermtest/multmatrix-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/multmatrix-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/polygon-expected.txt b/tests/regression/csgtermtest/polygon-expected.txt new file mode 100644 index 0000000..b41dfc6 --- /dev/null +++ b/tests/regression/csgtermtest/polygon-expected.txt @@ -0,0 +1 @@ +polygon2 diff --git a/tests/regression/csgtermtest/polyhedron-expected.txt b/tests/regression/csgtermtest/polyhedron-expected.txt new file mode 100644 index 0000000..5ccc055 --- /dev/null +++ b/tests/regression/csgtermtest/polyhedron-expected.txt @@ -0,0 +1 @@ +polyhedron2 diff --git a/tests/regression/csgtermtest/projection-expected.txt b/tests/regression/csgtermtest/projection-expected.txt new file mode 100644 index 0000000..2a4c47e --- /dev/null +++ b/tests/regression/csgtermtest/projection-expected.txt @@ -0,0 +1 @@ +projection2 diff --git a/tests/regression/csgtermtest/render-expected.txt b/tests/regression/csgtermtest/render-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/render-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/rotate-expected.txt b/tests/regression/csgtermtest/rotate-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/rotate-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/rotate_extrude-expected.txt b/tests/regression/csgtermtest/rotate_extrude-expected.txt new file mode 100644 index 0000000..318aa70 --- /dev/null +++ b/tests/regression/csgtermtest/rotate_extrude-expected.txt @@ -0,0 +1 @@ +rotate_extrude2 diff --git a/tests/regression/csgtermtest/scale-expected.txt b/tests/regression/csgtermtest/scale-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/scale-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/sphere-expected.txt b/tests/regression/csgtermtest/sphere-expected.txt new file mode 100644 index 0000000..f9b8d73 --- /dev/null +++ b/tests/regression/csgtermtest/sphere-expected.txt @@ -0,0 +1 @@ +sphere2 diff --git a/tests/regression/csgtermtest/square-expected.txt b/tests/regression/csgtermtest/square-expected.txt new file mode 100644 index 0000000..8190c0f --- /dev/null +++ b/tests/regression/csgtermtest/square-expected.txt @@ -0,0 +1 @@ +square2 diff --git a/tests/regression/csgtermtest/subdiv-expected.txt b/tests/regression/csgtermtest/subdiv-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/subdiv-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/surface-expected.txt b/tests/regression/csgtermtest/surface-expected.txt new file mode 100644 index 0000000..d0e3459 --- /dev/null +++ b/tests/regression/csgtermtest/surface-expected.txt @@ -0,0 +1 @@ +surface2 diff --git a/tests/regression/csgtermtest/transform-insert-expected.txt b/tests/regression/csgtermtest/transform-insert-expected.txt new file mode 100644 index 0000000..edf214d --- /dev/null +++ b/tests/regression/csgtermtest/transform-insert-expected.txt @@ -0,0 +1 @@ +import_dxf2 diff --git a/tests/regression/csgtermtest/translate-expected.txt b/tests/regression/csgtermtest/translate-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/translate-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtermtest/union-expected.txt b/tests/regression/csgtermtest/union-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/union-expected.txt @@ -0,0 +1 @@ +No top-level CSG object -- cgit v0.10.1 From 34e22b1bde06eb111eefcbfe5faa028ce9d5f9eb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 23:40:17 +0200 Subject: Updated color output to updated code diff --git a/tests/regression/dumptest/allmodules-expected.txt b/tests/regression/dumptest/allmodules-expected.txt index b51fae3..2849d7a 100644 --- a/tests/regression/dumptest/allmodules-expected.txt +++ b/tests/regression/dumptest/allmodules-expected.txt @@ -34,5 +34,5 @@ group() { multmatrix([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); - multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); + color([-1, -1, -1, 1]); } diff --git a/tests/regression/dumptest/color-expected.txt b/tests/regression/dumptest/color-expected.txt index 87e28e2..ef862fc 100644 --- a/tests/regression/dumptest/color-expected.txt +++ b/tests/regression/dumptest/color-expected.txt @@ -1,3 +1,3 @@ group() { - multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); + color([-1, -1, -1, 1]); } -- cgit v0.10.1 From 8685ce946bc455c49f0b0149fe7657f8dd068e3e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 23:54:41 +0200 Subject: Added color.cc diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a985ce7..30879f7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -90,6 +90,7 @@ set(COMMON_SOURCES ../src/polyset.cc ../src/csgops.cc ../src/transform.cc + ../src/color.cc ../src/primitives.cc ../src/projection.cc ../src/cgaladv.cc -- cgit v0.10.1 From f31d7b7596debfdc37ac6df90df8c3e4fc3a142a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 2 Sep 2011 23:54:56 +0200 Subject: Updated color node to latest version diff --git a/tests/regression/csgtexttest/allmodules-expected.txt b/tests/regression/csgtexttest/allmodules-expected.txt index 6b13f07..2595e02 100644 --- a/tests/regression/csgtexttest/allmodules-expected.txt +++ b/tests/regression/csgtexttest/allmodules-expected.txt @@ -1 +1 @@ -group1(minkowski2+glide3+subdiv4+hull5+group6+group6+group6+intersection_for9+group6+union11+difference12+intersection13+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import_stl+import_off+import_dxf+group6+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render30+surface+transform32+transform32+transform34+transform32+transform32+transform37) +group1(minkowski2+glide3+subdiv4+hull5+group6+group6+group6+intersection_for9+group6+union11+difference12+intersection13+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import_stl+import_off+import_dxf+group6+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render30+surface+transform32+transform32+transform34+transform32+transform32+color37) diff --git a/tests/regression/csgtexttest/color-expected.txt b/tests/regression/csgtexttest/color-expected.txt index 80024d2..6140174 100644 --- a/tests/regression/csgtexttest/color-expected.txt +++ b/tests/regression/csgtexttest/color-expected.txt @@ -1 +1 @@ -group1(transform2) +group1(color2) diff --git a/tests/regression/dumptest/allmodules-expected.txt b/tests/regression/dumptest/allmodules-expected.txt index 2849d7a..50c6605 100644 --- a/tests/regression/dumptest/allmodules-expected.txt +++ b/tests/regression/dumptest/allmodules-expected.txt @@ -34,5 +34,5 @@ group() { multmatrix([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); - color([-1, -1, -1, 1]); + color([-1, -1, -1, -1]); } diff --git a/tests/regression/dumptest/color-expected.txt b/tests/regression/dumptest/color-expected.txt index ef862fc..375ed05 100644 --- a/tests/regression/dumptest/color-expected.txt +++ b/tests/regression/dumptest/color-expected.txt @@ -1,3 +1,3 @@ group() { - color([-1, -1, -1, 1]); + color([-1, -1, -1, -1]); } -- cgit v0.10.1 From 3bd03237391c5bf13271d48adfe0357f8873fbb2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 00:01:22 +0200 Subject: diagram update diff --git a/doc/OpenSCAD-classes.graffle b/doc/OpenSCAD-classes.graffle index ef8c1b8..e067521 100644 Binary files a/doc/OpenSCAD-classes.graffle and b/doc/OpenSCAD-classes.graffle differ diff --git a/doc/OpenSCAD-classes.pdf b/doc/OpenSCAD-classes.pdf index 5870db0..04b62a9 100644 Binary files a/doc/OpenSCAD-classes.pdf and b/doc/OpenSCAD-classes.pdf differ diff --git a/doc/OpenSCAD-compile.graffle b/doc/OpenSCAD-compile.graffle index bb505c3..9a09fc3 100644 Binary files a/doc/OpenSCAD-compile.graffle and b/doc/OpenSCAD-compile.graffle differ diff --git a/doc/OpenSCAD-compile.pdf b/doc/OpenSCAD-compile.pdf index 2c9730d..efc7134 100644 Binary files a/doc/OpenSCAD-compile.pdf and b/doc/OpenSCAD-compile.pdf differ diff --git a/doc/OpenSCAD-csg.graffle b/doc/OpenSCAD-csg.graffle index ca0a0ff..507c694 100644 Binary files a/doc/OpenSCAD-csg.graffle and b/doc/OpenSCAD-csg.graffle differ diff --git a/doc/OpenSCAD-csg.pdf b/doc/OpenSCAD-csg.pdf new file mode 100644 index 0000000..0304cf7 Binary files /dev/null and b/doc/OpenSCAD-csg.pdf differ diff --git a/doc/OpenSCAD-polygons.pdf b/doc/OpenSCAD-polygons.pdf index d2eaa3b..ac18baf 100644 Binary files a/doc/OpenSCAD-polygons.pdf and b/doc/OpenSCAD-polygons.pdf differ -- cgit v0.10.1 From 4afdde51f45de5f35040b44680d306103888cdc9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 01:50:29 +0200 Subject: Added test for named color without alpha diff --git a/testdata/scad/features/color-tests.scad b/testdata/scad/features/color-tests.scad index a87dad3..67d65d0 100644 --- a/testdata/scad/features/color-tests.scad +++ b/testdata/scad/features/color-tests.scad @@ -2,7 +2,7 @@ module object() cube([10,10,10]); translate([12,12,0]) object(); color([1,0,0]) translate([24,12,0]) object(); -translate([0,12,0]) color([0,1,1]) object(); +translate([0,12,0]) color("Purple") object(); color([0,0,1,0.5]) object(); translate([12,0,0]) color([0,0,1],0.5) object(); translate([24,0,0]) color(c="Green",alpha=0.2) object(); -- cgit v0.10.1 From c6209f15b70f743bace2bf21e2801b9e5238ada8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 01:53:00 +0200 Subject: disable setting alpha without color diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index d624a5f..f07b900 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -93,7 +93,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), m, shaderinfo); } else if (background) { chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), m, shaderinfo); - } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { + } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0) { // User-defined color from source glColor4dv(c); if (shaderinfo) { diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 92a504a..598d542 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -92,7 +92,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, } else { chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); } - } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { + } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0) { glColor4dv(c); chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); if (showedges) { diff --git a/src/color.cc b/src/color.cc index a3c8101..7340612 100644 --- a/src/color.cc +++ b/src/color.cc @@ -47,7 +47,8 @@ AbstractNode *ColorModule::evaluate(const Context *ctx, const ModuleInstantiatio { ColorNode *node = new ColorNode(inst); - for (int i = 0; i < 4; i++) node->color[i] = -1; + node->color[0] = node->color[1] = node->color[2] = -1.0; + node->color[3] = 1.0; QVector argnames; QVector argexpr; -- cgit v0.10.1 From aeceee220844c5d6bd9a414604195f0c3f86169d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 01:53:36 +0200 Subject: Moved testcolornames to features diff --git a/testdata/scad/features/testcolornames.scad b/testdata/scad/features/testcolornames.scad new file mode 100644 index 0000000..b9ad334 --- /dev/null +++ b/testdata/scad/features/testcolornames.scad @@ -0,0 +1,159 @@ +/* color samples for SVG named colors, for OpenSCAD +Please see http://en.wikipedia.org/wiki/Web_colors +and http://www.w3.org/TR/SVG/types.html#ColorKeywords +for more information. */ + +$fn=5; +radius=0.8; +//translate([0,0]) color("Red colors") sphere(radius); +translate([1,0]) color("IndianRed") sphere(radius); +translate([2,0]) color("LightCoral") sphere(radius); +translate([3,0]) color("Salmon") sphere(radius); +translate([4,0]) color("DarkSalmon") sphere(radius); +translate([5,0]) color("LightSalmon") sphere(radius); +translate([6,0]) color("Red") sphere(radius); +translate([7,0]) color("Crimson") sphere(radius); +translate([8,0]) color("FireBrick") sphere(radius); +translate([9,0]) color("DarkRed") sphere(radius); +//translate([10,0]) color("Pink colors") sphere(radius); +translate([0,1]) color("Pink") sphere(radius); +translate([1,1]) color("LightPink") sphere(radius); +translate([2,1]) color("HotPink") sphere(radius); +translate([3,1]) color("DeepPink") sphere(radius); +translate([4,1]) color("MediumVioletRed") sphere(radius); +translate([5,1]) color("PaleVioletRed") sphere(radius); +//translate([6,1]) color("Orange colors") sphere(radius); +translate([7,1]) color("LightSalmon") sphere(radius); +translate([8,1]) color("Coral") sphere(radius); +translate([9,1]) color("Tomato") sphere(radius); +translate([10,1]) color("OrangeRed") sphere(radius); +translate([0,2]) color("DarkOrange") sphere(radius); +translate([1,2]) color("Orange") sphere(radius); +//translate([2,2]) color("Yellow colors") sphere(radius); +translate([3,2]) color("Gold") sphere(radius); +translate([4,2]) color("Yellow") sphere(radius); +translate([5,2]) color("LightYellow") sphere(radius); +translate([6,2]) color("LemonChiffon") sphere(radius); +translate([7,2]) color("LightGoldenrodYellow") sphere(radius); +translate([8,2]) color("PapayaWhip") sphere(radius); +translate([9,2]) color("Moccasin") sphere(radius); +translate([10,2]) color("PeachPuff") sphere(radius); +translate([0,3]) color("PaleGoldenrod") sphere(radius); +translate([1,3]) color("Khaki") sphere(radius); +translate([2,3]) color("DarkKhaki") sphere(radius); +//translate([3,3]) color("Purple colors") sphere(radius); +translate([4,3]) color("Lavender") sphere(radius); +translate([5,3]) color("Thistle") sphere(radius); +translate([6,3]) color("Plum") sphere(radius); +translate([7,3]) color("Violet") sphere(radius); +translate([8,3]) color("Orchid") sphere(radius); +translate([9,3]) color("Fuchsia") sphere(radius); +translate([10,3]) color("Magenta") sphere(radius); +translate([0,4]) color("MediumOrchid") sphere(radius); +translate([1,4]) color("MediumPurple") sphere(radius); +translate([2,4]) color("BlueViolet") sphere(radius); +translate([3,4]) color("DarkViolet") sphere(radius); +translate([4,4]) color("DarkOrchid") sphere(radius); +translate([5,4]) color("DarkMagenta") sphere(radius); +translate([6,4]) color("Purple") sphere(radius); +translate([7,4]) color("Indigo") sphere(radius); +translate([8,4]) color("DarkSlateBlue") sphere(radius); +translate([9,4]) color("SlateBlue") sphere(radius); +translate([10,4]) color("MediumSlateBlue") sphere(radius); +//translate([0,5]) color("Green colors") sphere(radius); +translate([1,5]) color("GreenYellow") sphere(radius); +translate([2,5]) color("Chartreuse") sphere(radius); +translate([3,5]) color("LawnGreen") sphere(radius); +translate([4,5]) color("Lime") sphere(radius); +translate([5,5]) color("LimeGreen") sphere(radius); +translate([6,5]) color("PaleGreen") sphere(radius); +translate([7,5]) color("LightGreen") sphere(radius); +translate([8,5]) color("MediumSpringGreen") sphere(radius); +translate([9,5]) color("SpringGreen") sphere(radius); +translate([10,5]) color("MediumSeaGreen") sphere(radius); +translate([0,6]) color("SeaGreen") sphere(radius); +translate([1,6]) color("ForestGreen") sphere(radius); +translate([2,6]) color("Green") sphere(radius); +translate([3,6]) color("DarkGreen") sphere(radius); +translate([4,6]) color("YellowGreen") sphere(radius); +translate([5,6]) color("OliveDrab") sphere(radius); +translate([6,6]) color("Olive") sphere(radius); +translate([7,6]) color("DarkOliveGreen") sphere(radius); +translate([8,6]) color("MediumAquamarine") sphere(radius); +translate([9,6]) color("DarkSeaGreen") sphere(radius); +translate([10,6]) color("LightSeaGreen") sphere(radius); +translate([0,7]) color("DarkCyan") sphere(radius); +translate([1,7]) color("Teal") sphere(radius); +//translate([2,7]) color("Blue/Cyan colors") sphere(radius); +translate([3,7]) color("Aqua") sphere(radius); +translate([4,7]) color("Cyan") sphere(radius); +translate([5,7]) color("LightCyan") sphere(radius); +translate([6,7]) color("PaleTurquoise") sphere(radius); +translate([7,7]) color("Aquamarine") sphere(radius); +translate([8,7]) color("Turquoise") sphere(radius); +translate([9,7]) color("MediumTurquoise") sphere(radius); +translate([10,7]) color("DarkTurquoise") sphere(radius); +translate([0,8]) color("CadetBlue") sphere(radius); +translate([1,8]) color("SteelBlue") sphere(radius); +translate([2,8]) color("LightSteelBlue") sphere(radius); +translate([3,8]) color("PowderBlue") sphere(radius); +translate([4,8]) color("LightBlue") sphere(radius); +translate([5,8]) color("SkyBlue") sphere(radius); +translate([6,8]) color("LightSkyBlue") sphere(radius); +translate([7,8]) color("DeepSkyBlue") sphere(radius); +translate([8,8]) color("DodgerBlue") sphere(radius); +translate([9,8]) color("CornflowerBlue") sphere(radius); +translate([10,8]) color("RoyalBlue") sphere(radius); +translate([0,9]) color("Blue") sphere(radius); +translate([1,9]) color("MediumBlue") sphere(radius); +translate([2,9]) color("DarkBlue") sphere(radius); +translate([3,9]) color("Navy") sphere(radius); +translate([4,9]) color("MidnightBlue") sphere(radius); +//translate([5,9]) color("Brown colors") sphere(radius); +translate([6,9]) color("Cornsilk") sphere(radius); +translate([7,9]) color("BlanchedAlmond") sphere(radius); +translate([8,9]) color("Bisque") sphere(radius); +translate([9,9]) color("NavajoWhite") sphere(radius); +translate([10,9]) color("Wheat") sphere(radius); +translate([0,10]) color("BurlyWood") sphere(radius); +translate([1,10]) color("Tan") sphere(radius); +translate([2,10]) color("RosyBrown") sphere(radius); +translate([3,10]) color("SandyBrown") sphere(radius); +translate([4,10]) color("Goldenrod") sphere(radius); +translate([5,10]) color("DarkGoldenrod") sphere(radius); +translate([6,10]) color("Peru") sphere(radius); +translate([7,10]) color("Chocolate") sphere(radius); +translate([8,10]) color("SaddleBrown") sphere(radius); +translate([9,10]) color("Sienna") sphere(radius); +translate([10,10]) color("Brown") sphere(radius); +translate([0,11]) color("Maroon") sphere(radius); +//translate([1,11]) color("White colors") sphere(radius); +translate([2,11]) color("White") sphere(radius); +translate([3,11]) color("Snow") sphere(radius); +translate([4,11]) color("Honeydew") sphere(radius); +translate([5,11]) color("MintCream") sphere(radius); +translate([6,11]) color("Azure") sphere(radius); +translate([7,11]) color("AliceBlue") sphere(radius); +translate([8,11]) color("GhostWhite") sphere(radius); +translate([9,11]) color("WhiteSmoke") sphere(radius); +translate([10,11]) color("Seashell") sphere(radius); +translate([0,12]) color("Beige") sphere(radius); +translate([1,12]) color("OldLace") sphere(radius); +translate([2,12]) color("FloralWhite") sphere(radius); +translate([3,12]) color("Ivory") sphere(radius); +translate([4,12]) color("AntiqueWhite") sphere(radius); +translate([5,12]) color("Linen") sphere(radius); +translate([6,12]) color("LavenderBlush") sphere(radius); +translate([7,12]) color("MistyRose") sphere(radius); +//translate([8,12]) color("Gray colors") sphere(radius); +translate([9,12]) color("Gainsboro") sphere(radius); +translate([10,12]) color("LightGrey") sphere(radius); +translate([0,13]) color("Silver") sphere(radius); +translate([1,13]) color("DarkGray") sphere(radius); +translate([2,13]) color("Gray") sphere(radius); +translate([3,13]) color("DimGray") sphere(radius); +translate([4,13]) color("LightSlateGray") sphere(radius); +translate([5,13]) color("SlateGray") sphere(radius); +translate([6,13]) color("DarkSlateGray") sphere(radius); +translate([7,13]) color("Black") sphere(radius); + diff --git a/testdata/scad/testcolornames.scad b/testdata/scad/testcolornames.scad deleted file mode 100644 index b9ad334..0000000 --- a/testdata/scad/testcolornames.scad +++ /dev/null @@ -1,159 +0,0 @@ -/* color samples for SVG named colors, for OpenSCAD -Please see http://en.wikipedia.org/wiki/Web_colors -and http://www.w3.org/TR/SVG/types.html#ColorKeywords -for more information. */ - -$fn=5; -radius=0.8; -//translate([0,0]) color("Red colors") sphere(radius); -translate([1,0]) color("IndianRed") sphere(radius); -translate([2,0]) color("LightCoral") sphere(radius); -translate([3,0]) color("Salmon") sphere(radius); -translate([4,0]) color("DarkSalmon") sphere(radius); -translate([5,0]) color("LightSalmon") sphere(radius); -translate([6,0]) color("Red") sphere(radius); -translate([7,0]) color("Crimson") sphere(radius); -translate([8,0]) color("FireBrick") sphere(radius); -translate([9,0]) color("DarkRed") sphere(radius); -//translate([10,0]) color("Pink colors") sphere(radius); -translate([0,1]) color("Pink") sphere(radius); -translate([1,1]) color("LightPink") sphere(radius); -translate([2,1]) color("HotPink") sphere(radius); -translate([3,1]) color("DeepPink") sphere(radius); -translate([4,1]) color("MediumVioletRed") sphere(radius); -translate([5,1]) color("PaleVioletRed") sphere(radius); -//translate([6,1]) color("Orange colors") sphere(radius); -translate([7,1]) color("LightSalmon") sphere(radius); -translate([8,1]) color("Coral") sphere(radius); -translate([9,1]) color("Tomato") sphere(radius); -translate([10,1]) color("OrangeRed") sphere(radius); -translate([0,2]) color("DarkOrange") sphere(radius); -translate([1,2]) color("Orange") sphere(radius); -//translate([2,2]) color("Yellow colors") sphere(radius); -translate([3,2]) color("Gold") sphere(radius); -translate([4,2]) color("Yellow") sphere(radius); -translate([5,2]) color("LightYellow") sphere(radius); -translate([6,2]) color("LemonChiffon") sphere(radius); -translate([7,2]) color("LightGoldenrodYellow") sphere(radius); -translate([8,2]) color("PapayaWhip") sphere(radius); -translate([9,2]) color("Moccasin") sphere(radius); -translate([10,2]) color("PeachPuff") sphere(radius); -translate([0,3]) color("PaleGoldenrod") sphere(radius); -translate([1,3]) color("Khaki") sphere(radius); -translate([2,3]) color("DarkKhaki") sphere(radius); -//translate([3,3]) color("Purple colors") sphere(radius); -translate([4,3]) color("Lavender") sphere(radius); -translate([5,3]) color("Thistle") sphere(radius); -translate([6,3]) color("Plum") sphere(radius); -translate([7,3]) color("Violet") sphere(radius); -translate([8,3]) color("Orchid") sphere(radius); -translate([9,3]) color("Fuchsia") sphere(radius); -translate([10,3]) color("Magenta") sphere(radius); -translate([0,4]) color("MediumOrchid") sphere(radius); -translate([1,4]) color("MediumPurple") sphere(radius); -translate([2,4]) color("BlueViolet") sphere(radius); -translate([3,4]) color("DarkViolet") sphere(radius); -translate([4,4]) color("DarkOrchid") sphere(radius); -translate([5,4]) color("DarkMagenta") sphere(radius); -translate([6,4]) color("Purple") sphere(radius); -translate([7,4]) color("Indigo") sphere(radius); -translate([8,4]) color("DarkSlateBlue") sphere(radius); -translate([9,4]) color("SlateBlue") sphere(radius); -translate([10,4]) color("MediumSlateBlue") sphere(radius); -//translate([0,5]) color("Green colors") sphere(radius); -translate([1,5]) color("GreenYellow") sphere(radius); -translate([2,5]) color("Chartreuse") sphere(radius); -translate([3,5]) color("LawnGreen") sphere(radius); -translate([4,5]) color("Lime") sphere(radius); -translate([5,5]) color("LimeGreen") sphere(radius); -translate([6,5]) color("PaleGreen") sphere(radius); -translate([7,5]) color("LightGreen") sphere(radius); -translate([8,5]) color("MediumSpringGreen") sphere(radius); -translate([9,5]) color("SpringGreen") sphere(radius); -translate([10,5]) color("MediumSeaGreen") sphere(radius); -translate([0,6]) color("SeaGreen") sphere(radius); -translate([1,6]) color("ForestGreen") sphere(radius); -translate([2,6]) color("Green") sphere(radius); -translate([3,6]) color("DarkGreen") sphere(radius); -translate([4,6]) color("YellowGreen") sphere(radius); -translate([5,6]) color("OliveDrab") sphere(radius); -translate([6,6]) color("Olive") sphere(radius); -translate([7,6]) color("DarkOliveGreen") sphere(radius); -translate([8,6]) color("MediumAquamarine") sphere(radius); -translate([9,6]) color("DarkSeaGreen") sphere(radius); -translate([10,6]) color("LightSeaGreen") sphere(radius); -translate([0,7]) color("DarkCyan") sphere(radius); -translate([1,7]) color("Teal") sphere(radius); -//translate([2,7]) color("Blue/Cyan colors") sphere(radius); -translate([3,7]) color("Aqua") sphere(radius); -translate([4,7]) color("Cyan") sphere(radius); -translate([5,7]) color("LightCyan") sphere(radius); -translate([6,7]) color("PaleTurquoise") sphere(radius); -translate([7,7]) color("Aquamarine") sphere(radius); -translate([8,7]) color("Turquoise") sphere(radius); -translate([9,7]) color("MediumTurquoise") sphere(radius); -translate([10,7]) color("DarkTurquoise") sphere(radius); -translate([0,8]) color("CadetBlue") sphere(radius); -translate([1,8]) color("SteelBlue") sphere(radius); -translate([2,8]) color("LightSteelBlue") sphere(radius); -translate([3,8]) color("PowderBlue") sphere(radius); -translate([4,8]) color("LightBlue") sphere(radius); -translate([5,8]) color("SkyBlue") sphere(radius); -translate([6,8]) color("LightSkyBlue") sphere(radius); -translate([7,8]) color("DeepSkyBlue") sphere(radius); -translate([8,8]) color("DodgerBlue") sphere(radius); -translate([9,8]) color("CornflowerBlue") sphere(radius); -translate([10,8]) color("RoyalBlue") sphere(radius); -translate([0,9]) color("Blue") sphere(radius); -translate([1,9]) color("MediumBlue") sphere(radius); -translate([2,9]) color("DarkBlue") sphere(radius); -translate([3,9]) color("Navy") sphere(radius); -translate([4,9]) color("MidnightBlue") sphere(radius); -//translate([5,9]) color("Brown colors") sphere(radius); -translate([6,9]) color("Cornsilk") sphere(radius); -translate([7,9]) color("BlanchedAlmond") sphere(radius); -translate([8,9]) color("Bisque") sphere(radius); -translate([9,9]) color("NavajoWhite") sphere(radius); -translate([10,9]) color("Wheat") sphere(radius); -translate([0,10]) color("BurlyWood") sphere(radius); -translate([1,10]) color("Tan") sphere(radius); -translate([2,10]) color("RosyBrown") sphere(radius); -translate([3,10]) color("SandyBrown") sphere(radius); -translate([4,10]) color("Goldenrod") sphere(radius); -translate([5,10]) color("DarkGoldenrod") sphere(radius); -translate([6,10]) color("Peru") sphere(radius); -translate([7,10]) color("Chocolate") sphere(radius); -translate([8,10]) color("SaddleBrown") sphere(radius); -translate([9,10]) color("Sienna") sphere(radius); -translate([10,10]) color("Brown") sphere(radius); -translate([0,11]) color("Maroon") sphere(radius); -//translate([1,11]) color("White colors") sphere(radius); -translate([2,11]) color("White") sphere(radius); -translate([3,11]) color("Snow") sphere(radius); -translate([4,11]) color("Honeydew") sphere(radius); -translate([5,11]) color("MintCream") sphere(radius); -translate([6,11]) color("Azure") sphere(radius); -translate([7,11]) color("AliceBlue") sphere(radius); -translate([8,11]) color("GhostWhite") sphere(radius); -translate([9,11]) color("WhiteSmoke") sphere(radius); -translate([10,11]) color("Seashell") sphere(radius); -translate([0,12]) color("Beige") sphere(radius); -translate([1,12]) color("OldLace") sphere(radius); -translate([2,12]) color("FloralWhite") sphere(radius); -translate([3,12]) color("Ivory") sphere(radius); -translate([4,12]) color("AntiqueWhite") sphere(radius); -translate([5,12]) color("Linen") sphere(radius); -translate([6,12]) color("LavenderBlush") sphere(radius); -translate([7,12]) color("MistyRose") sphere(radius); -//translate([8,12]) color("Gray colors") sphere(radius); -translate([9,12]) color("Gainsboro") sphere(radius); -translate([10,12]) color("LightGrey") sphere(radius); -translate([0,13]) color("Silver") sphere(radius); -translate([1,13]) color("DarkGray") sphere(radius); -translate([2,13]) color("Gray") sphere(radius); -translate([3,13]) color("DimGray") sphere(radius); -translate([4,13]) color("LightSlateGray") sphere(radius); -translate([5,13]) color("SlateGray") sphere(radius); -translate([6,13]) color("DarkSlateGray") sphere(radius); -translate([7,13]) color("Black") sphere(radius); - -- cgit v0.10.1 From abb78e223a97bcdf8d2605be5e61d57ad72a1436 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 06:00:35 +0200 Subject: line ending fix diff --git a/boost.pri b/boost.pri index b9f47d0..34a9dd2 100644 --- a/boost.pri +++ b/boost.pri @@ -1,18 +1,18 @@ -boost { - isEmpty(DEPLOYDIR) { - # Optionally specify location of boost using the - # BOOSTDIR env. variable - BOOST_DIR = $$(BOOSTDIR) - !isEmpty(BOOST_DIR) { - INCLUDEPATH += $$BOOST_DIR - message("boost location: $$BOOST_DIR") - win32:LIBS += -L$$BOOST_DIR/lib - } - } - - win32 { - LIBS += -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1 - } else { - LIBS += -lboost_thread -lboost_program_options - } -} +boost { + isEmpty(DEPLOYDIR) { + # Optionally specify location of boost using the + # BOOSTDIR env. variable + BOOST_DIR = $$(BOOSTDIR) + !isEmpty(BOOST_DIR) { + INCLUDEPATH += $$BOOST_DIR + message("boost location: $$BOOST_DIR") + win32:LIBS += -L$$BOOST_DIR/lib + } + } + + win32 { + LIBS += -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1 + } else { + LIBS += -lboost_thread -lboost_program_options + } +} -- cgit v0.10.1 From 3129189342f3da7322efa0b860ff3ff676ba7b77 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 06:02:15 +0200 Subject: Use our own boost with CGAL diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index d06c90e..0ed375f 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -125,7 +125,7 @@ build_cgal() tar xzf CGAL-$version.tar.gz cd CGAL-$version # We build a static lib. Not really necessary, but it's well tested. - cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DBUILD_SHARED_LIBS=FALSE -DCMAKE_OSX_DEPLOYMENT_TARGET="10.5" -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" + cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DBUILD_SHARED_LIBS=FALSE -DCMAKE_OSX_DEPLOYMENT_TARGET="10.5" -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" -DBOOST_ROOT=$DEPLOYDIR make -j4 make install } -- cgit v0.10.1 From 6f632190a05417d44193e3b16a7b3000b2cc1145 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 06:10:36 +0200 Subject: Ported a bunch of stuff from Qt to STL diff --git a/doc/visitor-changes.txt b/doc/visitor-changes.txt index 1e05cee..2fdc944 100644 --- a/doc/visitor-changes.txt +++ b/doc/visitor-changes.txt @@ -1,3 +1,3 @@ Changes in visitor branch: -o import_dxf(): layername="" imports all layers. Importing a single layer with a zero-length name is no longer supported. +o import_dxf(): layername="" imports all layers. Importing a single layer with a zero-length name is no longer supported. FIXME: The same prob. goes for dims o cylinder(): the r parameter will now always be used in place of a missing r1 or r2 diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 500c87d..791ad51 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -246,7 +246,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, DxfData *dxf; - if (node.filename.isEmpty()) + if (node.filename.empty()) { // Before extruding, union all (2D) children nodes // to a single DxfData, then tesselate this into a PolySet @@ -260,7 +260,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, dxf = sum.convertToDxfData();; } else { - dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); + dxf = new DxfData(node.fn, node.fs, node.fa, QString::fromStdString(node.filename), QString::fromStdString(node.layername), node.origin_x, node.origin_y, node.scale); } PolySet *ps = extrudeDxfData(node, *dxf); @@ -291,7 +291,7 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const DxfLinearExtrudeNode &node, continue; if (first_open_path) { PRINTF("WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):", - node.filename.toAscii().data(), node.layername.toAscii().data()); + node.filename.c_str(), node.layername.c_str()); first_open_path = false; } PRINTF(" %9.5f %10.5f ... %10.5f %10.5f", @@ -343,7 +343,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, DxfData *dxf; - if (node.filename.isEmpty()) + if (node.filename.empty()) { // Before extruding, union all (2D) children nodes // to a single DxfData, then tesselate this into a PolySet @@ -357,7 +357,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, dxf = sum.convertToDxfData(); } else { - dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); + dxf = new DxfData(node.fn, node.fs, node.fa, QString::fromStdString(node.filename), QString::fromStdString(node.layername), node.origin_x, node.origin_y, node.scale); } PolySet *ps = rotateDxfData(node, *dxf); diff --git a/src/builtin.h b/src/builtin.h index 79debe0..ae526f2 100644 --- a/src/builtin.h +++ b/src/builtin.h @@ -1,13 +1,14 @@ #ifndef BUILTIN_H_ #define BUILTIN_H_ -#include +#include +#include -extern QHash builtin_functions; +extern boost::unordered_map builtin_functions; extern void initialize_builtin_functions(); extern void destroy_builtin_functions(); -extern QHash builtin_modules; +extern boost::unordered_map builtin_modules; extern void initialize_builtin_modules(); extern void destroy_builtin_modules(); diff --git a/src/cgaladv.cc b/src/cgaladv.cc index 5b2e5df..908000d 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -32,6 +32,8 @@ #include "visitor.h" #include #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope enum cgaladv_type_e { MINKOWSKI, @@ -88,17 +90,17 @@ AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiat { CgaladvNode *node = new CgaladvNode(inst, type); - QVector argnames; - QVector argexpr; + std::vector argnames; + std::vector argexpr; if (type == MINKOWSKI) - argnames = QVector() << "convexity"; + argnames += "convexity"; if (type == GLIDE) - argnames = QVector() << "path" << "convexity"; + argnames += "path", "convexity"; if (type == SUBDIV) - argnames = QVector() << "type" << "level" << "convexity"; + argnames += "type", "level", "convexity"; Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); diff --git a/src/color.cc b/src/color.cc index 7340612..c64745c 100644 --- a/src/color.cc +++ b/src/color.cc @@ -33,6 +33,8 @@ #include #include #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope class ColorModule : public AbstractModule { @@ -50,28 +52,28 @@ AbstractNode *ColorModule::evaluate(const Context *ctx, const ModuleInstantiatio node->color[0] = node->color[1] = node->color[2] = -1.0; node->color[3] = 1.0; - QVector argnames; - QVector argexpr; + std::vector argnames; + std::vector argexpr; - argnames = QVector() << "c" << "alpha"; + argnames += "c", "alpha"; Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); Value v = c.lookup_variable("c"); if (v.type == Value::VECTOR) { - for (int i = 0; i < 4; i++) + for (size_t i = 0; i < 4; i++) node->color[i] = i < v.vec.size() ? v.vec[i]->num : 1.0; } else if (v.type == Value::STRING) { - QString colorname = QString::fromStdString(v.text); + std::string colorname = v.text; QColor color; - color.setNamedColor(colorname); + color.setNamedColor(QString::fromStdString(colorname)); if (color.isValid()) { node->color[0] = color.redF(); node->color[1] = color.greenF(); node->color[2] = color.blueF(); } else { - PRINTA_NOCACHE("WARNING: Color name \"%1\" unknown. Please see", colorname); + PRINTF_NOCACHE("WARNING: Color name \"%s\" unknown. Please see", colorname.c_str()); PRINTF_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors"); } } diff --git a/src/context.cc b/src/context.cc index ba2690c..7a0e3cd 100644 --- a/src/context.cc +++ b/src/context.cc @@ -31,6 +31,7 @@ #include "printutils.h" #include #include +#include Context::Context(const Context *parent) { @@ -40,7 +41,7 @@ Context::Context(const Context *parent) usedlibs_p = NULL; inst_p = NULL; if (parent) document_path = parent->document_path; - ctx_stack.append(this); + ctx_stack.push_back(this); } Context::~Context() @@ -48,16 +49,16 @@ Context::~Context() ctx_stack.pop_back(); } -void Context::args(const QVector &argnames, const QVector &argexpr, - const QVector &call_argnames, const QVector &call_argvalues) +void Context::args(const std::vector &argnames, const std::vector &argexpr, + const std::vector &call_argnames, const std::vector &call_argvalues) { - for (int i=0; ievaluate(this->parent) : Value()); } - int posarg = 0; - for (int i=0; i &argnames, const QVector } } -QVector Context::ctx_stack; +std::vector Context::ctx_stack; -void Context::set_variable(QString name, Value value) +void Context::set_variable(const std::string &name, Value value) { - if (name.startsWith("$")) + if (name[0] == '$') config_variables[name] = value; else variables[name] = value; } -Value Context::lookup_variable(QString name, bool silent) const +Value Context::lookup_variable(const std::string &name, bool silent) const { - if (name.startsWith("$")) { + if (name[0] == '$') { for (int i = ctx_stack.size()-1; i >= 0; i--) { - if (ctx_stack[i]->config_variables.contains(name)) - return ctx_stack[i]->config_variables[name]; + const ValueMap &confvars = ctx_stack[i]->config_variables; + if (confvars.find(name) != confvars.end()) + return confvars.find(name)->second; } return Value(); } - if (!parent && constants.contains(name)) - return constants[name]; - if (variables.contains(name)) - return variables[name]; + if (!parent && constants.find(name) != constants.end()) + return constants.find(name)->second; + if (variables.find(name) != variables.end()) + return variables.find(name)->second; if (parent) return parent->lookup_variable(name, silent); if (!silent) - PRINTA("WARNING: Ignoring unknown variable '%1'.", name); + PRINTF("WARNING: Ignoring unknown variable '%s'.", name.c_str()); return Value(); } -void Context::set_constant(QString name, Value value) +void Context::set_constant(const std::string &name, Value value) { - if (constants.contains(name)) - PRINTA("WARNING: Attempt to modify constant '%1'.",name); - else - constants.insert(name,value); + if (constants.count(name)) + PRINTF("WARNING: Attempt to modify constant '%s'.",name.c_str()); + else + constants[name] = value; } -Value Context::evaluate_function(QString name, const QVector &argnames, const QVector &argvalues) const +Value Context::evaluate_function(const std::string &name, const std::vector &argnames, const std::vector &argvalues) const { - if (functions_p && functions_p->contains(name)) - return functions_p->value(name)->evaluate(this, argnames, argvalues); + if (functions_p && functions_p->find(name) != functions_p->end()) + return functions_p->find(name)->second->evaluate(this, argnames, argvalues); if (usedlibs_p) { - QHashIterator i(*usedlibs_p); - while (i.hasNext()) { - i.next(); - if (i.value()->functions.contains(name)) { - Module *lib = i.value(); + BOOST_FOREACH(const ModuleContainer::value_type &m, *usedlibs_p) { + if (m.second->functions.count(name)) { + Module *lib = m.second; Context ctx(parent); ctx.functions_p = &lib->functions; ctx.modules_p = &lib->modules; ctx.usedlibs_p = &lib->usedlibs; - for (int j = 0; j < lib->assignments_var.size(); j++) { + for (size_t j = 0; j < lib->assignments_var.size(); j++) { ctx.set_variable(lib->assignments_var[j], lib->assignments_expr[j]->evaluate(&ctx)); } - return i.value()->functions.value(name)->evaluate(&ctx, argnames, argvalues); + return m.second->functions[name]->evaluate(&ctx, argnames, argvalues); } } } if (parent) return parent->evaluate_function(name, argnames, argvalues); - PRINTA("WARNING: Ignoring unkown function '%1'.", name); + PRINTF("WARNING: Ignoring unkown function '%s'.", name.c_str()); return Value(); } AbstractNode *Context::evaluate_module(const ModuleInstantiation *inst) const { - if (modules_p && modules_p->contains(inst->modname)) - return modules_p->value(inst->modname)->evaluate(this, inst); + if (modules_p && modules_p->find(inst->modname) != modules_p->end()) + return modules_p->find(inst->modname)->second->evaluate(this, inst); if (usedlibs_p) { - QHashIterator i(*usedlibs_p); - while (i.hasNext()) { - i.next(); - if (i.value()->modules.contains(inst->modname)) { - Module *lib = i.value(); + BOOST_FOREACH(const ModuleContainer::value_type &m, *usedlibs_p) { + if (m.second->modules.count(inst->modname)) { + Module *lib = m.second; Context ctx(parent); ctx.functions_p = &lib->functions; ctx.modules_p = &lib->modules; ctx.usedlibs_p = &lib->usedlibs; - for (int j = 0; j < lib->assignments_var.size(); j++) { + for (size_t j = 0; j < lib->assignments_var.size(); j++) { ctx.set_variable(lib->assignments_var[j], lib->assignments_expr[j]->evaluate(&ctx)); } - return i.value()->modules.value(inst->modname)->evaluate(&ctx, inst); + return m.second->modules[inst->modname]->evaluate(&ctx, inst); } } } if (parent) return parent->evaluate_module(inst); - PRINTA("WARNING: Ignoring unkown module '%1'.", inst->modname); + PRINTF("WARNING: Ignoring unkown module '%s'.", inst->modname.c_str()); return NULL; } /*! Returns the absolute path to the given filename, unless it's empty. */ -QString Context::get_absolute_path(const QString &filename) const +std::string Context::get_absolute_path(const std::string &filename) const { - if (!filename.isEmpty()) { - return QFileInfo(QDir(this->document_path), filename).absoluteFilePath(); + if (!filename.empty()) { + return QFileInfo(QDir(QString::fromStdString(this->document_path)), + QString::fromStdString(filename)).absoluteFilePath().toStdString(); } else { return filename; diff --git a/src/context.h b/src/context.h index cbb1c4f..99726a9 100644 --- a/src/context.h +++ b/src/context.h @@ -1,38 +1,43 @@ #ifndef CONTEXT_H_ #define CONTEXT_H_ -#include -#include +#include +#include +#include #include "value.h" +using boost::unordered_map; + class Context { public: const Context *parent; - QHash constants; - QHash variables; - QHash config_variables; - const QHash *functions_p; - const QHash *modules_p; - const QHash *usedlibs_p; + typedef unordered_map ValueMap; + ValueMap constants; + ValueMap variables; + ValueMap config_variables; + const unordered_map *functions_p; + const unordered_map *modules_p; + typedef unordered_map ModuleContainer; + const ModuleContainer *usedlibs_p; const class ModuleInstantiation *inst_p; - QString document_path; + std::string document_path; - static QVector ctx_stack; + static std::vector ctx_stack; Context(const Context *parent = NULL); ~Context(); - void args(const QVector &argnames, const QVector &argexpr, const QVector &call_argnames, const QVector &call_argvalues); + void args(const std::vector &argnames, const std::vector &argexpr, const std::vector &call_argnames, const std::vector &call_argvalues); - void set_variable(QString name, Value value); - Value lookup_variable(QString name, bool silent = false) const; + void set_variable(const std::string &name, Value value); + Value lookup_variable(const std::string &name, bool silent = false) const; - void set_constant(QString name, Value value); + void set_constant(const std::string &name, Value value); - QString get_absolute_path(const QString &filename) const; + std::string get_absolute_path(const std::string &filename) const; - Value evaluate_function(QString name, const QVector &argnames, const QVector &argvalues) const; + Value evaluate_function(const std::string &name, const std::vector &argnames, const std::vector &argvalues) const; class AbstractNode *evaluate_module(const ModuleInstantiation *inst) const; }; diff --git a/src/control.cc b/src/control.cc index e1b816c..d2df4f5 100644 --- a/src/control.cc +++ b/src/control.cc @@ -47,10 +47,10 @@ public: virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; }; -void for_eval(AbstractNode *node, int l, const QVector &call_argnames, const QVector &call_argvalues, const QVector arg_children, const Context *arg_context) +void for_eval(AbstractNode *node, size_t l, const std::vector &call_argnames, const std::vector &call_argvalues, const std::vector arg_children, const Context *arg_context) { if (call_argnames.size() > l) { - QString it_name = call_argnames[l]; + std::string it_name = call_argnames[l]; Value it_values = call_argvalues[l]; Context c(arg_context); if (it_values.type == Value::RANGE) { @@ -70,7 +70,7 @@ void for_eval(AbstractNode *node, int l, const QVector &call_argnames, } } else if (it_values.type == Value::VECTOR) { - for (int i = 0; i < it_values.vec.size(); i++) { + for (size_t i = 0; i < it_values.vec.size(); i++) { c.set_variable(it_name, *it_values.vec[i]); for_eval(node, l+1, call_argnames, call_argvalues, arg_children, &c); } @@ -91,7 +91,7 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation { if (type == CHILD) { - int n = 0; + size_t n = 0; if (inst->argvalues.size() > 0) { double v; if (inst->argvalues[0].getnum(v)) @@ -122,8 +122,8 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation for (int i = 0; i < inst->argnames.size(); i++) { if (i > 0) msg += QString(", "); - if (!inst->argnames[i].isEmpty()) - msg += inst->argnames[i] + QString(" = "); + if (!inst->argnames[i].empty()) + msg += QString::fromStdString(inst->argnames[i]) + QString(" = "); msg += QString::fromStdString(inst->argvalues[i].toString()); } PRINT(msg); @@ -133,7 +133,7 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation { Context c(inst->ctx); for (int i = 0; i < inst->argnames.size(); i++) { - if (!inst->argnames[i].isEmpty()) + if (!inst->argnames[i].empty()) c.set_variable(inst->argnames[i], inst->argvalues[i]); } foreach (ModuleInstantiation *v, inst->children) { diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 666b53d..88e007c 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -33,48 +33,50 @@ #include "context.h" #include "mathc99.h" -#include #include #include +#include -QHash dxf_dim_cache; -QHash dxf_cross_cache; +boost::unordered_map dxf_dim_cache; +boost::unordered_map dxf_cross_cache; -Value builtin_dxf_dim(const Context *ctx, const QVector &argnames, const QVector &args) +Value builtin_dxf_dim(const Context *ctx, const std::vector &argnames, const std::vector &args) { - QString filename; - QString layername; - QString name; + std::string filename; + std::string layername; + std::string name; double xorigin = 0; double yorigin = 0; double scale = 1; - for (int i = 0; i < argnames.count() && i < args.count(); i++) { + for (size_t i = 0; i < argnames.size() && i < args.size(); i++) { if (argnames[i] == "file") - filename = ctx->get_absolute_path(QString::fromStdString(args[i].text)); + filename = ctx->get_absolute_path(args[i].text); if (argnames[i] == "layer") - layername = QString::fromStdString(args[i].text); + layername = args[i].text; if (argnames[i] == "origin") args[i].getv2(xorigin, yorigin); if (argnames[i] == "scale") args[i].getnum(scale); if (argnames[i] == "name") - name = QString::fromStdString(args[i].text); + name = args[i].text; } - QFileInfo fileInfo(filename); + QFileInfo fileInfo(QString::fromStdString(filename)); - QString key = filename + "|" + layername + "|" + name + "|" + QString::number(xorigin) + "|" + QString::number(yorigin) + - "|" + QString::number(scale) + "|" + QString::number(fileInfo.lastModified().toTime_t()) + "|" + QString::number(fileInfo.size()); + std::stringstream keystream; + keystream << filename << "|" << layername << "|" << name << "|" << xorigin + << "|" << yorigin <<"|" << scale << "|" << fileInfo.lastModified().toTime_t() + << "|" << fileInfo.size(); + std::string key = keystream.str(); + if (dxf_dim_cache.find(key) != dxf_dim_cache.end()) + return dxf_dim_cache.find(key)->second; - if (dxf_dim_cache.contains(key)) - return dxf_dim_cache[key]; - - DxfData dxf(36, 0, 0, filename, layername, xorigin, yorigin, scale); + DxfData dxf(36, 0, 0, QString::fromStdString(filename), QString::fromStdString(layername), xorigin, yorigin, scale); for (int i = 0; i < dxf.dims.count(); i++) { - if (!name.isNull() && dxf.dims[i].name != name) + if (!name.empty() && dxf.dims[i].name != QString::fromStdString(name)) continue; DxfData::Dim *d = &dxf.dims[i]; @@ -114,43 +116,46 @@ Value builtin_dxf_dim(const Context *ctx, const QVector &argnames, cons return dxf_dim_cache[key] = Value((d->type & 64) ? d->coords[3][0] : d->coords[3][1]); } - PRINTA("WARNING: Dimension `%1' in `%2', layer `%3' has unsupported type!", name, filename, layername); + PRINTF("WARNING: Dimension `%s' in `%s', layer `%s' has unsupported type!", name.c_str(), filename.c_str(), layername.c_str()); return Value(); } - PRINTA("WARNING: Can't find dimension `%1' in `%2', layer `%3'!", name, filename, layername); + PRINTF("WARNING: Can't find dimension `%s' in `%s', layer `%s'!", name.c_str(), filename.c_str(), layername.c_str()); return Value(); } -Value builtin_dxf_cross(const Context *ctx, const QVector &argnames, const QVector &args) +Value builtin_dxf_cross(const Context *ctx, const std::vector &argnames, const std::vector &args) { - QString filename; - QString layername; + std::string filename; + std::string layername; double xorigin = 0; double yorigin = 0; double scale = 1; - for (int i = 0; i < argnames.count() && i < args.count(); i++) { + for (size_t i = 0; i < argnames.size() && i < args.size(); i++) { if (argnames[i] == "file") - filename = ctx->get_absolute_path(QString::fromStdString(args[i].text)); + filename = ctx->get_absolute_path(args[i].text); if (argnames[i] == "layer") - layername = QString::fromStdString(args[i].text); + layername = args[i].text; if (argnames[i] == "origin") args[i].getv2(xorigin, yorigin); if (argnames[i] == "scale") args[i].getnum(scale); } - QFileInfo fileInfo(filename); + QFileInfo fileInfo(QString::fromStdString(filename)); - QString key = filename + "|" + layername + "|" + QString::number(xorigin) + "|" + QString::number(yorigin) + - "|" + QString::number(scale) + "|" + QString::number(fileInfo.lastModified().toTime_t()) + "|" + QString::number(fileInfo.size()); + std::stringstream keystream; + keystream << filename << "|" << layername << "|" << xorigin << "|" << yorigin + << "|" << scale << "|" << fileInfo.lastModified().toTime_t() + << "|" << fileInfo.size(); + std::string key = keystream.str(); - if (dxf_cross_cache.contains(key)) - return dxf_cross_cache[key]; + if (dxf_cross_cache.find(key) != dxf_cross_cache.end()) + return dxf_cross_cache.find(key)->second; - DxfData dxf(36, 0, 0, filename, layername, xorigin, yorigin, scale); + DxfData dxf(36, 0, 0, QString::fromStdString(filename), QString::fromStdString(layername), xorigin, yorigin, scale); double coords[4][2]; @@ -182,7 +187,7 @@ Value builtin_dxf_cross(const Context *ctx, const QVector &argnames, co } } - PRINTA("WARNING: Can't find cross in `%1', layer `%2'!", filename, layername); + PRINTF("WARNING: Can't find cross in `%s', layer `%s'!", filename.c_str(), layername.c_str()); return Value(); } diff --git a/src/dxfdim.h b/src/dxfdim.h index 9686760..bd42109 100644 --- a/src/dxfdim.h +++ b/src/dxfdim.h @@ -1,10 +1,10 @@ #ifndef DXFDIM_H_ #define DXFDIM_H_ -#include +#include #include "value.h" -extern QHash dxf_cross_cache; -extern QHash dxf_dim_cache; +extern boost::unordered_map dxf_dim_cache; +extern boost::unordered_map dxf_cross_cache; #endif diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index 4bae863..283c7f4 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -39,11 +39,9 @@ #include "openscad.h" // get_fragments_from_r() #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope -#include -#include -#include -#include #include class DxfLinearExtrudeModule : public AbstractModule @@ -57,8 +55,9 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI { DxfLinearExtrudeNode *node = new DxfLinearExtrudeNode(inst); - QVector argnames = QVector() << "file" << "layer" << "height" << "origin" << "scale" << "center" << "twist" << "slices"; - QVector argexpr; + std::vector argnames; + argnames += "file", "layer", "height", "origin", "scale", "center", "twist", "slices"; + std::vector argexpr; Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); @@ -78,9 +77,9 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI Value slices = c.lookup_variable("slices", true); if (!file.text.empty()) - node->filename = c.get_absolute_path(QString::fromStdString(file.text)); + node->filename = c.get_absolute_path(file.text); - node->layername = QString::fromStdString(layer.text); + node->layername = layer.text; node->height = height.num; node->convexity = (int)convexity.num; origin.getv2(node->origin_x, node->origin_y); @@ -109,7 +108,7 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI node->has_twist = true; } - if (node->filename.isEmpty()) { + if (node->filename.empty()) { foreach (ModuleInstantiation *v, inst->children) { AbstractNode *n = v->evaluate(inst->ctx); if (n) @@ -149,11 +148,9 @@ std::string DxfLinearExtrudeNode::toString() const { std::stringstream stream; - QString text; - stream << this->name() << "(" "file = \"" << this->filename << "\", " - "cache = \"" << QFileInfo(this->filename) << "\", " + "cache = \"" << QFileInfo(QString::fromStdString(this->filename)) << "\", " "layer = \"" << this->layername << "\", " "height = " << std::dec << this->height << ", " "origin = [ " << this->origin_x << " " << this->origin_y << " ], " diff --git a/src/dxflinextrudenode.h b/src/dxflinextrudenode.h index 70e7a06..3c3beca 100644 --- a/src/dxflinextrudenode.h +++ b/src/dxflinextrudenode.h @@ -3,7 +3,6 @@ #include "node.h" #include "visitor.h" -#include class DxfLinearExtrudeNode : public AbstractPolyNode { @@ -24,7 +23,7 @@ public: double fn, fs, fa, height, twist; double origin_x, origin_y, scale; bool center, has_twist; - QString filename, layername; + std::string filename, layername; virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; }; diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index 7fdcd41..b333fbf 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -37,11 +37,9 @@ #include "openscad.h" // get_fragments_from_r() #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope -#include -#include -#include -#include #include class DxfRotateExtrudeModule : public AbstractModule @@ -55,8 +53,9 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI { DxfRotateExtrudeNode *node = new DxfRotateExtrudeNode(inst); - QVector argnames = QVector() << "file" << "layer" << "origin" << "scale"; - QVector argexpr; + std::vector argnames; + argnames += "file", "layer", "origin", "scale"; + std::vector argexpr; Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); @@ -72,9 +71,9 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI Value scale = c.lookup_variable("scale", true); if (!file.text.empty()) - node->filename = c.get_absolute_path(QString::fromStdString(file.text)); + node->filename = c.get_absolute_path(file.text); - node->layername = QString::fromStdString(layer.text); + node->layername = layer.text; node->convexity = (int)convexity.num; origin.getv2(node->origin_x, node->origin_y); node->scale = scale.num; @@ -85,7 +84,7 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI if (node->scale <= 0) node->scale = 1; - if (node->filename.isEmpty()) { + if (node->filename.empty()) { foreach (ModuleInstantiation *v, inst->children) { AbstractNode *n = v->evaluate(inst->ctx); if (n) @@ -127,7 +126,7 @@ std::string DxfRotateExtrudeNode::toString() const stream << this->name() << "(" "file = \"" << this->filename << "\", " - "cache = \"" << QFileInfo(this->filename) << "\", " + "cache = \"" << QFileInfo(QString::fromStdString(this->filename)) << "\", " "layer = \"" << this->layername << "\", " "origin = [ " << std::dec << this->origin_x << " " << this->origin_y << " ], " "scale = " << this->scale << ", " diff --git a/src/dxfrotextrudenode.h b/src/dxfrotextrudenode.h index aa22a73..797b53a 100644 --- a/src/dxfrotextrudenode.h +++ b/src/dxfrotextrudenode.h @@ -3,7 +3,6 @@ #include "node.h" #include "visitor.h" -#include class DxfRotateExtrudeNode : public AbstractPolyNode { @@ -22,7 +21,7 @@ public: int convexity; double fn, fs, fa; double origin_x, origin_y, scale; - QString filename, layername; + std::string filename, layername; virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; }; diff --git a/src/expr.cc b/src/expr.cc index 72f92a0..8e482e8 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -29,59 +29,59 @@ #include "context.h" #include #include +#include +#include "stl-utils.h" Expression::Expression() { - const_value = NULL; + this->const_value = NULL; } Expression::~Expression() { - for (int i=0; i < children.size(); i++) - delete children[i]; - if (const_value) - delete const_value; + std::for_each(this->children.begin(), this->children.end(), del_fun()); + delete this->const_value; } Value Expression::evaluate(const Context *context) const { - if (type == "!") - return ! children[0]->evaluate(context); - if (type == "&&") - return children[0]->evaluate(context) && children[1]->evaluate(context); - if (type == "||") - return children[0]->evaluate(context) || children[1]->evaluate(context); - if (type == "*") - return children[0]->evaluate(context) * children[1]->evaluate(context); - if (type == "/") - return children[0]->evaluate(context) / children[1]->evaluate(context); - if (type == "%") - return children[0]->evaluate(context) % children[1]->evaluate(context); - if (type == "+") - return children[0]->evaluate(context) + children[1]->evaluate(context); - if (type == "-") - return children[0]->evaluate(context) - children[1]->evaluate(context); - if (type == "<") - return children[0]->evaluate(context) < children[1]->evaluate(context); - if (type == "<=") - return children[0]->evaluate(context) <= children[1]->evaluate(context); - if (type == "==") - return children[0]->evaluate(context) == children[1]->evaluate(context); - if (type == "!=") - return children[0]->evaluate(context) != children[1]->evaluate(context); - if (type == ">=") - return children[0]->evaluate(context) >= children[1]->evaluate(context); - if (type == ">") - return children[0]->evaluate(context) > children[1]->evaluate(context); - if (type == "?:") { - Value v = children[0]->evaluate(context); + if (this->type == "!") + return ! this->children[0]->evaluate(context); + if (this->type == "&&") + return this->children[0]->evaluate(context) && this->children[1]->evaluate(context); + if (this->type == "||") + return this->children[0]->evaluate(context) || this->children[1]->evaluate(context); + if (this->type == "*") + return this->children[0]->evaluate(context) * this->children[1]->evaluate(context); + if (this->type == "/") + return this->children[0]->evaluate(context) / this->children[1]->evaluate(context); + if (this->type == "%") + return this->children[0]->evaluate(context) % this->children[1]->evaluate(context); + if (this->type == "+") + return this->children[0]->evaluate(context) + this->children[1]->evaluate(context); + if (this->type == "-") + return this->children[0]->evaluate(context) - this->children[1]->evaluate(context); + if (this->type == "<") + return this->children[0]->evaluate(context) < this->children[1]->evaluate(context); + if (this->type == "<=") + return this->children[0]->evaluate(context) <= this->children[1]->evaluate(context); + if (this->type == "==") + return this->children[0]->evaluate(context) == this->children[1]->evaluate(context); + if (this->type == "!=") + return this->children[0]->evaluate(context) != this->children[1]->evaluate(context); + if (this->type == ">=") + return this->children[0]->evaluate(context) >= this->children[1]->evaluate(context); + if (this->type == ">") + return this->children[0]->evaluate(context) > this->children[1]->evaluate(context); + if (this->type == "?:") { + Value v = this->children[0]->evaluate(context); if (v.type == Value::BOOL) - return children[v.b ? 1 : 2]->evaluate(context); + return this->children[v.b ? 1 : 2]->evaluate(context); return Value(); } - if (type == "[]") { - Value v1 = children[0]->evaluate(context); - Value v2 = children[1]->evaluate(context); + if (this->type == "[]") { + Value v1 = this->children[0]->evaluate(context); + Value v2 = this->children[1]->evaluate(context); if (v1.type == Value::VECTOR && v2.type == Value::NUMBER) { int i = (int)(v2.num); if (i >= 0 && i < v1.vec.size()) @@ -89,14 +89,14 @@ Value Expression::evaluate(const Context *context) const } return Value(); } - if (type == "I") - return children[0]->evaluate(context).inv(); - if (type == "C") - return *const_value; - if (type == "R") { - Value v1 = children[0]->evaluate(context); - Value v2 = children[1]->evaluate(context); - Value v3 = children[2]->evaluate(context); + if (this->type == "I") + return this->children[0]->evaluate(context).inv(); + if (this->type == "C") + return *this->const_value; + if (this->type == "R") { + Value v1 = this->children[0]->evaluate(context); + Value v2 = this->children[1]->evaluate(context); + Value v3 = this->children[2]->evaluate(context); if (v1.type == Value::NUMBER && v2.type == Value::NUMBER && v3.type == Value::NUMBER) { Value r = Value(); r.type = Value::RANGE; @@ -107,40 +107,40 @@ Value Expression::evaluate(const Context *context) const } return Value(); } - if (type == "V") { + if (this->type == "V") { Value v; v.type = Value::VECTOR; - for (int i = 0; i < children.size(); i++) - v.append(new Value(children[i]->evaluate(context))); + for (int i = 0; i < this->children.size(); i++) + v.append(new Value(this->children[i]->evaluate(context))); return v; } - if (type == "L") - return context->lookup_variable(var_name); - if (type == "N") + if (this->type == "L") + return context->lookup_variable(this->var_name); + if (this->type == "N") { - Value v = children[0]->evaluate(context); + Value v = this->children[0]->evaluate(context); - if (v.type == Value::VECTOR && var_name == QString("x")) + if (v.type == Value::VECTOR && this->var_name == "x") return *v.vec[0]; - if (v.type == Value::VECTOR && var_name == QString("y")) + if (v.type == Value::VECTOR && this->var_name == "y") return *v.vec[1]; - if (v.type == Value::VECTOR && var_name == QString("z")) + if (v.type == Value::VECTOR && this->var_name == "z") return *v.vec[2]; - if (v.type == Value::RANGE && var_name == QString("begin")) + if (v.type == Value::RANGE && this->var_name == "begin") return Value(v.range_begin); - if (v.type == Value::RANGE && var_name == QString("step")) + if (v.type == Value::RANGE && this->var_name == "step") return Value(v.range_step); - if (v.type == Value::RANGE && var_name == QString("end")) + if (v.type == Value::RANGE && this->var_name == "end") return Value(v.range_end); return Value(); } - if (type == "F") { - QVector argvalues; - for (int i=0; i < children.size(); i++) - argvalues.append(children[i]->evaluate(context)); - return context->evaluate_function(call_funcname, call_argnames, argvalues); + if (this->type == "F") { + std::vector argvalues; + for (int i=0; i < this->children.size(); i++) + argvalues.push_back(this->children[i]->evaluate(context)); + return context->evaluate_function(this->call_funcname, this->call_argnames, argvalues); } abort(); } @@ -152,43 +152,43 @@ std::string Expression::toString() const if (this->type == "*" || this->type == "/" || this->type == "%" || this->type == "+" || this->type == "-" || this->type == "<" || this->type == "<=" || this->type == "==" || this->type == "!=" || this->type == ">=" || this->type == ">") { - stream << "(" << *children[0] << " " << this->type << " " << *children[1] << ")"; + stream << "(" << *this->children[0] << " " << this->type << " " << *this->children[1] << ")"; } else if (this->type == "?:") { - stream << "(" << *children[0] << " ? " << this->type << " : " << *children[1] << ")"; + stream << "(" << *this->children[0] << " ? " << this->type << " : " << *this->children[1] << ")"; } else if (this->type == "[]") { - stream << "(" << *children[0] << "[" << *children[1] << "])"; + stream << "(" << *this->children[0] << "[" << *this->children[1] << "])"; } else if (this->type == "I") { - stream << "(-" << *children[0] << ")"; + stream << "(-" << *this->children[0] << ")"; } else if (this->type == "C") { - stream << *const_value; + stream << *this->const_value; } else if (this->type == "R") { - stream << "[" << *children[0] << " : " << *children[1] << " : " << children[2] << "]"; + stream << "[" << *this->children[0] << " : " << *this->children[1] << " : " << this->children[2] << "]"; } else if (this->type == "V") { stream << "["; - for (int i=0; i < children.size(); i++) { + for (int i=0; i < this->children.size(); i++) { if (i > 0) stream << ", "; - stream << *children[i]; + stream << *this->children[i]; } stream << "]"; } else if (this->type == "L") { - stream << var_name; + stream << this->var_name; } else if (this->type == "N") { - stream << "(" << *children[0] << "." << var_name << ")"; + stream << "(" << *this->children[0] << "." << this->var_name << ")"; } else if (this->type == "F") { - stream << call_funcname << "("; - for (int i=0; i < children.size(); i++) { + stream << this->call_funcname << "("; + for (int i=0; i < this->children.size(); i++) { if (i > 0) stream << ", "; - if (!call_argnames[i].isEmpty()) stream << call_argnames[i] << " = "; - stream << *children[i]; + if (!this->call_argnames[i].empty()) stream << this->call_argnames[i] << " = "; + stream << *this->children[i]; } stream << ")"; } diff --git a/src/expression.h b/src/expression.h index 38043db..acbd6aa 100644 --- a/src/expression.h +++ b/src/expression.h @@ -1,19 +1,19 @@ #ifndef EXPRESSION_H_ #define EXPRESSION_H_ -#include -#include +#include +#include class Expression { public: - QVector children; + std::vector children; class Value *const_value; - QString var_name; + std::string var_name; - QString call_funcname; - QVector call_argnames; + std::string call_funcname; + std::vector call_argnames; // Boolean: ! && || // Operators: * / % + - @@ -28,7 +28,7 @@ public: // Lookup Variable: L // Lookup member per name: N // Function call: F - QString type; + std::string type; Expression(); ~Expression(); diff --git a/src/func.cc b/src/func.cc index c10963c..31c8ad2 100644 --- a/src/func.cc +++ b/src/func.cc @@ -32,29 +32,33 @@ #include #include #include "mathc99.h" +#include +#include "stl-utils.h" +#include AbstractFunction::~AbstractFunction() { } -Value AbstractFunction::evaluate(const Context*, const QVector&, const QVector&) const +Value AbstractFunction::evaluate(const Context*, const std::vector&, const std::vector&) const { return Value(); } -QString AbstractFunction::dump(QString indent, QString name) const +std::string AbstractFunction::dump(const std::string &indent, const std::string &name) const { - return QString("%1abstract function %2();\n").arg(indent, name); + std::stringstream dump; + dump << indent << "abstract function " << name << "();\n"; + return dump.str(); } Function::~Function() { - for (int i=0; i < argexpr.size(); i++) - delete argexpr[i]; + std::for_each(this->argexpr.begin(), this->argexpr.end(), del_fun()); delete expr; } -Value Function::evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const +Value Function::evaluate(const Context *ctx, const std::vector &call_argnames, const std::vector &call_argvalues) const { Context c(ctx); c.args(argnames, argexpr, call_argnames, call_argvalues); @@ -63,34 +67,36 @@ Value Function::evaluate(const Context *ctx, const QVector &call_argnam return Value(); } -QString Function::dump(QString indent, QString name) const +std::string Function::dump(const std::string &indent, const std::string &name) const { - QString text = QString("%1function %2(").arg(indent, name); - for (int i=0; i < argnames.size(); i++) { - if (i > 0) - text += QString(", "); - text += argnames[i]; - if (argexpr[i]) - text += QString(" = ") + QString::fromStdString(argexpr[i]->toString()); + std::stringstream dump; + dump << indent << "function " << name << "("; + for (size_t i=0; i < argnames.size(); i++) { + if (i > 0) dump << ", "; + dump << argnames[i]; + if (argexpr[i]) dump << " = " << *argexpr[i]; } - text += QString(") = %1;\n").arg(QString::fromStdString(expr->toString())); - return text; + dump << ") = " << *expr << ";\n"; + return dump.str(); } -QHash builtin_functions; +typedef boost::unordered_map BuiltinContainer; +BuiltinContainer builtin_functions; BuiltinFunction::~BuiltinFunction() { } -Value BuiltinFunction::evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const +Value BuiltinFunction::evaluate(const Context *ctx, const std::vector &call_argnames, const std::vector &call_argvalues) const { return eval_func(ctx, call_argnames, call_argvalues); } -QString BuiltinFunction::dump(QString indent, QString name) const +std::string BuiltinFunction::dump(const std::string &indent, const std::string &name) const { - return QString("%1builtin function %2();\n").arg(indent, name); + std::stringstream dump; + dump << indent << "builtin function " << name << "();\n"; + return dump.str(); } static double deg2rad(double x) @@ -113,14 +119,14 @@ static double rad2deg(double x) return x; } -Value builtin_abs(const Context *, const QVector&, const QVector &args) +Value builtin_abs(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(fabs(args[0].num)); return Value(); } -Value builtin_sign(const Context *, const QVector&, const QVector &args) +Value builtin_sign(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value((args[0].num<0) ? -1.0 : ((args[0].num>0) ? 1.0 : 0.0)); @@ -137,7 +143,7 @@ double frand(double min, double max) return (min>max) ? frand()*(min-max)+max : frand()*(max-min)+min; } -Value builtin_rands(const Context *, const QVector&, const QVector &args) +Value builtin_rands(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 3 && args[0].type == Value::NUMBER && @@ -172,11 +178,11 @@ Value builtin_rands(const Context *, const QVector&, const QVector&, const QVector &args) +Value builtin_min(const Context *, const std::vector&, const std::vector &args) { if (args.size() >= 1 && args[0].type == Value::NUMBER) { double val = args[0].num; - for (int i = 1; i < args.size(); i++) + for (size_t i = 1; i < args.size(); i++) if (args[1].type == Value::NUMBER) val = fmin(val, args[i].num); return Value(val); @@ -184,11 +190,11 @@ Value builtin_min(const Context *, const QVector&, const QVector return Value(); } -Value builtin_max(const Context *, const QVector&, const QVector &args) +Value builtin_max(const Context *, const std::vector&, const std::vector &args) { if (args.size() >= 1 && args[0].type == Value::NUMBER) { double val = args[0].num; - for (int i = 1; i < args.size(); i++) + for (size_t i = 1; i < args.size(); i++) if (args[1].type == Value::NUMBER) val = fmax(val, args[i].num); return Value(val); @@ -196,98 +202,98 @@ Value builtin_max(const Context *, const QVector&, const QVector return Value(); } -Value builtin_sin(const Context *, const QVector&, const QVector &args) +Value builtin_sin(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(sin(deg2rad(args[0].num))); return Value(); } -Value builtin_cos(const Context *, const QVector&, const QVector &args) +Value builtin_cos(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(cos(deg2rad(args[0].num))); return Value(); } -Value builtin_asin(const Context *, const QVector&, const QVector &args) +Value builtin_asin(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(rad2deg(asin(args[0].num))); return Value(); } -Value builtin_acos(const Context *, const QVector&, const QVector &args) +Value builtin_acos(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(rad2deg(acos(args[0].num))); return Value(); } -Value builtin_tan(const Context *, const QVector&, const QVector &args) +Value builtin_tan(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(tan(deg2rad(args[0].num))); return Value(); } -Value builtin_atan(const Context *, const QVector&, const QVector &args) +Value builtin_atan(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(rad2deg(atan(args[0].num))); return Value(); } -Value builtin_atan2(const Context *, const QVector&, const QVector &args) +Value builtin_atan2(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 2 && args[0].type == Value::NUMBER && args[1].type == Value::NUMBER) return Value(rad2deg(atan2(args[0].num, args[1].num))); return Value(); } -Value builtin_pow(const Context *, const QVector&, const QVector &args) +Value builtin_pow(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 2 && args[0].type == Value::NUMBER && args[1].type == Value::NUMBER) return Value(pow(args[0].num, args[1].num)); return Value(); } -Value builtin_round(const Context *, const QVector&, const QVector &args) +Value builtin_round(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(round(args[0].num)); return Value(); } -Value builtin_ceil(const Context *, const QVector&, const QVector &args) +Value builtin_ceil(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(ceil(args[0].num)); return Value(); } -Value builtin_floor(const Context *, const QVector&, const QVector &args) +Value builtin_floor(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(floor(args[0].num)); return Value(); } -Value builtin_sqrt(const Context *, const QVector&, const QVector &args) +Value builtin_sqrt(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(sqrt(args[0].num)); return Value(); } -Value builtin_exp(const Context *, const QVector&, const QVector &args) +Value builtin_exp(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(exp(args[0].num)); return Value(); } -Value builtin_log(const Context *, const QVector&, const QVector &args) +Value builtin_log(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 2 && args[0].type == Value::NUMBER && args[1].type == Value::NUMBER) return Value(log(args[1].num) / log(args[0].num)); @@ -296,31 +302,31 @@ Value builtin_log(const Context *, const QVector&, const QVector return Value(); } -Value builtin_ln(const Context *, const QVector&, const QVector &args) +Value builtin_ln(const Context *, const std::vector&, const std::vector &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) return Value(log(args[0].num)); return Value(); } -Value builtin_str(const Context *, const QVector&, const QVector &args) +Value builtin_str(const Context *, const std::vector&, const std::vector &args) { std::stringstream stream; - for (int i = 0; i < args.size(); i++) { + for (size_t i = 0; i < args.size(); i++) { stream << args[i]; } return Value(stream.str()); } -Value builtin_lookup(const Context *, const QVector&, const QVector &args) +Value builtin_lookup(const Context *, const std::vector&, const std::vector &args) { double p, low_p, low_v, high_p, high_v; if (args.size() < 2 || !args[0].getnum(p) || args[1].vec.size() < 2 || args[1].vec[0]->vec.size() < 2) return Value(); if (!args[1].vec[0]->getv2(low_p, low_v) || !args[1].vec[0]->getv2(high_p, high_v)) return Value(); - for (int i = 1; i < args[1].vec.size(); i++) { + for (size_t i = 1; i < args[1].vec.size(); i++) { double this_p, this_v; if (args[1].vec[i]->getv2(this_p, this_v)) { if (this_p <= p && (this_p > low_p || low_p > p)) { @@ -370,8 +376,7 @@ void initialize_builtin_functions() void destroy_builtin_functions() { - foreach (AbstractFunction *v, builtin_functions) - delete v; + BOOST_FOREACH(BuiltinContainer::value_type &f, builtin_functions) delete f.second; +//std::for_each(builtin_functions.begin(), builtin_functions.end(), del_fun()); builtin_functions.clear(); } - diff --git a/src/function.h b/src/function.h index 7b58e38..623ef7e 100644 --- a/src/function.h +++ b/src/function.h @@ -2,43 +2,43 @@ #define FUNCTION_H_ #include "value.h" -#include -#include +#include +#include class AbstractFunction { public: virtual ~AbstractFunction(); - virtual Value evaluate(const class Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; + virtual Value evaluate(const class Context *ctx, const std::vector &call_argnames, const std::vector &call_argvalues) const; + virtual std::string dump(const std::string &indent, const std::string &name) const; }; class BuiltinFunction : public AbstractFunction { public: - typedef Value (*eval_func_t)(const Context *ctx, const QVector &argnames, const QVector &args); + typedef Value (*eval_func_t)(const Context *ctx, const std::vector &argnames, const std::vector &args); eval_func_t eval_func; BuiltinFunction(eval_func_t f) : eval_func(f) { } virtual ~BuiltinFunction(); - virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; + virtual Value evaluate(const Context *ctx, const std::vector &call_argnames, const std::vector &call_argvalues) const; + virtual std::string dump(const std::string &indent, const std::string &name) const; }; class Function : public AbstractFunction { public: - QVector argnames; - QVector argexpr; + std::vector argnames; + std::vector argexpr; Expression *expr; Function() { } virtual ~Function(); - virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; - virtual QString dump(QString indent, QString name) const; + virtual Value evaluate(const Context *ctx, const std::vector &call_argnames, const std::vector &call_argvalues) const; + virtual std::string dump(const std::string &indent, const std::string &name) const; }; #endif diff --git a/src/import.cc b/src/import.cc index 737ab31..b26d05d 100644 --- a/src/import.cc +++ b/src/import.cc @@ -42,6 +42,8 @@ #include #include #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope class ImportModule : public AbstractModule { @@ -55,17 +57,17 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati { ImportNode *node = new ImportNode(inst, type); - QVector argnames; + std::vector argnames; if (this->type == TYPE_DXF) { - argnames = QVector() << "file" << "layer" << "convexity" << "origin" << "scale"; + argnames += "file", "layer", "convexity", "origin", "scale"; } else { - argnames = QVector() << "file" << "convexity"; + argnames += "file", "convexity"; } - QVector argexpr; + std::vector argexpr; // Map old argnames to new argnames for compatibility - QVector inst_argnames = inst->argnames; - for (int i=0; i inst_argnames = inst->argnames; + for (size_t i=0; ifa = c.lookup_variable("$fa").num; Value v = c.lookup_variable("file"); - node->filename = c.get_absolute_path(QString::fromStdString(v.text)); -// node->filename = c.get_absolute_path(QString::fromStdString(c.lookup_variable("file").text)); - node->layername = QString::fromStdString(c.lookup_variable("layer", true).text); + node->filename = c.get_absolute_path(v.text); +// node->filename = c.get_absolute_path(c.lookup_variable("file").text); + node->layername = c.lookup_variable("layer", true).text; node->convexity = c.lookup_variable("convexity", true).num; if (node->convexity <= 0) @@ -114,10 +116,10 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c if (this->type == TYPE_STL) { - handle_dep(this->filename); - QFile f(this->filename); + handle_dep(QString::fromStdString(this->filename)); + QFile f(QString::fromStdString(this->filename)); if (!f.open(QIODevice::ReadOnly)) { - PRINTF("WARNING: Can't open import file `%s'.", this->filename.toAscii().data()); + PRINTF("WARNING: Can't open import file `%s'.", this->filename.c_str()); return p; } @@ -196,7 +198,7 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c if (this->type == TYPE_DXF) { - DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale); + DxfData dd(this->fn, this->fs, this->fa, QString::fromStdString(this->filename), QString::fromStdString(this->layername), this->origin_x, this->origin_y, this->scale); p->is2d = true; dxf_tesselate(p, dd, 0, true, false, 0); dxf_border_to_ps(p, &dd); @@ -212,7 +214,7 @@ std::string ImportNode::toString() const QString text; struct stat st; memset(&st, 0, sizeof(struct stat)); - stat(this->filename.toAscii().data(), &st); + stat(this->filename.c_str(), &st); stream << this->name(); switch (this->type) { diff --git a/src/importnode.h b/src/importnode.h index 94417b9..3fcdb37 100644 --- a/src/importnode.h +++ b/src/importnode.h @@ -3,7 +3,6 @@ #include "node.h" #include "visitor.h" -#include enum import_type_e { TYPE_STL, @@ -22,8 +21,8 @@ public: virtual std::string name() const; import_type_e type; - QString filename; - QString layername; + std::string filename; + std::string layername; int convexity; double fn, fs, fa; double origin_x, origin_y, scale; diff --git a/src/mainwin.cc b/src/mainwin.cc index a2c845d..c82f5f1 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -495,7 +495,7 @@ MainWindow::setFileName(const QString &filename) { if (filename.isEmpty()) { this->fileName.clear(); - this->root_ctx.document_path = currentdir; + this->root_ctx.document_path = currentdir.toStdString(); setWindowTitle("OpenSCAD - New Document[*]"); } else { @@ -518,7 +518,7 @@ MainWindow::setFileName(const QString &filename) this->fileName = fileinfo.fileName(); } - this->root_ctx.document_path = fileinfo.dir().absolutePath(); + this->root_ctx.document_path = fileinfo.dir().absolutePath().toStdString(); QDir::setCurrent(fileinfo.dir().absolutePath()); } @@ -1310,7 +1310,7 @@ void MainWindow::actionDisplayAST() e->setWindowTitle("AST Dump"); e->setReadOnly(true); if (root_module) { - e->setPlainText(root_module->dump("", "")); + e->setPlainText(QString::fromStdString(root_module->dump("", ""))); } else { e->setPlainText("No AST to dump. Please try compiling first..."); } diff --git a/src/module.cc b/src/module.cc index 0f1b1aa..49a5f1b 100644 --- a/src/module.cc +++ b/src/module.cc @@ -31,6 +31,8 @@ #include "function.h" #include "builtin.h" #include "printutils.h" +#include +#include AbstractModule::~AbstractModule() { @@ -49,9 +51,11 @@ AbstractNode *AbstractModule::evaluate(const Context*, const ModuleInstantiation return node; } -QString AbstractModule::dump(QString indent, QString name) const +std::string AbstractModule::dump(const std::string &indent, const std::string &name) const { - return QString("%1abstract module %2();\n").arg(indent, name); + std::stringstream dump; + dump << indent << "abstract module " << name << "();\n"; + return dump.str(); } ModuleInstantiation::~ModuleInstantiation() @@ -68,44 +72,42 @@ IfElseModuleInstantiation::~IfElseModuleInstantiation() delete v; } -QString ModuleInstantiation::dump(QString indent) const +std::string ModuleInstantiation::dump(const std::string &indent) const { - QString text = indent; - if (!label.isEmpty()) - text += label + QString(": "); - text += modname + QString("("); - for (int i=0; i < argnames.size(); i++) { - if (i > 0) - text += QString(", "); - if (!argnames[i].isEmpty()) - text += argnames[i] + QString(" = "); - text += QString::fromStdString(argexpr[i]->toString()); + std::stringstream dump; + dump << indent; + if (!label.empty()) dump << label <<": "; + dump << modname + "("; + for (size_t i=0; i < argnames.size(); i++) { + if (i > 0) dump << ", "; + if (!argnames[i].empty()) dump << argnames[i] << " = "; + dump << *argexpr[i]; } if (children.size() == 0) { - text += QString(");\n"); + dump << ");\n"; } else if (children.size() == 1) { - text += QString(")\n"); - text += children[0]->dump(indent + QString("\t")); + dump << ")\n"; + dump << children[0]->dump(indent + "\t"); } else { - text += QString(") {\n"); - for (int i = 0; i < children.size(); i++) { - text += children[i]->dump(indent + QString("\t")); + dump << ") {\n"; + for (size_t i = 0; i < children.size(); i++) { + dump << children[i]->dump(indent + "\t"); } - text += QString("%1}\n").arg(indent); + dump << indent << "}\n"; } - return text; + return dump.str(); } AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const { AbstractNode *node = NULL; if (this->ctx) { - PRINTA("WARNING: Ignoring recursive module instanciation of '%1'.", modname); + PRINTF("WARNING: Ignoring recursive module instanciation of '%s'.", modname.c_str()); } else { ModuleInstantiation *that = (ModuleInstantiation*)this; that->argvalues.clear(); foreach (Expression *v, that->argexpr) { - that->argvalues.append(v->evaluate(ctx)); + that->argvalues.push_back(v->evaluate(ctx)); } that->ctx = ctx; node = ctx->evaluate_module(this); @@ -119,10 +121,12 @@ Module::~Module() { foreach (Expression *v, assignments_expr) delete v; - foreach (AbstractFunction *v, functions) - delete v; - foreach (AbstractModule *v, modules) - delete v; + BOOST_FOREACH(FunctionContainer::value_type &f, functions) { + delete f.second; + } + BOOST_FOREACH(AbstractModuleContainer::value_type &m, modules) { + delete m.second; + } foreach (ModuleInstantiation *v, children) delete v; } @@ -143,12 +147,12 @@ AbstractNode *Module::evaluate(const Context *ctx, const ModuleInstantiation *in else c.usedlibs_p = NULL; - for (int i = 0; i < assignments_var.size(); i++) { + for (size_t i = 0; i < assignments_var.size(); i++) { c.set_variable(assignments_var[i], assignments_expr[i]->evaluate(&c)); } AbstractNode *node = new AbstractNode(inst); - for (int i = 0; i < children.size(); i++) { + for (size_t i = 0; i < children.size(); i++) { AbstractNode *n = children[i]->evaluate(&c); if (n != NULL) node->children.push_back(n); @@ -157,48 +161,39 @@ AbstractNode *Module::evaluate(const Context *ctx, const ModuleInstantiation *in return node; } -QString Module::dump(QString indent, QString name) const +std::string Module::dump(const std::string &indent, const std::string &name) const { - QString text, tab; - if (!name.isEmpty()) { - text = QString("%1module %2(").arg(indent, name); - for (int i=0; i < argnames.size(); i++) { - if (i > 0) - text += QString(", "); - text += argnames[i]; - if (argexpr[i]) - text += QString(" = ") + QString::fromStdString(argexpr[i]->toString()); + std::stringstream dump; + std::string tab; + if (!name.empty()) { + dump << indent << "module " << name << "("; + for (size_t i=0; i < argnames.size(); i++) { + if (i > 0) dump << ", "; + dump << argnames[i]; + if (argexpr[i]) dump << " = " << *argexpr[i]; } - text += QString(") {\n"); + dump << ") {\n"; tab = "\t"; } - { - QHashIterator i(functions); - while (i.hasNext()) { - i.next(); - text += i.value()->dump(indent + tab, i.key()); - } + BOOST_FOREACH(const FunctionContainer::value_type &f, functions) { + dump << f.second->dump(indent + tab, f.first); } - { - QHashIterator i(modules); - while (i.hasNext()) { - i.next(); - text += i.value()->dump(indent + tab, i.key()); - } + BOOST_FOREACH(const AbstractModuleContainer::value_type &m, modules) { + dump << m.second->dump(indent + tab, m.first); } - for (int i = 0; i < assignments_var.size(); i++) { - text += QString("%1%2 = %3;\n").arg(indent + tab, assignments_var[i], QString::fromStdString(assignments_expr[i]->toString())); + for (size_t i = 0; i < assignments_var.size(); i++) { + dump << indent << tab << assignments_var[i] << " = " << *assignments_expr[i] << ";\n"; } - for (int i = 0; i < children.size(); i++) { - text += children[i]->dump(indent + tab); + for (size_t i = 0; i < children.size(); i++) { + dump << children[i]->dump(indent + tab); } - if (!name.isEmpty()) { - text += QString("%1}\n").arg(indent); + if (!name.empty()) { + dump << indent << "}\n"; } - return text; + return dump.str(); } -QHash builtin_modules; +Module::AbstractModuleContainer builtin_modules; void initialize_builtin_modules() { @@ -220,7 +215,8 @@ void initialize_builtin_modules() void destroy_builtin_modules() { - foreach (AbstractModule *v, builtin_modules) - delete v; + BOOST_FOREACH(Module::AbstractModuleContainer::value_type &m, builtin_modules) { + delete m.second; + } builtin_modules.clear(); } diff --git a/src/module.h b/src/module.h index b680ea1..5262bfc 100644 --- a/src/module.h +++ b/src/module.h @@ -1,20 +1,20 @@ #ifndef MODULE_H_ #define MODULE_H_ -#include -#include -#include +#include +#include +#include #include "value.h" class ModuleInstantiation { public: - QString label; - QString modname; - QVector argnames; - QVector argexpr; - QVector argvalues; - QVector children; + std::string label; + std::string modname; + std::vector argnames; + std::vector argexpr; + std::vector argvalues; + std::vector children; bool tag_root; bool tag_highlight; @@ -24,7 +24,7 @@ public: ModuleInstantiation() : tag_root(false), tag_highlight(false), tag_background(false), ctx(NULL) { } virtual ~ModuleInstantiation(); - QString dump(QString indent) const; + std::string dump(const std::string &indent) const; class AbstractNode *evaluate(const Context *ctx) const; }; @@ -32,7 +32,7 @@ class IfElseModuleInstantiation : public ModuleInstantiation { public: virtual ~IfElseModuleInstantiation(); - QVector else_children; + std::vector else_children; }; class AbstractModule @@ -40,37 +40,40 @@ class AbstractModule public: virtual ~AbstractModule(); virtual class AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; - virtual QString dump(QString indent, QString name) const; + virtual std::string dump(const std::string &indent, const std::string &name) const; }; class Module : public AbstractModule { public: - QHash< QString, Module*> usedlibs; + typedef boost::unordered_map ModuleContainer; + ModuleContainer usedlibs; struct libs_cache_ent { Module *mod; - QString cache_id, msg; + std::string cache_id, msg; }; - static QHash libs_cache; - static Module *compile_library(QString filename); + static boost::unordered_map libs_cache; + static Module *compile_library(std::string filename); - QVector argnames; - QVector argexpr; + std::vector argnames; + std::vector argexpr; - QVector assignments_var; - QVector assignments_expr; + std::vector assignments_var; + std::vector assignments_expr; - QHash functions; - QHash modules; + typedef boost::unordered_map FunctionContainer; + FunctionContainer functions; + typedef boost::unordered_map AbstractModuleContainer; + AbstractModuleContainer modules; - QVector children; + std::vector children; Module() { } virtual ~Module(); virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; - virtual QString dump(QString indent, QString name) const; + virtual std::string dump(const std::string &indent, const std::string &name) const; }; #endif diff --git a/src/parser.y b/src/parser.y index 2bd425f..219dd5e 100644 --- a/src/parser.y +++ b/src/parser.y @@ -44,6 +44,8 @@ #include "value.h" #include "function.h" #include "printutils.h" +#include +#include int parser_error_pos = -1; @@ -54,18 +56,18 @@ int lexerget_lineno(void); int lexerlex_destroy(void); int lexerlex(void); -QVector module_stack; +std::vector module_stack; Module *module; class ArgContainer { -public: - QString argname; +public: + std::string argname; Expression *argexpr; }; class ArgsContainer { public: - QVector argnames; - QVector argexpr; + std::vector argnames; + std::vector argexpr; }; %} @@ -144,29 +146,29 @@ statement: '{' inner_input '}' | module_instantiation { if ($1) { - module->children.append($1); + module->children.push_back($1); } else { delete $1; } } | TOK_ID '=' expr ';' { bool add_new_assignment = true; - for (int i = 0; i < module->assignments_var.size(); i++) { - if (module->assignments_var[i] != QString($1)) + for (size_t i = 0; i < module->assignments_var.size(); i++) { + if (module->assignments_var[i] != $1) continue; delete module->assignments_expr[i]; module->assignments_expr[i] = $3; add_new_assignment = false; } if (add_new_assignment) { - module->assignments_var.append($1); - module->assignments_expr.append($3); + module->assignments_var.push_back($1); + module->assignments_expr.push_back($3); free($1); } } | TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' { Module *p = module; - module_stack.append(module); + module_stack.push_back(module); module = new Module(); p->modules[$2] = module; module->argnames = $4->argnames; @@ -174,7 +176,7 @@ statement: free($2); delete $4; } statement { - module = module_stack.last(); + module = module_stack.back(); module_stack.pop_back(); } | TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr { @@ -192,7 +194,7 @@ children_instantiation: module_instantiation { $$ = new ModuleInstantiation(); if ($1) { - $$->children.append($1); + $$->children.push_back($1); } else { delete $1; } @@ -205,13 +207,13 @@ if_statement: TOK_IF '(' expr ')' children_instantiation { $$ = new IfElseModuleInstantiation(); $$->modname = "if"; - $$->argnames.append(QString()); - $$->argexpr.append($3); + $$->argnames.push_back(""); + $$->argexpr.push_back($3); if ($$) { $$->children = $5->children; } else { - for (int i = 0; i < $5->children.count(); i++) + for (size_t i = 0; i < $5->children.size(); i++) delete $5->children[i]; } $5->children.clear(); @@ -227,7 +229,7 @@ ifelse_statement: if ($$) { $$->else_children = $3->children; } else { - for (int i = 0; i < $3->children.count(); i++) + for (size_t i = 0; i < $3->children.size(); i++) delete $3->children[i]; } $3->children.clear(); @@ -243,7 +245,7 @@ module_instantiation: if ($$) { $$->children = $2->children; } else { - for (int i = 0; i < $2->children.count(); i++) + for (size_t i = 0; i < $2->children.size(); i++) delete $2->children[i]; } $2->children.clear(); @@ -261,7 +263,7 @@ module_instantiation_list: $$ = $1; if ($$) { if ($2) - $$->children.append($2); + $$->children.push_back($2); } else { delete $2; } @@ -270,7 +272,7 @@ module_instantiation_list: single_module_instantiation: TOK_ID '(' arguments_call ')' { $$ = new ModuleInstantiation(); - $$->modname = QString($1); + $$->modname = $1; $$->argnames = $3->argnames; $$->argexpr = $3->argexpr; free($1); @@ -279,7 +281,7 @@ single_module_instantiation: TOK_ID ':' single_module_instantiation { $$ = $3; if ($$) - $$->label = QString($1); + $$->label = $1; free($1); } | '!' single_module_instantiation { @@ -321,14 +323,14 @@ expr: TOK_ID { $$ = new Expression(); $$->type = "L"; - $$->var_name = QString($1); + $$->var_name = $1; free($1); } | expr '.' TOK_ID { $$ = new Expression(); $$->type = "N"; - $$->children.append($1); - $$->var_name = QString($3); + $$->children.push_back($1); + $$->var_name = $3; free($3); } | TOK_STRING { @@ -348,16 +350,16 @@ expr: e_one->const_value = new Value(1.0); $$ = new Expression(); $$->type = "R"; - $$->children.append($2); - $$->children.append(e_one); - $$->children.append($4); + $$->children.push_back($2); + $$->children.push_back(e_one); + $$->children.push_back($4); } | '[' expr ':' expr ':' expr ']' { $$ = new Expression(); $$->type = "R"; - $$->children.append($2); - $$->children.append($4); - $$->children.append($6); + $$->children.push_back($2); + $$->children.push_back($4); + $$->children.push_back($6); } | '[' optional_commas ']' { $$ = new Expression(); @@ -371,80 +373,80 @@ expr: expr '*' expr { $$ = new Expression(); $$->type = "*"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr '/' expr { $$ = new Expression(); $$->type = "/"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr '%' expr { $$ = new Expression(); $$->type = "%"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr '+' expr { $$ = new Expression(); $$->type = "+"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr '-' expr { $$ = new Expression(); $$->type = "-"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr '<' expr { $$ = new Expression(); $$->type = "<"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr LE expr { $$ = new Expression(); $$->type = "<="; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr EQ expr { $$ = new Expression(); $$->type = "=="; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr NE expr { $$ = new Expression(); $$->type = "!="; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr GE expr { $$ = new Expression(); $$->type = ">="; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr '>' expr { $$ = new Expression(); $$->type = ">"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr AND expr { $$ = new Expression(); $$->type = "&&"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | expr OR expr { $$ = new Expression(); $$->type = "||"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | '+' expr { $$ = $2; @@ -452,12 +454,12 @@ expr: '-' expr { $$ = new Expression(); $$->type = "I"; - $$->children.append($2); + $$->children.push_back($2); } | '!' expr { $$ = new Expression(); $$->type = "!"; - $$->children.append($2); + $$->children.push_back($2); } | '(' expr ')' { $$ = $2; @@ -465,20 +467,20 @@ expr: expr '?' expr ':' expr { $$ = new Expression(); $$->type = "?:"; - $$->children.append($1); - $$->children.append($3); - $$->children.append($5); + $$->children.push_back($1); + $$->children.push_back($3); + $$->children.push_back($5); } | expr '[' expr ']' { $$ = new Expression(); $$->type = "[]"; - $$->children.append($1); - $$->children.append($3); + $$->children.push_back($1); + $$->children.push_back($3); } | TOK_ID '(' arguments_call ')' { $$ = new Expression(); $$->type = "F"; - $$->call_funcname = QString($1); + $$->call_funcname = $1; $$->call_argnames = $3->argnames; $$->children = $3->argexpr; free($1); @@ -492,11 +494,11 @@ vector_expr: expr { $$ = new Expression(); $$->type = 'V'; - $$->children.append($1); + $$->children.push_back($1); } | vector_expr ',' optional_commas expr { $$ = $1; - $$->children.append($4); + $$->children.push_back($4); } ; arguments_decl: @@ -505,27 +507,27 @@ arguments_decl: } | argument_decl { $$ = new ArgsContainer(); - $$->argnames.append($1->argname); - $$->argexpr.append($1->argexpr); + $$->argnames.push_back($1->argname); + $$->argexpr.push_back($1->argexpr); delete $1; } | arguments_decl ',' optional_commas argument_decl { $$ = $1; - $$->argnames.append($4->argname); - $$->argexpr.append($4->argexpr); + $$->argnames.push_back($4->argname); + $$->argexpr.push_back($4->argexpr); delete $4; } ; argument_decl: TOK_ID { $$ = new ArgContainer(); - $$->argname = QString($1); + $$->argname = $1; $$->argexpr = NULL; free($1); } | TOK_ID '=' expr { $$ = new ArgContainer(); - $$->argname = QString($1); + $$->argname = $1; $$->argexpr = $3; free($1); } ; @@ -536,14 +538,14 @@ arguments_call: } | argument_call { $$ = new ArgsContainer(); - $$->argnames.append($1->argname); - $$->argexpr.append($1->argexpr); + $$->argnames.push_back($1->argname); + $$->argexpr.push_back($1->argexpr); delete $1; } | arguments_call ',' optional_commas argument_call { $$ = $1; - $$->argnames.append($4->argname); - $$->argexpr.append($4->argexpr); + $$->argnames.push_back($4->argname); + $$->argexpr.push_back($4->argexpr); delete $4; } ; @@ -554,7 +556,7 @@ argument_call: } | TOK_ID '=' expr { $$ = new ArgContainer(); - $$->argname = QString($1); + $$->argname = $1; $$->argexpr = $3; free($1); } ; @@ -596,13 +598,11 @@ AbstractModule *parse(const char *text, const char *path, int debug) if (!module) return NULL; - QHashIterator i(module->usedlibs); - while (i.hasNext()) { - i.next(); - module->usedlibs[i.key()] = Module::compile_library(i.key()); - if (!module->usedlibs[i.key()]) { - PRINTF("WARNING: Failed to compile library `%s'.", i.key().toUtf8().data()); - module->usedlibs.remove(i.key()); + BOOST_FOREACH(Module::ModuleContainer::value_type &m, module->usedlibs) { + module->usedlibs[m.first] = Module::compile_library(m.first); + if (!module->usedlibs[m.first]) { + PRINTF("WARNING: Failed to compile library `%s'.", m.first.c_str()); + module->usedlibs.erase(m.first); } } @@ -610,46 +610,48 @@ AbstractModule *parse(const char *text, const char *path, int debug) return module; } -QHash Module::libs_cache; +boost::unordered_map Module::libs_cache; -Module *Module::compile_library(QString filename) +Module *Module::compile_library(std::string filename) { struct stat st; memset(&st, 0, sizeof(struct stat)); - stat(filename.toAscii().data(), &st); + stat(filename.c_str(), &st); - QString cache_id; - cache_id.sprintf("%x.%x", (int)st.st_mtime, (int)st.st_size); + std::stringstream idstream; + // FIXME: stream as hex + idstream << st.st_mtime << "." << st.st_size; + std::string cache_id = idstream.str(); - if (libs_cache.contains(filename) && libs_cache[filename].cache_id == cache_id) { - PRINT(libs_cache[filename].msg); - return &(*libs_cache[filename].mod); + if (libs_cache.find(filename) != libs_cache.end() && libs_cache[filename].cache_id == cache_id) { + PRINTF("%s", libs_cache[filename].msg.c_str()); + return &(*libs_cache[filename].mod); } - QFile f(filename); + QFile f(QString::fromStdString(filename)); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { - PRINTF("WARNING: Can't open library file `%s'.", filename.toUtf8().data()); + PRINTF("WARNING: Can't open library file `%s'.", filename.c_str()); return NULL; } QString text = QTextStream(&f).readAll(); print_messages_push(); - PRINTF("Compiling library `%s'.", filename.toUtf8().data()); - libs_cache_ent e = { NULL, cache_id, QString("WARNING: Library `%1' tries to recursively use itself!").arg(filename) }; - if (libs_cache.contains(filename)) + PRINTF("Compiling library `%s'.", filename.c_str()); + libs_cache_ent e = { NULL, cache_id, std::string("WARNING: Library `") + filename + "' tries to recursively use itself!" }; + if (libs_cache.find(filename) != libs_cache.end()) delete libs_cache[filename].mod; libs_cache[filename] = e; Module *backup_mod = module; - Module *lib_mod = dynamic_cast(parse(text.toLocal8Bit(), QFileInfo(filename).absoluteDir().absolutePath().toLocal8Bit(), 0)); + Module *lib_mod = dynamic_cast(parse(text.toLocal8Bit(), QFileInfo(QString::fromStdString(filename)).absoluteDir().absolutePath().toLocal8Bit(), 0)); module = backup_mod; if (lib_mod) { libs_cache[filename].mod = lib_mod; - libs_cache[filename].msg = print_messages_stack.last(); + libs_cache[filename].msg = print_messages_stack.last().toStdString(); } else { - libs_cache.remove(filename); + libs_cache.erase(filename); } print_messages_pop(); diff --git a/src/primitives.cc b/src/primitives.cc index 0da8fba..1a04cad 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -36,6 +36,8 @@ #include "visitor.h" #include #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope #define F_MINIMUM 0.01 @@ -110,30 +112,30 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstanti node->center = false; node->x = node->y = node->z = node->h = node->r1 = node->r2 = 1; - QVector argnames; - QVector argexpr; + std::vector argnames; + std::vector argexpr; switch (this->type) { case CUBE: - argnames = QVector() << "size" << "center"; + argnames += "size", "center"; break; case SPHERE: - argnames = QVector() << "r"; + argnames += "r"; break; case CYLINDER: - argnames = QVector() << "h" << "r1" << "r2" << "center"; + argnames += "h", "r1", "r2", "center"; break; case POLYHEDRON: - argnames = QVector() << "points" << "triangles" << "convexity"; + argnames += "points", "triangles", "convexity"; break; case SQUARE: - argnames = QVector() << "size" << "center"; + argnames += "size", "center"; break; case CIRCLE: - argnames = QVector() << "r"; + argnames += "r"; break; case POLYGON: - argnames = QVector() << "points" << "paths" << "convexity"; + argnames += "points", "paths", "convexity"; break; default: assert(false && "PrimitiveModule::evaluate(): Unknown node type"); @@ -463,7 +465,7 @@ sphere_next_r2: { p->append_poly(); for (size_t j=0; jtriangles.vec[i]->vec.size(); j++) { - int pt = this->triangles.vec[i]->vec[j]->num; + size_t pt = this->triangles.vec[i]->vec[j]->num; if (pt < this->points.vec.size()) { double px, py, pz; if (this->points.vec[pt]->getv3(px, py, pz)) diff --git a/src/projection.cc b/src/projection.cc index 67bd683..ce702e4 100644 --- a/src/projection.cc +++ b/src/projection.cc @@ -44,10 +44,8 @@ #include #include - -#include -#include -#include +#include +using namespace boost::assign; // bring 'operator+=()' into scope class ProjectionModule : public AbstractModule { @@ -60,8 +58,9 @@ AbstractNode *ProjectionModule::evaluate(const Context *ctx, const ModuleInstant { ProjectionNode *node = new ProjectionNode(inst); - QVector argnames = QVector() << "cut"; - QVector argexpr; + std::vector argnames; + argnames += "cut"; + std::vector argexpr; Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); diff --git a/src/render.cc b/src/render.cc index a463c67..15b4863 100644 --- a/src/render.cc +++ b/src/render.cc @@ -36,9 +36,9 @@ #include "progress.h" #include "visitor.h" -#include -#include #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope class RenderModule : public AbstractModule { @@ -51,8 +51,9 @@ AbstractNode *RenderModule::evaluate(const Context *ctx, const ModuleInstantiati { RenderNode *node = new RenderNode(inst); - QVector argnames = QVector() << "convexity"; - QVector argexpr; + std::vector argnames; + argnames += "convexity"; + std::vector argexpr; Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); diff --git a/src/surface.cc b/src/surface.cc index 2a4fec6..d9a0c6e 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -38,6 +38,9 @@ #include #include #include +#include +#include +using namespace boost::assign; // bring 'operator+=()' into scope class SurfaceModule : public AbstractModule { @@ -56,7 +59,7 @@ public: virtual std::string toString() const; virtual std::string name() const { return "surface"; } - QString filename; + std::string filename; bool center; int convexity; virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; @@ -68,13 +71,14 @@ AbstractNode *SurfaceModule::evaluate(const Context *ctx, const ModuleInstantiat node->center = false; node->convexity = 1; - QVector argnames = QVector() << "file" << "center" << "convexity"; - QVector argexpr; + std::vector argnames; + argnames += "file", "center", "convexity"; + std::vector argexpr; Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); - node->filename = c.get_absolute_path(QString::fromStdString(c.lookup_variable("file").text)); + node->filename = c.get_absolute_path(c.lookup_variable("file").text); Value center = c.lookup_variable("center", true); if (center.type == Value::BOOL) { @@ -97,16 +101,16 @@ void register_builtin_surface() PolySet *SurfaceNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const { PolySet *p = new PolySet(); - handle_dep(filename); - QFile f(filename); + handle_dep(QString::fromStdString(filename)); + QFile f(QString::fromStdString(filename)); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { - PRINTF("WARNING: Can't open DAT file `%s'.", filename.toAscii().data()); + PRINTF("WARNING: Can't open DAT file `%s'.", filename.c_str()); return p; } int lines = 0, columns = 0; - QHash,double> data; + boost::unordered_map,double> data; double min_val = 0; while (!f.atEnd()) @@ -123,7 +127,7 @@ PolySet *SurfaceNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) if (i >= columns) columns = i + 1; double v = fields[i].toDouble(); - data[QPair(lines, i)] = v; + data[std::make_pair(lines, i)] = v; min_val = fmin(v-1, min_val); } lines++; @@ -137,10 +141,10 @@ PolySet *SurfaceNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) for (int i = 1; i < lines; i++) for (int j = 1; j < columns; j++) { - double v1 = data[QPair(i-1, j-1)]; - double v2 = data[QPair(i-1, j)]; - double v3 = data[QPair(i, j-1)]; - double v4 = data[QPair(i, j)]; + double v1 = data[std::make_pair(i-1, j-1)]; + double v2 = data[std::make_pair(i-1, j)]; + double v3 = data[std::make_pair(i, j-1)]; + double v4 = data[std::make_pair(i, j)]; double vx = (v1 + v2 + v3 + v4) / 4; p->append_poly(); @@ -168,14 +172,14 @@ PolySet *SurfaceNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) { p->append_poly(); p->append_vertex(ox + 0, oy + i-1, min_val); - p->append_vertex(ox + 0, oy + i-1, data[QPair(i-1, 0)]); - p->append_vertex(ox + 0, oy + i, data[QPair(i, 0)]); + p->append_vertex(ox + 0, oy + i-1, data[std::make_pair(i-1, 0)]); + p->append_vertex(ox + 0, oy + i, data[std::make_pair(i, 0)]); p->append_vertex(ox + 0, oy + i, min_val); p->append_poly(); p->insert_vertex(ox + columns-1, oy + i-1, min_val); - p->insert_vertex(ox + columns-1, oy + i-1, data[QPair(i-1, columns-1)]); - p->insert_vertex(ox + columns-1, oy + i, data[QPair(i, columns-1)]); + p->insert_vertex(ox + columns-1, oy + i-1, data[std::make_pair(i-1, columns-1)]); + p->insert_vertex(ox + columns-1, oy + i, data[std::make_pair(i, columns-1)]); p->insert_vertex(ox + columns-1, oy + i, min_val); } @@ -183,14 +187,14 @@ PolySet *SurfaceNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) { p->append_poly(); p->insert_vertex(ox + i-1, oy + 0, min_val); - p->insert_vertex(ox + i-1, oy + 0, data[QPair(0, i-1)]); - p->insert_vertex(ox + i, oy + 0, data[QPair(0, i)]); + p->insert_vertex(ox + i-1, oy + 0, data[std::make_pair(0, i-1)]); + p->insert_vertex(ox + i, oy + 0, data[std::make_pair(0, i)]); p->insert_vertex(ox + i, oy + 0, min_val); p->append_poly(); p->append_vertex(ox + i-1, oy + lines-1, min_val); - p->append_vertex(ox + i-1, oy + lines-1, data[QPair(lines-1, i-1)]); - p->append_vertex(ox + i, oy + lines-1, data[QPair(lines-1, i)]); + p->append_vertex(ox + i-1, oy + lines-1, data[std::make_pair(lines-1, i-1)]); + p->append_vertex(ox + i, oy + lines-1, data[std::make_pair(lines-1, i)]); p->append_vertex(ox + i, oy + lines-1, min_val); } diff --git a/src/transform.cc b/src/transform.cc index 07aaee8..8975fd5 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -37,6 +37,8 @@ #include #include #include +#include +using namespace boost::assign; // bring 'operator+=()' into scope enum transform_type_e { SCALE, @@ -86,24 +88,24 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti for (int i = 0; i < 16; i++) node->matrix[i] = i % 5 == 0 ? 1.0 : 0.0; - QVector argnames; - QVector argexpr; + std::vector argnames; + std::vector argexpr; switch (this->type) { case SCALE: - argnames = QVector() << "v"; + argnames += "v"; break; case ROTATE: - argnames = QVector() << "a" << "v"; + argnames += "a", "v"; break; case MIRROR: - argnames = QVector() << "v"; + argnames += "v"; break; case TRANSLATE: - argnames = QVector() << "v"; + argnames += "v"; break; case MULTMATRIX: - argnames = QVector() << "m"; + argnames += "m"; break; default: assert(false); @@ -127,7 +129,7 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti Value val_a = c.lookup_variable("a"); if (val_a.type == Value::VECTOR) { - for (int i = 0; i < 3 && i < val_a.vec.size(); i++) { + for (size_t i = 0; i < 3 && i < val_a.vec.size(); i++) { double a; val_a.vec[i]->getnum(a); double c = cos(a*M_PI/180.0); @@ -230,7 +232,7 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti Value v = c.lookup_variable("m"); if (v.type == Value::VECTOR) { for (int i = 0; i < 16; i++) { - int x = i / 4, y = i % 4; + size_t x = i / 4, y = i % 4; if (y < v.vec.size() && v.vec[y]->type == Value::VECTOR && x < v.vec[y]->vec.size()) v.vec[y]->vec[x]->getnum(node->matrix[i]); } -- cgit v0.10.1 From acfd1e1b19eeffc62f66f9ff52605303fd0eb2d5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 06:30:48 +0200 Subject: More de-Qt-ify diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index aaf96ef..b75babe 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -90,7 +90,9 @@ static CSGTerm *evaluate_csg_term_from_ps(const State &state, const ModuleInstantiation *modinst, const AbstractPolyNode &node) { - CSGTerm *t = new CSGTerm(ps, state.matrix(), state.color(), QString("%1%2").arg(node.name().c_str()).arg(node.index())); + std::stringstream stream; + stream << node.name() << node.index(); + CSGTerm *t = new CSGTerm(ps, state.matrix(), state.color(), stream.str()); if (modinst->tag_highlight) highlights.push_back(t->link()); if (modinst->tag_background) { diff --git a/src/csgterm.cc b/src/csgterm.cc index 179381e..c615a58 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -26,6 +26,7 @@ #include "csgterm.h" #include "polyset.h" +#include /*! \class CSGTerm @@ -46,7 +47,7 @@ */ -CSGTerm::CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], QString label) +CSGTerm::CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], const std::string &label) { this->type = TYPE_PRIMITIVE; this->polyset = polyset; @@ -176,28 +177,33 @@ void CSGTerm::unlink() } } -QString CSGTerm::dump() +std::string CSGTerm::dump() { + std::stringstream dump; + if (type == TYPE_UNION) - return QString("(%1 + %2)").arg(left->dump(), right->dump()); - if (type == TYPE_INTERSECTION) - return QString("(%1 * %2)").arg(left->dump(), right->dump()); - if (type == TYPE_DIFFERENCE) - return QString("(%1 - %2)").arg(left->dump(), right->dump()); - return label; + dump << "(" << left->dump() << " + " << right->dump() << ")"; + else if (type == TYPE_INTERSECTION) + dump << "(" << left->dump() << " * " << right->dump() << ")"; + else if (type == TYPE_DIFFERENCE) + dump << "(" << left->dump() << " - " << right->dump() << ")"; + else + dump << this->label; + + return dump.str(); } CSGChain::CSGChain() { } -void CSGChain::add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, QString label) +void CSGChain::add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, std::string label) { - polysets.append(polyset); - matrices.append(m); - colors.append(color); - types.append(type); - labels.append(label); + polysets.push_back(polyset); + matrices.push_back(m); + colors.push_back(color); + types.push_back(type); + labels.push_back(label); } void CSGChain::import(CSGTerm *term, CSGTerm::type_e type) @@ -210,24 +216,24 @@ void CSGChain::import(CSGTerm *term, CSGTerm::type_e type) } } -QString CSGChain::dump() +std::string CSGChain::dump() { - QString text; + std::stringstream dump; + for (int i = 0; i < types.size(); i++) { if (types[i] == CSGTerm::TYPE_UNION) { - if (i != 0) - text += "\n"; - text += "+"; + if (i != 0) dump << "\n"; + dump << "+"; } else if (types[i] == CSGTerm::TYPE_DIFFERENCE) - text += " -"; + dump << " -"; else if (types[i] == CSGTerm::TYPE_INTERSECTION) - text += " *"; - text += labels[i]; + dump << " *"; + dump << labels[i]; } - text += "\n"; - return text; + dump << "\n"; + return dump.str(); } BoundingBox CSGChain::getBoundingBox() const diff --git a/src/csgterm.h b/src/csgterm.h index b0fffe4..2a89ef1 100644 --- a/src/csgterm.h +++ b/src/csgterm.h @@ -1,8 +1,8 @@ #ifndef CSGTERM_H_ #define CSGTERM_H_ -#include -#include +#include +#include #include "polyset.h" class CSGTerm @@ -17,14 +17,14 @@ public: type_e type; PolySet *polyset; - QString label; + std::string label; CSGTerm *left; CSGTerm *right; double m[16]; double color[4]; int refcounter; - CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], QString label); + CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], const std::string &label); CSGTerm(type_e type, CSGTerm *left, CSGTerm *right); CSGTerm *normalize(); @@ -32,23 +32,23 @@ public: CSGTerm *link(); void unlink(); - QString dump(); + std::string dump(); }; class CSGChain { public: - QVector polysets; - QVector matrices; - QVector colors; - QVector types; - QVector labels; + std::vector polysets; + std::vector matrices; + std::vector colors; + std::vector types; + std::vector labels; CSGChain(); - void add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, QString label); + void add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, std::string label); void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); - QString dump(); + std::string dump(); BoundingBox getBoundingBox() const; }; diff --git a/src/mainwin.cc b/src/mainwin.cc index c82f5f1..6408418 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1345,7 +1345,7 @@ void MainWindow::actionDisplayCSGProducts() e->setTabStopWidth(30); e->setWindowTitle("CSG Products Dump"); e->setReadOnly(true); - e->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n\n\nCSG rendering chain:\n%3\n\n\nHighlights CSG rendering chain:\n%4\n\n\nBackground CSG rendering chain:\n%5\n").arg(root_raw_term ? root_raw_term->dump() : "N/A", root_norm_term ? root_norm_term->dump() : "N/A", root_chain ? root_chain->dump() : "N/A", highlights_chain ? highlights_chain->dump() : "N/A", background_chain ? background_chain->dump() : "N/A")); + e->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n\n\nCSG rendering chain:\n%3\n\n\nHighlights CSG rendering chain:\n%4\n\n\nBackground CSG rendering chain:\n%5\n").arg(root_raw_term ? QString::fromStdString(root_raw_term->dump()) : "N/A", root_norm_term ? QString::fromStdString(root_norm_term->dump()) : "N/A", root_chain ? QString::fromStdString(root_chain->dump()) : "N/A", highlights_chain ? QString::fromStdString(highlights_chain->dump()) : "N/A", background_chain ? QString::fromStdString(background_chain->dump()) : "N/A")); e->show(); e->resize(600, 400); clearCurrentOutput(); diff --git a/src/value.cc b/src/value.cc index 139bd1c..740cb3d 100644 --- a/src/value.cc +++ b/src/value.cc @@ -377,9 +377,3 @@ std::ostream &operator<<(std::ostream &stream, const Value &value) return stream; } -std::ostream &operator<<(std::ostream &stream, const QString &str) -{ - stream << str.toStdString(); - return stream; -} - diff --git a/src/value.h b/src/value.h index 9140912..2003460 100644 --- a/src/value.h +++ b/src/value.h @@ -69,8 +69,4 @@ private: std::ostream &operator<<(std::ostream &stream, const Value &value); -// FIXME: Doesn't belong here.. -#include -std::ostream &operator<<(std::ostream &stream, const QString &str); - #endif -- cgit v0.10.1 From fa8bed77261fb9e4a0ec2b9be40c07908fc93116 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 16:53:05 +0200 Subject: refactor fix: use hex timestamps diff --git a/src/parser.y b/src/parser.y index 219dd5e..2d78d1f 100644 --- a/src/parser.y +++ b/src/parser.y @@ -619,8 +619,7 @@ Module *Module::compile_library(std::string filename) stat(filename.c_str(), &st); std::stringstream idstream; - // FIXME: stream as hex - idstream << st.st_mtime << "." << st.st_size; + idstream << std::hex << st.st_mtime << "." << st.st_size; std::string cache_id = idstream.str(); if (libs_cache.find(filename) != libs_cache.end() && libs_cache[filename].cache_id == cache_id) { -- cgit v0.10.1 From 488d173b4a3e323bbdd965ffdaf4ba9a08b79e2f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 18:42:12 +0200 Subject: killed warnings diff --git a/src/control.cc b/src/control.cc index d2df4f5..2e2f525 100644 --- a/src/control.cc +++ b/src/control.cc @@ -119,7 +119,7 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation if (type == ECHO) { QString msg = QString("ECHO: "); - for (int i = 0; i < inst->argnames.size(); i++) { + for (size_t i = 0; i < inst->argnames.size(); i++) { if (i > 0) msg += QString(", "); if (!inst->argnames[i].empty()) @@ -132,7 +132,7 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation if (type == ASSIGN) { Context c(inst->ctx); - for (int i = 0; i < inst->argnames.size(); i++) { + for (size_t i = 0; i < inst->argnames.size(); i++) { if (!inst->argnames[i].empty()) c.set_variable(inst->argnames[i], inst->argvalues[i]); } -- cgit v0.10.1 From 16b74df94104525436342e7a128573a2a63d3494 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 18:42:45 +0200 Subject: killed warnings diff --git a/src/expr.cc b/src/expr.cc index 8e482e8..c9eda4e 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -83,8 +83,8 @@ Value Expression::evaluate(const Context *context) const Value v1 = this->children[0]->evaluate(context); Value v2 = this->children[1]->evaluate(context); if (v1.type == Value::VECTOR && v2.type == Value::NUMBER) { - int i = (int)(v2.num); - if (i >= 0 && i < v1.vec.size()) + int i = int(v2.num); + if (i >= 0 && i < int(v1.vec.size())) return *v1.vec[i]; } return Value(); @@ -110,7 +110,7 @@ Value Expression::evaluate(const Context *context) const if (this->type == "V") { Value v; v.type = Value::VECTOR; - for (int i = 0; i < this->children.size(); i++) + for (size_t i = 0; i < this->children.size(); i++) v.append(new Value(this->children[i]->evaluate(context))); return v; } @@ -138,7 +138,7 @@ Value Expression::evaluate(const Context *context) const } if (this->type == "F") { std::vector argvalues; - for (int i=0; i < this->children.size(); i++) + for (size_t i=0; i < this->children.size(); i++) argvalues.push_back(this->children[i]->evaluate(context)); return context->evaluate_function(this->call_funcname, this->call_argnames, argvalues); } @@ -171,7 +171,7 @@ std::string Expression::toString() const } else if (this->type == "V") { stream << "["; - for (int i=0; i < this->children.size(); i++) { + for (size_t i=0; i < this->children.size(); i++) { if (i > 0) stream << ", "; stream << *this->children[i]; } @@ -185,7 +185,7 @@ std::string Expression::toString() const } else if (this->type == "F") { stream << this->call_funcname << "("; - for (int i=0; i < this->children.size(); i++) { + for (size_t i=0; i < this->children.size(); i++) { if (i > 0) stream << ", "; if (!this->call_argnames[i].empty()) stream << this->call_argnames[i] << " = "; stream << *this->children[i]; -- cgit v0.10.1 From f58c0a3eb5ce9f252e98f41ddc34dcb70a68052b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 18:51:29 +0200 Subject: Some cleanup of the Context class diff --git a/src/context.cc b/src/context.cc index 7a0e3cd..9722428 100644 --- a/src/context.cc +++ b/src/context.cc @@ -33,15 +33,30 @@ #include #include -Context::Context(const Context *parent) +std::vector Context::ctx_stack; + +/*! + Initializes this context. Optionally initializes a context for an external library +*/ +Context::Context(const Context *parent, const Module *library) + : parent(parent), inst_p(NULL) { - this->parent = parent; - functions_p = NULL; - modules_p = NULL; - usedlibs_p = NULL; - inst_p = NULL; - if (parent) document_path = parent->document_path; ctx_stack.push_back(this); + if (parent) document_path = parent->document_path; + if (library) { + this->functions_p = &library->functions; + this->modules_p = &library->modules; + this->usedlibs_p = &library->usedlibs; + for (size_t j = 0; j < library->assignments_var.size(); j++) { + this->set_variable(library->assignments_var[j], + library->assignments_expr[j]->evaluate(this)); + } + } + else { + functions_p = NULL; + modules_p = NULL; + usedlibs_p = NULL; + } } Context::~Context() @@ -49,11 +64,17 @@ Context::~Context() ctx_stack.pop_back(); } -void Context::args(const std::vector &argnames, const std::vector &argexpr, - const std::vector &call_argnames, const std::vector &call_argvalues) +/*! + Initialize context from argument lists (function call/module instantiation) + */ +void Context::args(const std::vector &argnames, + const std::vector &argexpr, + const std::vector &call_argnames, + const std::vector &call_argvalues) { for (size_t i=0; ievaluate(this->parent) : Value()); + set_variable(argnames[i], i < argexpr.size() && argexpr[i] ? + argexpr[i]->evaluate(this->parent) : Value()); } size_t posarg = 0; @@ -67,14 +88,20 @@ void Context::args(const std::vector &argnames, const std::vector Context::ctx_stack; - -void Context::set_variable(const std::string &name, Value value) +void Context::set_variable(const std::string &name, const Value &value) { if (name[0] == '$') - config_variables[name] = value; + this->config_variables[name] = value; + else + this->variables[name] = value; +} + +void Context::set_constant(const std::string &name, const Value &value) +{ + if (this->constants.find(name) != this->constants.end()) + PRINTF("WARNING: Attempt to modify constant '%s'.",name.c_str()); else - variables[name] = value; + this->constants[name] = value; } Value Context::lookup_variable(const std::string &name, bool silent) const @@ -87,79 +114,58 @@ Value Context::lookup_variable(const std::string &name, bool silent) const } return Value(); } - if (!parent && constants.find(name) != constants.end()) - return constants.find(name)->second; - if (variables.find(name) != variables.end()) - return variables.find(name)->second; - if (parent) - return parent->lookup_variable(name, silent); + if (!this->parent && this->constants.find(name) != this->constants.end()) + return this->constants.find(name)->second; + if (this->variables.find(name) != this->variables.end()) + return this->variables.find(name)->second; + if (this->parent) + return this->parent->lookup_variable(name, silent); if (!silent) PRINTF("WARNING: Ignoring unknown variable '%s'.", name.c_str()); return Value(); } -void Context::set_constant(const std::string &name, Value value) +Value Context::evaluate_function(const std::string &name, + const std::vector &argnames, + const std::vector &argvalues) const { - if (constants.count(name)) - PRINTF("WARNING: Attempt to modify constant '%s'.",name.c_str()); - else - constants[name] = value; -} - -Value Context::evaluate_function(const std::string &name, const std::vector &argnames, const std::vector &argvalues) const -{ - if (functions_p && functions_p->find(name) != functions_p->end()) - return functions_p->find(name)->second->evaluate(this, argnames, argvalues); - if (usedlibs_p) { - BOOST_FOREACH(const ModuleContainer::value_type &m, *usedlibs_p) { - if (m.second->functions.count(name)) { - Module *lib = m.second; - Context ctx(parent); - ctx.functions_p = &lib->functions; - ctx.modules_p = &lib->modules; - ctx.usedlibs_p = &lib->usedlibs; - for (size_t j = 0; j < lib->assignments_var.size(); j++) { - ctx.set_variable(lib->assignments_var[j], lib->assignments_expr[j]->evaluate(&ctx)); - } + if (this->functions_p && this->functions_p->find(name) != this->functions_p->end()) + return this->functions_p->find(name)->second->evaluate(this, argnames, argvalues); + if (this->usedlibs_p) { + BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) { + if (m.second->functions.find(name) != m.second->functions.end()) { + Context ctx(this->parent, m.second); return m.second->functions[name]->evaluate(&ctx, argnames, argvalues); } } } - if (parent) - return parent->evaluate_function(name, argnames, argvalues); - PRINTF("WARNING: Ignoring unkown function '%s'.", name.c_str()); + if (this->parent) + return this->parent->evaluate_function(name, argnames, argvalues); + PRINTF("WARNING: Ignoring unknown function '%s'.", name.c_str()); return Value(); } -AbstractNode *Context::evaluate_module(const ModuleInstantiation *inst) const +AbstractNode *Context::evaluate_module(const ModuleInstantiation &inst) const { - if (modules_p && modules_p->find(inst->modname) != modules_p->end()) - return modules_p->find(inst->modname)->second->evaluate(this, inst); - if (usedlibs_p) { - BOOST_FOREACH(const ModuleContainer::value_type &m, *usedlibs_p) { - if (m.second->modules.count(inst->modname)) { - Module *lib = m.second; - Context ctx(parent); - ctx.functions_p = &lib->functions; - ctx.modules_p = &lib->modules; - ctx.usedlibs_p = &lib->usedlibs; - for (size_t j = 0; j < lib->assignments_var.size(); j++) { - ctx.set_variable(lib->assignments_var[j], lib->assignments_expr[j]->evaluate(&ctx)); - } - return m.second->modules[inst->modname]->evaluate(&ctx, inst); + if (this->modules_p && this->modules_p->find(inst.modname) != this->modules_p->end()) + return this->modules_p->find(inst.modname)->second->evaluate(this, &inst); + if (this->usedlibs_p) { + BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) { + if (m.second->modules.find(inst.modname) != m.second->modules.end()) { + Context ctx(this->parent, m.second); + return m.second->modules[inst.modname]->evaluate(&ctx, &inst); } } } - if (parent) - return parent->evaluate_module(inst); - PRINTF("WARNING: Ignoring unkown module '%s'.", inst->modname.c_str()); + if (this->parent) return this->parent->evaluate_module(inst); + PRINTF("WARNING: Ignoring unknown module '%s'.", inst.modname.c_str()); return NULL; } /*! Returns the absolute path to the given filename, unless it's empty. */ -std::string Context::get_absolute_path(const std::string &filename) const +std::string Context::getAbsolutePath(const std::string &filename) const { if (!filename.empty()) { return QFileInfo(QDir(QString::fromStdString(this->document_path)), @@ -169,4 +175,3 @@ std::string Context::get_absolute_path(const std::string &filename) const return filename; } } - diff --git a/src/context.h b/src/context.h index 99726a9..f085e01 100644 --- a/src/context.h +++ b/src/context.h @@ -11,34 +11,42 @@ using boost::unordered_map; class Context { public: + Context(const Context *parent = NULL, const class Module *library = NULL); + ~Context(); + + void args(const std::vector &argnames, + const std::vector &argexpr, + const std::vector &call_argnames, + const std::vector &call_argvalues); + + void set_variable(const std::string &name, const Value &value); + void set_constant(const std::string &name, const Value &value); + + Value lookup_variable(const std::string &name, bool silent = false) const; + Value evaluate_function(const std::string &name, + const std::vector &argnames, + const std::vector &argvalues) const; + class AbstractNode *evaluate_module(const class ModuleInstantiation &inst) const; + + void setDocumentPath(const std::string &path) { this->document_path = path; } + std::string getAbsolutePath(const std::string &filename) const; + +public: const Context *parent; - typedef unordered_map ValueMap; - ValueMap constants; - ValueMap variables; - ValueMap config_variables; const unordered_map *functions_p; const unordered_map *modules_p; typedef unordered_map ModuleContainer; const ModuleContainer *usedlibs_p; - const class ModuleInstantiation *inst_p; - std::string document_path; + const ModuleInstantiation *inst_p; static std::vector ctx_stack; - Context(const Context *parent = NULL); - ~Context(); - - void args(const std::vector &argnames, const std::vector &argexpr, const std::vector &call_argnames, const std::vector &call_argvalues); - - void set_variable(const std::string &name, Value value); - Value lookup_variable(const std::string &name, bool silent = false) const; - - void set_constant(const std::string &name, Value value); - - std::string get_absolute_path(const std::string &filename) const; - - Value evaluate_function(const std::string &name, const std::vector &argnames, const std::vector &argvalues) const; - class AbstractNode *evaluate_module(const ModuleInstantiation *inst) const; +private: + typedef unordered_map ValueMap; + ValueMap constants; + ValueMap variables; + ValueMap config_variables; + std::string document_path; }; #endif diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 88e007c..636ea6c 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -51,7 +51,7 @@ Value builtin_dxf_dim(const Context *ctx, const std::vector &argnam for (size_t i = 0; i < argnames.size() && i < args.size(); i++) { if (argnames[i] == "file") - filename = ctx->get_absolute_path(args[i].text); + filename = ctx->getAbsolutePath(args[i].text); if (argnames[i] == "layer") layername = args[i].text; if (argnames[i] == "origin") @@ -135,7 +135,7 @@ Value builtin_dxf_cross(const Context *ctx, const std::vector &argn for (size_t i = 0; i < argnames.size() && i < args.size(); i++) { if (argnames[i] == "file") - filename = ctx->get_absolute_path(args[i].text); + filename = ctx->getAbsolutePath(args[i].text); if (argnames[i] == "layer") layername = args[i].text; if (argnames[i] == "origin") diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index 283c7f4..94792ef 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -77,7 +77,7 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI Value slices = c.lookup_variable("slices", true); if (!file.text.empty()) - node->filename = c.get_absolute_path(file.text); + node->filename = c.getAbsolutePath(file.text); node->layername = layer.text; node->height = height.num; diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index b333fbf..44a70a5 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -71,7 +71,7 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI Value scale = c.lookup_variable("scale", true); if (!file.text.empty()) - node->filename = c.get_absolute_path(file.text); + node->filename = c.getAbsolutePath(file.text); node->layername = layer.text; node->convexity = (int)convexity.num; diff --git a/src/func.cc b/src/func.cc index 31c8ad2..52f04dd 100644 --- a/src/func.cc +++ b/src/func.cc @@ -58,7 +58,9 @@ Function::~Function() delete expr; } -Value Function::evaluate(const Context *ctx, const std::vector &call_argnames, const std::vector &call_argvalues) const +Value Function::evaluate(const Context *ctx, + const std::vector &call_argnames, + const std::vector &call_argvalues) const { Context c(ctx); c.args(argnames, argexpr, call_argnames, call_argvalues); diff --git a/src/import.cc b/src/import.cc index b26d05d..0f107f7 100644 --- a/src/import.cc +++ b/src/import.cc @@ -82,8 +82,8 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati node->fa = c.lookup_variable("$fa").num; Value v = c.lookup_variable("file"); - node->filename = c.get_absolute_path(v.text); -// node->filename = c.get_absolute_path(c.lookup_variable("file").text); + node->filename = c.getAbsolutePath(v.text); +// node->filename = c.getAbsolutePath(c.lookup_variable("file").text); node->layername = c.lookup_variable("layer", true).text; node->convexity = c.lookup_variable("convexity", true).num; diff --git a/src/mainwin.cc b/src/mainwin.cc index 6408418..4b5ba89 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -495,7 +495,7 @@ MainWindow::setFileName(const QString &filename) { if (filename.isEmpty()) { this->fileName.clear(); - this->root_ctx.document_path = currentdir.toStdString(); + this->root_ctx.setDocumentPath(currentdir.toStdString()); setWindowTitle("OpenSCAD - New Document[*]"); } else { @@ -518,7 +518,7 @@ MainWindow::setFileName(const QString &filename) this->fileName = fileinfo.fileName(); } - this->root_ctx.document_path = fileinfo.dir().absolutePath().toStdString(); + this->root_ctx.setDocumentPath(fileinfo.dir().absolutePath().toStdString()); QDir::setCurrent(fileinfo.dir().absolutePath()); } diff --git a/src/module.cc b/src/module.cc index 49a5f1b..2852c4e 100644 --- a/src/module.cc +++ b/src/module.cc @@ -102,7 +102,7 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const { AbstractNode *node = NULL; if (this->ctx) { - PRINTF("WARNING: Ignoring recursive module instanciation of '%s'.", modname.c_str()); + PRINTF("WARNING: Ignoring recursive module instantiation of '%s'.", modname.c_str()); } else { ModuleInstantiation *that = (ModuleInstantiation*)this; that->argvalues.clear(); @@ -110,7 +110,7 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const that->argvalues.push_back(v->evaluate(ctx)); } that->ctx = ctx; - node = ctx->evaluate_module(this); + node = ctx->evaluate_module(*this); that->ctx = NULL; that->argvalues.clear(); } diff --git a/src/surface.cc b/src/surface.cc index d9a0c6e..b7dfa0f 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -78,7 +78,7 @@ AbstractNode *SurfaceModule::evaluate(const Context *ctx, const ModuleInstantiat Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); - node->filename = c.get_absolute_path(c.lookup_variable("file").text); + node->filename = c.getAbsolutePath(c.lookup_variable("file").text); Value center = c.lookup_variable("center", true); if (center.type == Value::BOOL) { -- cgit v0.10.1 From 34e4213c3331f02b5210eef7b21d554546417813 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 19:18:26 +0200 Subject: default color somehow got messed up - fixed now diff --git a/tests/regression/dumptest/allmodules-expected.txt b/tests/regression/dumptest/allmodules-expected.txt index 50c6605..2849d7a 100644 --- a/tests/regression/dumptest/allmodules-expected.txt +++ b/tests/regression/dumptest/allmodules-expected.txt @@ -34,5 +34,5 @@ group() { multmatrix([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); - color([-1, -1, -1, -1]); + color([-1, -1, -1, 1]); } diff --git a/tests/regression/dumptest/color-expected.txt b/tests/regression/dumptest/color-expected.txt index 375ed05..ef862fc 100644 --- a/tests/regression/dumptest/color-expected.txt +++ b/tests/regression/dumptest/color-expected.txt @@ -1,3 +1,3 @@ group() { - color([-1, -1, -1, -1]); + color([-1, -1, -1, 1]); } -- cgit v0.10.1 From 7adf625ecc7647f9c6ba20bcc86f89256a962f2a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 19:32:55 +0200 Subject: Added allfunctions diff --git a/testdata/scad/minimal/allfunctions.scad b/testdata/scad/minimal/allfunctions.scad new file mode 100644 index 0000000..e58bd07 --- /dev/null +++ b/testdata/scad/minimal/allfunctions.scad @@ -0,0 +1,24 @@ +a = abs(); +a = sign(); +a = rands(); +a = min(); +a = max(); +a = sin(); +a = cos(); +a = asin(); +a = acos(); +a = tan(); +a = atan(); +a = atan2(); +a = round(); +a = ceil(); +a = floor(); +a = pow(); +a = sqrt(); +a = exp(); +a = log(); +a = ln(); +a = str(); +a = lookup(); +a = dxf_dim(); +a = dxf_cross(); diff --git a/tests/regression/csgtermtest/allfunctions-expected.txt b/tests/regression/csgtermtest/allfunctions-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/allfunctions-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtexttest/allfunctions-expected.txt b/tests/regression/csgtexttest/allfunctions-expected.txt new file mode 100644 index 0000000..331822f --- /dev/null +++ b/tests/regression/csgtexttest/allfunctions-expected.txt @@ -0,0 +1 @@ +group1 diff --git a/tests/regression/dumptest/allfunctions-expected.txt b/tests/regression/dumptest/allfunctions-expected.txt new file mode 100644 index 0000000..0a04719 --- /dev/null +++ b/tests/regression/dumptest/allfunctions-expected.txt @@ -0,0 +1 @@ +group(); -- cgit v0.10.1 From 90e96a34ac684831c756da60a32b4571a585f030 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 19:57:24 +0200 Subject: Added polygon-tests diff --git a/testdata/scad/features/polygon-tests.scad b/testdata/scad/features/polygon-tests.scad new file mode 100644 index 0000000..ab3a345 --- /dev/null +++ b/testdata/scad/features/polygon-tests.scad @@ -0,0 +1,17 @@ +polygon(); +polygon([]); +polygon([[],[]]); +polygon([[[]]]); +translate([2,0,0]) polygon([[0,0], [1,0], [1,1]]); +translate([0,2,0]) polygon([[0,0]]); +translate([2,2,0]) polygon([[0,0],[1,1]]); +translate([2,2,0]) polygon([[0,0],[1,1],[2,2]]); +translate([0,-2,0]) polygon(points=[[0,0], [1,0], [1,1], [0,1]]); +translate([0,-4,0]) polygon(points=[[0,0], [1,0], [1,1], [0,1]], paths=[]); +translate([2,-2,0]) polygon([[0,0], [1,0], [0.8,0.5], [1,1], [0,1]]); + +points = [[0,0], [0.5,-0.2], [1,0], [1.2,0.5], [1,1], [0.5,1.2], [0,1], [-0.2,0.5]]; +translate([-2,0,0]) polygon(points); +translate([-2,-2,0]) polygon(points=points, paths=[[0,1,2,3], [4,5,6,7]]); + +// FIXME: convexity diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 30879f7..2bdef54 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -208,6 +208,7 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cube-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/sphere-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/polygon-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad diff --git a/tests/regression/cgalpngtest/polygon-tests-expected.png b/tests/regression/cgalpngtest/polygon-tests-expected.png new file mode 100644 index 0000000..89aed2f Binary files /dev/null and b/tests/regression/cgalpngtest/polygon-tests-expected.png differ -- cgit v0.10.1 From 946605234c7cf35cadfe9bde5531ebe6655f1b42 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 22:42:48 +0200 Subject: Added import_dxf-tests diff --git a/testdata/dxf/multiple-layers.dxf b/testdata/dxf/multiple-layers.dxf new file mode 100644 index 0000000..88b530f --- /dev/null +++ b/testdata/dxf/multiple-layers.dxf @@ -0,0 +1,2140 @@ +999 +dxflib 2.2.0.0 + 0 +SECTION + 2 +HEADER + 9 +$ACADVER + 1 +AC1015 + 9 +$HANDSEED + 5 +FFFF + 9 +$DIMASZ + 40 +2.5 + 9 +$PLIMMIN + 10 +0.0 + 20 +0.0 + 9 +$DIMEXE + 40 +1.25 + 9 +$DIMGAP + 40 +0.625 + 9 +$PLIMMAX + 10 +210.0 + 20 +297.0 + 9 +$INSUNITS + 70 +4 + 9 +$DIMEXO + 40 +0.625 + 9 +$DIMTXT + 40 +2.5 + 9 +$CLAYER + 8 +Layer with a pretty long name including \ "special" /'\\ characters + 0 +ENDSEC + 0 +SECTION + 2 +TABLES + 0 +TABLE + 2 +VPORT + 5 +8 +100 +AcDbSymbolTable + 70 +1 + 0 +VPORT + 5 +30 +100 +AcDbSymbolTableRecord +100 +AcDbViewportTableRecord + 2 +*Active + 70 +0 + 10 +0.0 + 20 +0.0 + 11 +1.0 + 21 +1.0 + 12 +286.3055555555554861 + 22 +148.5 + 13 +0.0 + 23 +0.0 + 14 +10.0 + 24 +10.0 + 15 +10.0 + 25 +10.0 + 16 +0.0 + 26 +0.0 + 36 +1.0 + 17 +0.0 + 27 +0.0 + 37 +0.0 + 40 +297.0 + 41 +1.92798353909465 + 42 +50.0 + 43 +0.0 + 44 +0.0 + 50 +0.0 + 51 +0.0 + 71 +0 + 72 +100 + 73 +1 + 74 +3 + 75 +1 + 76 +1 + 77 +0 + 78 +0 +281 +0 + 65 +1 +110 +0.0 +120 +0.0 +130 +0.0 +111 +1.0 +121 +0.0 +131 +0.0 +112 +0.0 +122 +1.0 +132 +0.0 + 79 +0 +146 +0.0 + 0 +ENDTAB + 0 +TABLE + 2 +LTYPE + 5 +5 +100 +AcDbSymbolTable + 70 +21 + 0 +LTYPE + 5 +14 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +ByBlock + 70 +0 + 3 + + 72 +65 + 73 +0 + 40 +0.0 + 0 +LTYPE + 5 +15 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +ByLayer + 70 +0 + 3 + + 72 +65 + 73 +0 + 40 +0.0 + 0 +LTYPE + 5 +16 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +CONTINUOUS + 70 +0 + 3 +Solid line + 72 +65 + 73 +0 + 40 +0.0 + 0 +LTYPE + 5 +31 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DOT + 70 +0 + 3 +Dot . . . . . . . . . . . . . . . . . . . . . . + 72 +65 + 73 +2 + 40 +6.3499999999999996 + 49 +0.0 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 0 +LTYPE + 5 +32 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DOT2 + 70 +0 + 3 +Dot (.5x) ..................................... + 72 +65 + 73 +2 + 40 +3.1749999999999998 + 49 +0.0 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 0 +LTYPE + 5 +33 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DOTX2 + 70 +0 + 3 +Dot (2x) . . . . . . . . . . . . . + 72 +65 + 73 +2 + 40 +12.6999999999999993 + 49 +0.0 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 0 +LTYPE + 5 +34 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DASHED + 70 +0 + 3 +Dashed __ __ __ __ __ __ __ __ __ __ __ __ __ _ + 72 +65 + 73 +2 + 40 +19.0500000000000007 + 49 +12.6999999999999993 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 0 +LTYPE + 5 +35 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DASHED2 + 70 +0 + 3 +Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + 72 +65 + 73 +2 + 40 +9.5250000000000004 + 49 +6.3499999999999996 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 0 +LTYPE + 5 +36 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DASHEDX2 + 70 +0 + 3 +Dashed (2x) ____ ____ ____ ____ ____ ___ + 72 +65 + 73 +2 + 40 +38.1000000000000014 + 49 +25.3999999999999986 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 0 +LTYPE + 5 +37 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DASHDOT + 70 +0 + 3 +Dash dot __ . __ . __ . __ . __ . __ . __ . __ + 72 +65 + 73 +4 + 40 +25.3999999999999986 + 49 +12.6999999999999993 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 0 +LTYPE + 5 +38 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DASHDOT2 + 70 +0 + 3 +Dash dot (.5x) _._._._._._._._._._._._._._._. + 72 +65 + 73 +4 + 40 +12.6999999999999993 + 49 +6.3499999999999996 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 0 +LTYPE + 5 +39 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DASHDOTX2 + 70 +0 + 3 +Dash dot (2x) ____ . ____ . ____ . ___ + 72 +65 + 73 +4 + 40 +50.7999999999999972 + 49 +25.3999999999999986 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 0 +LTYPE + 5 +3A +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DIVIDE + 70 +0 + 3 +Divide ____ . . ____ . . ____ . . ____ . . ____ + 72 +65 + 73 +6 + 40 +31.75 + 49 +12.6999999999999993 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 0 +LTYPE + 5 +3B +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DIVIDE2 + 70 +0 + 3 +Divide (.5x) __..__..__..__..__..__..__..__.._ + 72 +65 + 73 +6 + 40 +15.875 + 49 +6.3499999999999996 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 0 +LTYPE + 5 +3C +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +DIVIDEX2 + 70 +0 + 3 +Divide (2x) ________ . . ________ . . _ + 72 +65 + 73 +6 + 40 +63.5 + 49 +25.3999999999999986 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 0 +LTYPE + 5 +3D +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +CENTER + 70 +0 + 3 +Center ____ _ ____ _ ____ _ ____ _ ____ _ ____ + 72 +65 + 73 +4 + 40 +50.7999999999999972 + 49 +31.75 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 49 +6.3499999999999996 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 0 +LTYPE + 5 +3E +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +CENTER2 + 70 +0 + 3 +Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___ + 72 +65 + 73 +4 + 40 +28.5749999999999993 + 49 +19.0500000000000007 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 49 +3.1749999999999998 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 0 +LTYPE + 5 +3F +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +CENTERX2 + 70 +0 + 3 +Center (2x) ________ __ ________ __ _____ + 72 +65 + 73 +4 + 40 +101.5999999999999943 + 49 +63.5 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 49 +12.6999999999999993 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 0 +LTYPE + 5 +40 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +BORDER + 70 +0 + 3 +Border __ __ . __ __ . __ __ . __ __ . __ __ . + 72 +65 + 73 +6 + 40 +44.4500000000000028 + 49 +12.6999999999999993 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 49 +12.6999999999999993 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-6.3499999999999996 + 74 +0 + 0 +LTYPE + 5 +41 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +BORDER2 + 70 +0 + 3 +Border (.5x) __.__.__.__.__.__.__.__.__.__.__. + 72 +65 + 73 +6 + 40 +22.2250000000000014 + 49 +6.3499999999999996 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 49 +6.3499999999999996 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-3.1749999999999998 + 74 +0 + 0 +LTYPE + 5 +42 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +BORDERX2 + 70 +0 + 3 +Border (2x) ____ ____ . ____ ____ . ___ + 72 +65 + 73 +6 + 40 +88.9000000000000057 + 49 +25.3999999999999986 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 49 +25.3999999999999986 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 49 +0.0 + 74 +0 + 49 +-12.6999999999999993 + 74 +0 + 0 +ENDTAB + 0 +TABLE + 2 +LAYER + 5 +2 +100 +AcDbSymbolTable + 70 +3 + 0 +LAYER + 5 +10 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +0 + 70 +0 + 62 +7 +420 +0 + 6 +CONTINUOUS +370 +25 +390 +F + 0 +LAYER + 5 +43 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +noname + 70 +0 + 62 +7 +420 +0 + 6 +CONTINUOUS +370 +0 +390 +F + 0 +LAYER + 5 +44 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +Layer with a pretty long name including \ "special" /'\\ characters + 70 +0 + 62 +7 +420 +0 + 6 +CONTINUOUS +370 +0 +390 +F + 0 +ENDTAB + 0 +TABLE + 2 +STYLE + 5 +3 +100 +AcDbSymbolTable + 70 +1 + 0 +STYLE + 5 +11 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord + 2 +Standard + 70 +0 + 40 +0.0 + 41 +0.75 + 50 +0.0 + 71 +0 + 42 +2.5 + 3 +txt + 4 + + 0 +ENDTAB + 0 +TABLE + 2 +VIEW + 5 +6 +100 +AcDbSymbolTable + 70 +0 + 0 +ENDTAB + 0 +TABLE + 2 +UCS + 5 +7 +100 +AcDbSymbolTable + 70 +0 + 0 +ENDTAB + 0 +TABLE + 2 +APPID + 5 +9 +100 +AcDbSymbolTable + 70 +1 + 0 +APPID + 5 +12 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord + 2 +ACAD + 70 +0 + 0 +ENDTAB + 0 +TABLE + 2 +DIMSTYLE + 5 +A +100 +AcDbSymbolTable + 70 +1 +100 +AcDbDimStyleTable + 71 +0 + 0 +DIMSTYLE +105 +27 +100 +AcDbSymbolTableRecord +100 +AcDbDimStyleTableRecord + 2 +Standard + 41 +2.5 + 42 +0.625 + 43 +3.75 + 44 +1.25 + 70 +0 + 73 +0 + 74 +0 + 77 +1 + 78 +8 +140 +2.5 +141 +2.5 +143 +0.03937007874016 +147 +0.625 +171 +3 +172 +1 +271 +2 +272 +2 +274 +3 +278 +44 +283 +0 +284 +8 +340 +11 + 0 +ENDTAB + 0 +TABLE + 2 +BLOCK_RECORD + 5 +1 +100 +AcDbSymbolTable + 70 +1 + 0 +BLOCK_RECORD + 5 +1F +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*Model_Space +340 +22 + 0 +BLOCK_RECORD + 5 +1B +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*Paper_Space +340 +1E + 0 +BLOCK_RECORD + 5 +23 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*Paper_Space0 +340 +26 + 0 +ENDTAB + 0 +ENDSEC + 0 +SECTION + 2 +BLOCKS + 0 +BLOCK + 5 +20 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockBegin + 2 +*Model_Space + 70 +0 + 10 +0.0 + 20 +0.0 + 30 +0.0 + 3 +*Model_Space + 1 + + 0 +ENDBLK + 5 +21 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockEnd + 0 +BLOCK + 5 +1C +100 +AcDbEntity + 67 +1 + 8 +0 +100 +AcDbBlockBegin + 2 +*Paper_Space + 70 +0 + 10 +0.0 + 20 +0.0 + 30 +0.0 + 3 +*Paper_Space + 1 + + 0 +ENDBLK + 5 +1D +100 +AcDbEntity + 67 +1 + 8 +0 +100 +AcDbBlockEnd + 0 +BLOCK + 5 +24 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockBegin + 2 +*Paper_Space0 + 70 +0 + 10 +0.0 + 20 +0.0 + 30 +0.0 + 3 +*Paper_Space0 + 1 + + 0 +ENDBLK + 5 +25 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockEnd + 0 +ENDSEC + 0 +SECTION + 2 +ENTITIES + 0 +LINE + 5 +45 +100 +AcDbEntity +100 +AcDbLine + 8 +0 + 62 +256 +370 +-1 + 6 +ByLayer + 10 +-40.0 + 20 +40.0 + 30 +0.0 + 11 +40.0 + 21 +40.0 + 31 +0.0 + 0 +LINE + 5 +46 +100 +AcDbEntity +100 +AcDbLine + 8 +0 + 62 +256 +370 +-1 + 6 +ByLayer + 10 +40.0 + 20 +40.0 + 30 +0.0 + 11 +40.0 + 21 +-40.0 + 31 +0.0 + 0 +LINE + 5 +47 +100 +AcDbEntity +100 +AcDbLine + 8 +0 + 62 +256 +370 +-1 + 6 +ByLayer + 10 +40.0 + 20 +-40.0 + 30 +0.0 + 11 +-40.0 + 21 +-40.0 + 31 +0.0 + 0 +LINE + 5 +48 +100 +AcDbEntity +100 +AcDbLine + 8 +0 + 62 +256 +370 +-1 + 6 +ByLayer + 10 +-40.0 + 20 +-40.0 + 30 +0.0 + 11 +-40.0 + 21 +40.0 + 31 +0.0 + 0 +CIRCLE + 5 +49 +100 +AcDbEntity +100 +AcDbCircle + 8 +noname + 62 +256 +370 +-1 + 6 +ByLayer + 10 +0.0 + 20 +0.0 + 30 +0.0 + 40 +70.7106781186547551 + 0 +LINE + 5 +4A +100 +AcDbEntity +100 +AcDbLine + 8 +Layer with a pretty long name including \ "special" /'\\ characters + 62 +256 +370 +-1 + 6 +ByLayer + 10 +100.0 + 20 +0.0 + 30 +0.0 + 11 +50.0000000000000142 + 21 +86.6025403784438623 + 31 +0.0 + 0 +LINE + 5 +4B +100 +AcDbEntity +100 +AcDbLine + 8 +Layer with a pretty long name including \ "special" /'\\ characters + 62 +256 +370 +-1 + 6 +ByLayer + 10 +50.0000000000000142 + 20 +86.6025403784438623 + 30 +0.0 + 11 +-49.9999999999999858 + 21 +86.6025403784438907 + 31 +0.0 + 0 +LINE + 5 +4C +100 +AcDbEntity +100 +AcDbLine + 8 +Layer with a pretty long name including \ "special" /'\\ characters + 62 +256 +370 +-1 + 6 +ByLayer + 10 +-49.9999999999999858 + 20 +86.6025403784438907 + 30 +0.0 + 11 +-100.0000000000000142 + 21 +0.0000000000000122 + 31 +0.0 + 0 +LINE + 5 +4D +100 +AcDbEntity +100 +AcDbLine + 8 +Layer with a pretty long name including \ "special" /'\\ characters + 62 +256 +370 +-1 + 6 +ByLayer + 10 +-100.0000000000000142 + 20 +0.0000000000000122 + 30 +0.0 + 11 +-50.0000000000000497 + 21 +-86.6025403784438481 + 31 +0.0 + 0 +LINE + 5 +4E +100 +AcDbEntity +100 +AcDbLine + 8 +Layer with a pretty long name including \ "special" /'\\ characters + 62 +256 +370 +-1 + 6 +ByLayer + 10 +-50.0000000000000497 + 20 +-86.6025403784438481 + 30 +0.0 + 11 +49.9999999999998579 + 21 +-86.6025403784439618 + 31 +0.0 + 0 +LINE + 5 +4F +100 +AcDbEntity +100 +AcDbLine + 8 +Layer with a pretty long name including \ "special" /'\\ characters + 62 +256 +370 +-1 + 6 +ByLayer + 10 +49.9999999999998579 + 20 +-86.6025403784439618 + 30 +0.0 + 11 +100.0000000000000142 + 21 +-0.0000000000002021 + 31 +0.0 + 0 +ENDSEC + 0 +SECTION + 2 +OBJECTS + 0 +DICTIONARY + 5 +C +100 +AcDbDictionary +280 +0 +281 +1 + 3 +ACAD_GROUP +350 +D + 3 +ACAD_LAYOUT +350 +1A + 3 +ACAD_MLINESTYLE +350 +17 + 3 +ACAD_PLOTSETTINGS +350 +19 + 3 +ACAD_PLOTSTYLENAME +350 +E + 3 +AcDbVariableDictionary +350 +50 + 0 +DICTIONARY + 5 +D +100 +AcDbDictionary +280 +0 +281 +1 + 0 +ACDBDICTIONARYWDFLT + 5 +E +100 +AcDbDictionary +281 +1 + 3 +Normal +350 +F +100 +AcDbDictionaryWithDefault +340 +F + 0 +ACDBPLACEHOLDER + 5 +F + 0 +DICTIONARY + 5 +17 +100 +AcDbDictionary +280 +0 +281 +1 + 3 +Standard +350 +18 + 0 +MLINESTYLE + 5 +18 +100 +AcDbMlineStyle + 2 +STANDARD + 70 +0 + 3 + + 62 +256 + 51 +90.0 + 52 +90.0 + 71 +2 + 49 +0.5 + 62 +256 + 6 +BYLAYER + 49 +-0.5 + 62 +256 + 6 +BYLAYER + 0 +DICTIONARY + 5 +19 +100 +AcDbDictionary +280 +0 +281 +1 + 0 +DICTIONARY + 5 +1A +100 +AcDbDictionary +281 +1 + 3 +Layout1 +350 +1E + 3 +Layout2 +350 +26 + 3 +Model +350 +22 + 0 +LAYOUT + 5 +1E +100 +AcDbPlotSettings + 1 + + 2 +C:\Program Files\AutoCAD 2002\plotters\DWF ePlot (optimized for plotting).pc3 + 4 + + 6 + + 40 +0.0 + 41 +0.0 + 42 +0.0 + 43 +0.0 + 44 +0.0 + 45 +0.0 + 46 +0.0 + 47 +0.0 + 48 +0.0 + 49 +0.0 +140 +0.0 +141 +0.0 +142 +1.0 +143 +1.0 + 70 +688 + 72 +0 + 73 +0 + 74 +5 + 7 + + 75 +16 +147 +1.0 +148 +0.0 +149 +0.0 +100 +AcDbLayout + 1 +Layout1 + 70 +1 + 71 +1 + 10 +0.0 + 20 +0.0 + 11 +420.0 + 21 +297.0 + 12 +0.0 + 22 +0.0 + 32 +0.0 + 14 +100000000000000000000.0 + 24 +100000000000000000000.0 + 34 +100000000000000000000.0 + 15 +-100000000000000000000.0 + 25 +-100000000000000000000.0 + 35 +-100000000000000000000.0 +146 +0.0 + 13 +0.0 + 23 +0.0 + 33 +0.0 + 16 +1.0 + 26 +0.0 + 36 +0.0 + 17 +0.0 + 27 +1.0 + 37 +0.0 + 76 +0 +330 +1B + 0 +LAYOUT + 5 +22 +100 +AcDbPlotSettings + 1 + + 2 +C:\Program Files\AutoCAD 2002\plotters\DWF ePlot (optimized for plotting).pc3 + 4 + + 6 + + 40 +0.0 + 41 +0.0 + 42 +0.0 + 43 +0.0 + 44 +0.0 + 45 +0.0 + 46 +0.0 + 47 +0.0 + 48 +0.0 + 49 +0.0 +140 +0.0 +141 +0.0 +142 +1.0 +143 +1.0 + 70 +1712 + 72 +0 + 73 +0 + 74 +0 + 7 + + 75 +0 +147 +1.0 +148 +0.0 +149 +0.0 +100 +AcDbLayout + 1 +Model + 70 +1 + 71 +0 + 10 +0.0 + 20 +0.0 + 11 +12.0 + 21 +9.0 + 12 +0.0 + 22 +0.0 + 32 +0.0 + 14 +0.0 + 24 +0.0 + 34 +0.0 + 15 +0.0 + 25 +0.0 + 35 +0.0 +146 +0.0 + 13 +0.0 + 23 +0.0 + 33 +0.0 + 16 +1.0 + 26 +0.0 + 36 +0.0 + 17 +0.0 + 27 +1.0 + 37 +0.0 + 76 +0 +330 +1F + 0 +LAYOUT + 5 +26 +100 +AcDbPlotSettings + 1 + + 2 +C:\Program Files\AutoCAD 2002\plotters\DWF ePlot (optimized for plotting).pc3 + 4 + + 6 + + 40 +0.0 + 41 +0.0 + 42 +0.0 + 43 +0.0 + 44 +0.0 + 45 +0.0 + 46 +0.0 + 47 +0.0 + 48 +0.0 + 49 +0.0 +140 +0.0 +141 +0.0 +142 +1.0 +143 +1.0 + 70 +688 + 72 +0 + 73 +0 + 74 +5 + 7 + + 75 +16 +147 +1.0 +148 +0.0 +149 +0.0 +100 +AcDbLayout + 1 +Layout2 + 70 +1 + 71 +2 + 10 +0.0 + 20 +0.0 + 11 +12.0 + 21 +9.0 + 12 +0.0 + 22 +0.0 + 32 +0.0 + 14 +0.0 + 24 +0.0 + 34 +0.0 + 15 +0.0 + 25 +0.0 + 35 +0.0 +146 +0.0 + 13 +0.0 + 23 +0.0 + 33 +0.0 + 16 +1.0 + 26 +0.0 + 36 +0.0 + 17 +0.0 + 27 +1.0 + 37 +0.0 + 76 +0 +330 +23 + 0 +DICTIONARY + 5 +50 +100 +AcDbDictionary +281 +1 + 3 +DIMASSOC +350 +52 + 3 +HIDETEXT +350 +51 + 0 +DICTIONARYVAR + 5 +51 +100 +DictionaryVariables +280 +0 + 1 +2 + 0 +DICTIONARYVAR + 5 +52 +100 +DictionaryVariables +280 +0 + 1 +1 + 0 +ENDSEC + 0 +EOF diff --git a/testdata/scad/features/import_dxf-tests.scad b/testdata/scad/features/import_dxf-tests.scad new file mode 100644 index 0000000..814a46c --- /dev/null +++ b/testdata/scad/features/import_dxf-tests.scad @@ -0,0 +1,9 @@ +import_dxf(); +translate([-210,0,0]) import_dxf(file="../../dxf/polygons.dxf"); +translate([-210,0,0]) import_dxf(file="../../dxf/polygons.dxf", origin=[0,110]); +translate([-210,0,0]) import_dxf(file="../../dxf/polygons.dxf", origin=[110,110], scale=0.5); +import_dxf(file="../../dxf/multiple-layers.dxf"); +translate([-200,200,0]) import_dxf(file="../../dxf/multiple-layers.dxf", layer="0"); +translate([0,200,0]) import_dxf(file="../../dxf/multiple-layers.dxf", layer="0"); +translate([200,200,0]) import_dxf(file="../../dxf/multiple-layers.dxf", layer="noname"); +translate([0,200,0]) import_dxf(file="../../dxf/multiple-layers.dxf", layer="Layer with a pretty long name including \\ \"special\" /'\\\\ characters"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2bdef54..c274435 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -205,13 +205,14 @@ add_cmdline_test(cgaltest stl ${CGALTEST_FILES}) LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/circle-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/square-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/polygon-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cube-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/sphere-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/cylinder-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/polygon-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/import_dxf-tests-expected.png b/tests/regression/cgalpngtest/import_dxf-tests-expected.png new file mode 100644 index 0000000..7c8a63e Binary files /dev/null and b/tests/regression/cgalpngtest/import_dxf-tests-expected.png differ -- cgit v0.10.1 From 6096f2734a9a2f2c789f2e948c021def6b41f85b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 22:44:41 +0200 Subject: De-Qt-ification continues, almost done with DxfData diff --git a/src/CGAL_Nef_polyhedron_DxfData.cc b/src/CGAL_Nef_polyhedron_DxfData.cc index 4bfb205..fe58636 100644 --- a/src/CGAL_Nef_polyhedron_DxfData.cc +++ b/src/CGAL_Nef_polyhedron_DxfData.cc @@ -55,21 +55,21 @@ DxfData *CGAL_Nef_polyhedron::convertToDxfData() const this_point = grid.align(x, y); } else { this_point = grid.align(x, y) = dxfdata->points.size(); - dxfdata->points.append(Vector2d(x, y)); + dxfdata->points.push_back(Vector2d(x, y)); } if (first_point < 0) { - dxfdata->paths.append(DxfData::Path()); + dxfdata->paths.push_back(DxfData::Path()); first_point = this_point; } if (this_point != last_point) { - dxfdata->paths.last().points.append(&dxfdata->points[this_point]); + dxfdata->paths.back().indices.push_back(this_point); last_point = this_point; } } } if (first_point >= 0) { - dxfdata->paths.last().is_closed = 1; - dxfdata->paths.last().points.append(&dxfdata->points[first_point]); + dxfdata->paths.back().is_closed = 1; + dxfdata->paths.back().indices.push_back(first_point); } } diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 791ad51..652881f 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -155,7 +155,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr } DxfData *dxf = np.convertToDxfData(); dxf_tesselate(ps, *dxf, 0, true, false, 0); - dxf_border_to_ps(ps, dxf); + dxf_border_to_ps(ps, *dxf); ps3->unlink(); delete dxf; } @@ -166,23 +166,23 @@ cant_project_non_simple_polyhedron: return ps; } -static void add_slice(PolySet *ps, DxfData::Path &pt, double rot1, double rot2, double h1, double h2) +static void add_slice(PolySet *ps, const DxfData &dxf, DxfData::Path &path, double rot1, double rot2, double h1, double h2) { - for (int j = 1; j < pt.points.count(); j++) + for (size_t j = 1; j < path.indices.size(); j++) { int k = j - 1; - double jx1 = (*pt.points[j])[0] * cos(rot1*M_PI/180) + (*pt.points[j])[1] * sin(rot1*M_PI/180); - double jy1 = (*pt.points[j])[0] * -sin(rot1*M_PI/180) + (*pt.points[j])[1] * cos(rot1*M_PI/180); + double jx1 = dxf.points[path.indices[j]][0] * cos(rot1*M_PI/180) + dxf.points[path.indices[j]][1] * sin(rot1*M_PI/180); + double jy1 = dxf.points[path.indices[j]][0] * -sin(rot1*M_PI/180) + dxf.points[path.indices[j]][1] * cos(rot1*M_PI/180); - double jx2 = (*pt.points[j])[0] * cos(rot2*M_PI/180) + (*pt.points[j])[1] * sin(rot2*M_PI/180); - double jy2 = (*pt.points[j])[0] * -sin(rot2*M_PI/180) + (*pt.points[j])[1] * cos(rot2*M_PI/180); + double jx2 = dxf.points[path.indices[j]][0] * cos(rot2*M_PI/180) + dxf.points[path.indices[j]][1] * sin(rot2*M_PI/180); + double jy2 = dxf.points[path.indices[j]][0] * -sin(rot2*M_PI/180) + dxf.points[path.indices[j]][1] * cos(rot2*M_PI/180); - double kx1 = (*pt.points[k])[0] * cos(rot1*M_PI/180) + (*pt.points[k])[1] * sin(rot1*M_PI/180); - double ky1 = (*pt.points[k])[0] * -sin(rot1*M_PI/180) + (*pt.points[k])[1] * cos(rot1*M_PI/180); + double kx1 = dxf.points[path.indices[k]][0] * cos(rot1*M_PI/180) + dxf.points[path.indices[k]][1] * sin(rot1*M_PI/180); + double ky1 = dxf.points[path.indices[k]][0] * -sin(rot1*M_PI/180) + dxf.points[path.indices[k]][1] * cos(rot1*M_PI/180); - double kx2 = (*pt.points[k])[0] * cos(rot2*M_PI/180) + (*pt.points[k])[1] * sin(rot2*M_PI/180); - double ky2 = (*pt.points[k])[0] * -sin(rot2*M_PI/180) + (*pt.points[k])[1] * cos(rot2*M_PI/180); + double kx2 = dxf.points[path.indices[k]][0] * cos(rot2*M_PI/180) + dxf.points[path.indices[k]][1] * sin(rot2*M_PI/180); + double ky2 = dxf.points[path.indices[k]][0] * -sin(rot2*M_PI/180) + dxf.points[path.indices[k]][1] * cos(rot2*M_PI/180); double dia1_len_sq = (jy1-ky2)*(jy1-ky2) + (jx1-kx2)*(jx1-kx2); double dia2_len_sq = (jy2-ky1)*(jy2-ky1) + (jx2-kx1)*(jx2-kx1); @@ -190,7 +190,7 @@ static void add_slice(PolySet *ps, DxfData::Path &pt, double rot1, double rot2, if (dia1_len_sq > dia2_len_sq) { ps->append_poly(); - if (pt.is_inner) { + if (path.is_inner) { ps->append_vertex(kx1, ky1, h1); ps->append_vertex(jx1, jy1, h1); ps->append_vertex(jx2, jy2, h2); @@ -201,7 +201,7 @@ static void add_slice(PolySet *ps, DxfData::Path &pt, double rot1, double rot2, } ps->append_poly(); - if (pt.is_inner) { + if (path.is_inner) { ps->append_vertex(kx2, ky2, h2); ps->append_vertex(kx1, ky1, h1); ps->append_vertex(jx2, jy2, h2); @@ -214,7 +214,7 @@ static void add_slice(PolySet *ps, DxfData::Path &pt, double rot1, double rot2, else { ps->append_poly(); - if (pt.is_inner) { + if (path.is_inner) { ps->append_vertex(kx1, ky1, h1); ps->append_vertex(jx1, jy1, h1); ps->append_vertex(kx2, ky2, h2); @@ -225,7 +225,7 @@ static void add_slice(PolySet *ps, DxfData::Path &pt, double rot1, double rot2, } ps->append_poly(); - if (pt.is_inner) { + if (path.is_inner) { ps->append_vertex(jx2, jy2, h2); ps->append_vertex(kx2, ky2, h2); ps->append_vertex(jx1, jy1, h1); @@ -260,7 +260,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, dxf = sum.convertToDxfData();; } else { - dxf = new DxfData(node.fn, node.fs, node.fa, QString::fromStdString(node.filename), QString::fromStdString(node.layername), node.origin_x, node.origin_y, node.scale); + dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } PolySet *ps = extrudeDxfData(node, *dxf); @@ -285,7 +285,7 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const DxfLinearExtrudeNode &node, } bool first_open_path = true; - for (int i = 0; i < dxf.paths.count(); i++) + for (size_t i = 0; i < dxf.paths.size(); i++) { if (dxf.paths[i].is_closed) continue; @@ -295,10 +295,10 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const DxfLinearExtrudeNode &node, first_open_path = false; } PRINTF(" %9.5f %10.5f ... %10.5f %10.5f", - (*dxf.paths[i].points.first())[0] / node.scale + node.origin_x, - (*dxf.paths[i].points.first())[1] / node.scale + node.origin_y, - (*dxf.paths[i].points.last())[0] / node.scale + node.origin_x, - (*dxf.paths[i].points.last())[1] / node.scale + node.origin_y); + dxf.points[dxf.paths[i].indices.front()][0] / node.scale + node.origin_x, + dxf.points[dxf.paths[i].indices.front()][1] / node.scale + node.origin_y, + dxf.points[dxf.paths[i].indices.back()][0] / node.scale + node.origin_x, + dxf.points[dxf.paths[i].indices.back()][1] / node.scale + node.origin_y); } @@ -312,11 +312,11 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const DxfLinearExtrudeNode &node, double t2 = node.twist*(j+1) / node.slices; double g1 = h1 + (h2-h1)*j / node.slices; double g2 = h1 + (h2-h1)*(j+1) / node.slices; - for (int i = 0; i < dxf.paths.count(); i++) + for (size_t i = 0; i < dxf.paths.size(); i++) { if (!dxf.paths[i].is_closed) continue; - add_slice(ps, dxf.paths[i], t1, t2, g1, g2); + add_slice(ps, dxf, dxf.paths[i], t1, t2, g1, g2); } } } @@ -324,11 +324,11 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const DxfLinearExtrudeNode &node, { dxf_tesselate(ps, dxf, 0, false, true, h1); dxf_tesselate(ps, dxf, 0, true, true, h2); - for (int i = 0; i < dxf.paths.count(); i++) + for (size_t i = 0; i < dxf.paths.size(); i++) { if (!dxf.paths[i].is_closed) continue; - add_slice(ps, dxf.paths[i], 0, 0, h1, h2); + add_slice(ps, dxf, dxf.paths[i], 0, 0, h1, h2); } } @@ -357,7 +357,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, dxf = sum.convertToDxfData(); } else { - dxf = new DxfData(node.fn, node.fs, node.fa, QString::fromStdString(node.filename), QString::fromStdString(node.layername), node.origin_x, node.origin_y, node.scale); + dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); } PolySet *ps = rotateDxfData(node, *dxf); @@ -371,11 +371,11 @@ PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, D PolySet *ps = new PolySet(); ps->convexity = node.convexity; - for (int i = 0; i < dxf.paths.count(); i++) + for (int i = 0; i < dxf.paths.size(); i++) { double max_x = 0; - for (int j = 0; j < dxf.paths[i].points.count(); j++) { - max_x = fmax(max_x, (*dxf.paths[i].points[j])[0]); + for (int j = 0; j < dxf.paths[i].indices.size(); j++) { + max_x = fmax(max_x, dxf.points[dxf.paths[i].indices[j]][0]); } int fragments = get_fragments_from_r(max_x, node.fn, node.fs, node.fa); @@ -383,29 +383,29 @@ PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, D double ***points; points = new double**[fragments]; for (int j=0; j < fragments; j++) { - points[j] = new double*[dxf.paths[i].points.count()]; - for (int k=0; k < dxf.paths[i].points.count(); k++) + points[j] = new double*[dxf.paths[i].indices.size()]; + for (int k=0; k < dxf.paths[i].indices.size(); k++) points[j][k] = new double[3]; } for (int j = 0; j < fragments; j++) { double a = (j*2*M_PI) / fragments; - for (int k = 0; k < dxf.paths[i].points.count(); k++) { - if ((*dxf.paths[i].points[k])[0] == 0) { + for (int k = 0; k < dxf.paths[i].indices.size(); k++) { + if (dxf.points[dxf.paths[i].indices[k]][0] == 0) { points[j][k][0] = 0; points[j][k][1] = 0; } else { - points[j][k][0] = (*dxf.paths[i].points[k])[0] * sin(a); - points[j][k][1] = (*dxf.paths[i].points[k])[0] * cos(a); + points[j][k][0] = dxf.points[dxf.paths[i].indices[k]][0] * sin(a); + points[j][k][1] = dxf.points[dxf.paths[i].indices[k]][0] * cos(a); } - points[j][k][2] = (*dxf.paths[i].points[k])[1]; + points[j][k][2] = dxf.points[dxf.paths[i].indices[k]][1]; } } for (int j = 0; j < fragments; j++) { int j1 = j + 1 < fragments ? j + 1 : 0; - for (int k = 0; k < dxf.paths[i].points.count(); k++) { - int k1 = k + 1 < dxf.paths[i].points.count() ? k + 1 : 0; + for (size_t k = 0; k < dxf.paths[i].indices.size(); k++) { + int k1 = k + 1 < dxf.paths[i].indices.size() ? k + 1 : 0; if (points[j][k][0] != points[j1][k][0] || points[j][k][1] != points[j1][k][1] || points[j][k][2] != points[j1][k][2]) { @@ -432,7 +432,7 @@ PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, D } for (int j=0; j < fragments; j++) { - for (int k=0; k < dxf.paths[i].points.count(); k++) + for (size_t k=0; k < dxf.paths[i].indices.size(); k++) delete[] points[j][k]; delete[] points[j]; } diff --git a/src/dxfdata.cc b/src/dxfdata.cc index 7bf4364..430a1c3 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -35,12 +35,14 @@ #include #include "mathc99.h" #include +#include +#include +#include struct Line { - Vector2d *p[2]; + int idx[2]; // indices into DxfData::points bool disabled; - Line(Vector2d *p1, Vector2d *p2) { p[0] = p1; p[1] = p2; disabled = false; } - Line() { p[0] = NULL; p[1] = NULL; disabled = false; } + Line(int i1 = -1, int i2 = -1) { idx[0] = i1; idx[1] = i2; disabled = false; } }; DxfData::DxfData() @@ -48,51 +50,53 @@ DxfData::DxfData() } /*! - Reads a layer from the given file, or all layers if layername.isEmpty() + Reads a layer from the given file, or all layers if layername.empty() */ -DxfData::DxfData(double fn, double fs, double fa, QString filename, QString layername, double xorigin, double yorigin, double scale) +DxfData::DxfData(double fn, double fs, double fa, + const std::string &filename, const std::string &layername, + double xorigin, double yorigin, double scale) { - handle_dep(filename); // Register ourselves as a dependency + handle_dep(QString::fromStdString(filename)); // Register ourselves as a dependency - QFile f(filename); + QFile f(QString::fromStdString(filename)); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { - PRINTF("WARNING: Can't open DXF file `%s'.", filename.toUtf8().data()); + PRINTF("WARNING: Can't open DXF file `%s'.", filename.c_str()); return; } QTextStream stream(&f); - Grid2d< QVector > grid(GRID_COARSE); - QList lines; // Global lines - QHash< QString, QList > blockdata; // Lines in blocks + Grid2d< std::vector > grid(GRID_COARSE); + std::vector lines; // Global lines + QHash< QString, std::vector > blockdata; // Lines in blocks bool in_entities_section = false; bool in_blocks_section = false; - QString current_block; + std::string current_block; #define ADD_LINE(_x1, _y1, _x2, _y2) do { \ double _p1x = _x1, _p1y = _y1, _p2x = _x2, _p2y = _y2; \ if (!in_entities_section && !in_blocks_section) \ break; \ if (in_entities_section && \ - !(layername.isEmpty() || layername == layer)) \ + !(layername.empty() || layername == layer)) \ break; \ grid.align(_p1x, _p1y); \ grid.align(_p2x, _p2y); \ - grid.data(_p1x, _p1y).append(lines.count()); \ - grid.data(_p2x, _p2y).append(lines.count()); \ + grid.data(_p1x, _p1y).push_back(lines.size()); \ + grid.data(_p2x, _p2y).push_back(lines.size()); \ if (in_entities_section) \ - lines.append( \ + lines.push_back( \ Line(addPoint(_p1x, _p1y), addPoint(_p2x, _p2y))); \ - if (in_blocks_section && !current_block.isNull()) \ - blockdata[current_block].append( \ + if (in_blocks_section && !current_block.empty()) \ + blockdata[QString::fromStdString(current_block)].push_back( \ Line(addPoint(_p1x, _p1y), addPoint(_p2x, _p2y))); \ } while (0) - QString mode, layer, name, iddata; + std::string mode, layer, name, iddata; int dimtype = 0; double coords[7][2]; // Used by DIMENSION entities - QVector xverts; - QVector yverts; + std::vector xverts; + std::vector yverts; double radius = 0; double arc_start_angle = 0, arc_stop_angle = 0; double ellipse_start_angle = 0, ellipse_stop_angle = 0; @@ -116,7 +120,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye int id = id_str.toInt(&status); if (!status) { - PRINTA("WARNING: Illegal ID `%1' in `%3'.", id_str, filename); + PRINTF("WARNING: Illegal ID `%s' in `%s'.", id_str.toUtf8().data(), filename.c_str()); break; } @@ -234,13 +238,13 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye else if (mode == "INSERT") { // scale is stored in ellipse_start|stop_angle, rotation in arc_start_angle; // due to the parser code not checking entity type - int n = blockdata[iddata].size(); + int n = blockdata[QString::fromStdString(iddata)].size(); for (int i = 0; i < n; i++) { double a = arc_start_angle * M_PI / 180.0; - double lx1 = (*blockdata[iddata][i].p[0])[0] * ellipse_start_angle; - double ly1 = (*blockdata[iddata][i].p[0])[1] * ellipse_stop_angle; - double lx2 = (*blockdata[iddata][i].p[1])[0] * ellipse_start_angle; - double ly2 = (*blockdata[iddata][i].p[1])[1] * ellipse_stop_angle; + double lx1 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[0]][0] * ellipse_start_angle; + double ly1 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[0]][1] * ellipse_stop_angle; + double lx2 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[1]][0] * ellipse_start_angle; + double ly2 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[1]][1] * ellipse_stop_angle; double px1 = (cos(a)*lx1 - sin(a)*ly1) * scale + xverts[0]; double py1 = (sin(a)*lx1 + cos(a)*ly1) * scale + yverts[0]; double px2 = (cos(a)*lx2 - sin(a)*ly2) * scale + xverts[0]; @@ -249,32 +253,32 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye } } else if (mode == "DIMENSION" && - (layername.isEmpty() || layername == layer)) { - this->dims.append(Dim()); - this->dims.last().type = dimtype; + (layername.empty() || layername == layer)) { + this->dims.push_back(Dim()); + this->dims.back().type = dimtype; for (int i = 0; i < 7; i++) for (int j = 0; j < 2; j++) - this->dims.last().coords[i][j] = coords[i][j]; - this->dims.last().angle = arc_start_angle; - this->dims.last().length = radius; - this->dims.last().name = name; + this->dims.back().coords[i][j] = coords[i][j]; + this->dims.back().angle = arc_start_angle; + this->dims.back().length = radius; + this->dims.back().name = name; } else if (mode == "BLOCK") { current_block = iddata; } else if (mode == "ENDBLK") { - current_block = QString(); + current_block.erase(); } else if (mode == "ENDSEC") { } else if (in_blocks_section || (in_entities_section && - (layername.isEmpty() || layername == layer))) { - unsupported_entities_list[mode]++; + (layername.empty() || layername == layer))) { + unsupported_entities_list[QString::fromStdString(mode)]++; } - mode = data; - layer = QString(); - name = QString(); - iddata = QString(); + mode = data.toStdString(); + layer.erase(); + name.erase(); + iddata.erase(); dimtype = 0; for (int i = 0; i < 7; i++) for (int j = 0; j < 2; j++) @@ -288,37 +292,37 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye } break; case 1: - name = data; + name = data.toStdString(); break; case 2: - iddata = data; + iddata = data.toStdString(); break; case 8: - layer = data; + layer = data.toStdString(); break; case 10: if (in_blocks_section) - xverts.append((data.toDouble())); + xverts.push_back((data.toDouble())); else - xverts.append((data.toDouble() - xorigin) * scale); + xverts.push_back((data.toDouble() - xorigin) * scale); break; case 11: if (in_blocks_section) - xverts.append((data.toDouble())); + xverts.push_back((data.toDouble())); else - xverts.append((data.toDouble() - xorigin) * scale); + xverts.push_back((data.toDouble() - xorigin) * scale); break; case 20: if (in_blocks_section) - yverts.append((data.toDouble())); + yverts.push_back((data.toDouble())); else - yverts.append((data.toDouble() - yorigin) * scale); + yverts.push_back((data.toDouble() - yorigin) * scale); break; case 21: if (in_blocks_section) - yverts.append((data.toDouble())); + yverts.push_back((data.toDouble())); else - yverts.append((data.toDouble() - yorigin) * scale); + yverts.push_back((data.toDouble() - yorigin) * scale); break; case 40: // CIRCLE, ARC: radius @@ -357,37 +361,39 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye QHashIterator i(unsupported_entities_list); while (i.hasNext()) { i.next(); - if (layername.isEmpty()) { + if (layername.empty()) { PRINTA("WARNING: Unsupported DXF Entity `%1' (%2x) in `%3'.", - i.key(), QString::number(i.value()), filename); + i.key(), QString::number(i.value()), QString::fromStdString(filename)); } else { PRINTA("WARNING: Unsupported DXF Entity `%1' (%2x) in layer `%3' of `%4'.", - i.key(), QString::number(i.value()), layername, filename); + i.key(), QString::number(i.value()), QString::fromStdString(layername), QString::fromStdString(filename)); } } // Extract paths from parsed data - QHash enabled_lines; - for (int i = 0; i < lines.count(); i++) { + typedef boost::unordered_map LineMap; + LineMap enabled_lines; + for (size_t i = 0; i < lines.size(); i++) { enabled_lines[i] = i; } // extract all open paths - while (enabled_lines.count() > 0) + while (enabled_lines.size() > 0) { int current_line, current_point; - foreach (int i, enabled_lines) { + BOOST_FOREACH(const LineMap::value_type &l, enabled_lines) { + int idx = l.second; for (int j = 0; j < 2; j++) { - QVector *lv = &grid.data((*lines[i].p[j])[0], (*lines[i].p[j])[1]); - for (int ki = 0; ki < lv->count(); ki++) { + std::vector *lv = &grid.data(this->points[lines[idx].idx[j]][0], this->points[lines[idx].idx[j]][1]); + for (int ki = 0; ki < lv->size(); ki++) { int k = lv->at(ki); - if (k == i || lines[k].disabled) + if (k == idx || lines[k].disabled) continue; goto next_open_path_j; } - current_line = i; + current_line = idx; current_point = j; goto create_open_path; next_open_path_j:; @@ -397,26 +403,26 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye break; create_open_path: - this->paths.append(Path()); - Path *this_path = &this->paths.last(); + this->paths.push_back(Path()); + Path *this_path = &this->paths.back(); - this_path->points.append(lines[current_line].p[current_point]); + this_path->indices.push_back(lines[current_line].idx[current_point]); while (1) { - this_path->points.append(lines[current_line].p[!current_point]); - const Vector2d &ref_point = *lines[current_line].p[!current_point]; + this_path->indices.push_back(lines[current_line].idx[!current_point]); + const Vector2d &ref_point = this->points[lines[current_line].idx[!current_point]]; lines[current_line].disabled = true; - enabled_lines.remove(current_line); - QVector *lv = &grid.data(ref_point[0], ref_point[1]); - for (int ki = 0; ki < lv->count(); ki++) { + enabled_lines.erase(current_line); + std::vector *lv = &grid.data(ref_point[0], ref_point[1]); + for (int ki = 0; ki < lv->size(); ki++) { int k = lv->at(ki); if (lines[k].disabled) continue; - if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[0])[0], (*lines[k].p[0])[1])) { + if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[0]][0], this->points[lines[k].idx[0]][1])) { current_line = k; current_point = 0; goto found_next_line_in_open_path; } - if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[1])[0], (*lines[k].p[1])[1])) { + if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[1]][0], this->points[lines[k].idx[1]][1])) { current_line = k; current_point = 1; goto found_next_line_in_open_path; @@ -428,31 +434,31 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye } // extract all closed paths - while (enabled_lines.count() > 0) + while (enabled_lines.size() > 0) { - int current_line = enabled_lines.begin().value(), current_point = 0; + int current_line = enabled_lines.begin()->second, current_point = 0; - this->paths.append(Path()); - Path *this_path = &this->paths.last(); + this->paths.push_back(Path()); + Path *this_path = &this->paths.back(); this_path->is_closed = true; - this_path->points.append(lines[current_line].p[current_point]); + this_path->indices.push_back(lines[current_line].idx[current_point]); while (1) { - this_path->points.append(lines[current_line].p[!current_point]); - const Vector2d &ref_point = *lines[current_line].p[!current_point]; + this_path->indices.push_back(lines[current_line].idx[!current_point]); + const Vector2d &ref_point = this->points[lines[current_line].idx[!current_point]]; lines[current_line].disabled = true; - enabled_lines.remove(current_line); - QVector *lv = &grid.data(ref_point[0], ref_point[1]); - for (int ki = 0; ki < lv->count(); ki++) { + enabled_lines.erase(current_line); + std::vector *lv = &grid.data(ref_point[0], ref_point[1]); + for (int ki = 0; ki < lv->size(); ki++) { int k = lv->at(ki); if (lines[k].disabled) continue; - if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[0])[0], (*lines[k].p[0])[1])) { + if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[0]][0], this->points[lines[k].idx[0]][1])) { current_line = k; current_point = 0; goto found_next_line_in_closed_path; } - if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[1])[0], (*lines[k].p[1])[1])) { + if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[1]][0], this->points[lines[k].idx[1]][1])) { current_line = k; current_point = 1; goto found_next_line_in_closed_path; @@ -467,9 +473,9 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye #if 0 printf("----- DXF Data -----\n"); - for (int i = 0; i < this->paths.count(); i++) { + for (int i = 0; i < this->paths.size(); i++) { printf("Path %d (%s):\n", i, this->paths[i].is_closed ? "closed" : "open"); - for (int j = 0; j < this->paths[i].points.count(); j++) + for (int j = 0; j < this->paths[i].points.size(); j++) printf(" %f %f\n", (*this->paths[i].points[j])[0], (*this->paths[i].points[j])[1]); } printf("--------------------\n"); @@ -483,26 +489,26 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye */ void DxfData::fixup_path_direction() { - for (int i = 0; i < this->paths.count(); i++) { + for (size_t i = 0; i < this->paths.size(); i++) { if (!this->paths[i].is_closed) break; this->paths[i].is_inner = true; - double min_x = (*this->paths[i].points[0])[0]; + double min_x = this->points[this->paths[i].indices[0]][0]; int min_x_point = 0; - for (int j = 1; j < this->paths[i].points.count(); j++) { - if ((*this->paths[i].points[j])[0] < min_x) { - min_x = (*this->paths[i].points[j])[0]; + for (size_t j = 1; j < this->paths[i].indices.size(); j++) { + if (this->points[this->paths[i].indices[j]][0] < min_x) { + min_x = this->points[this->paths[i].indices[j]][0]; min_x_point = j; } } // rotate points if the path is in non-standard rotation int b = min_x_point; - int a = b == 0 ? this->paths[i].points.count() - 2 : b - 1; - int c = b == this->paths[i].points.count() - 1 ? 1 : b + 1; - double ax = (*this->paths[i].points[a])[0] - (*this->paths[i].points[b])[0]; - double ay = (*this->paths[i].points[a])[1] - (*this->paths[i].points[b])[1]; - double cx = (*this->paths[i].points[c])[0] - (*this->paths[i].points[b])[0]; - double cy = (*this->paths[i].points[c])[1] - (*this->paths[i].points[b])[1]; + int a = b == 0 ? this->paths[i].indices.size() - 2 : b - 1; + int c = b == this->paths[i].indices.size() - 1 ? 1 : b + 1; + double ax = this->points[this->paths[i].indices[a]][0] - this->points[this->paths[i].indices[b]][0]; + double ay = this->points[this->paths[i].indices[a]][1] - this->points[this->paths[i].indices[b]][1]; + double cx = this->points[this->paths[i].indices[c]][0] - this->points[this->paths[i].indices[b]][0]; + double cy = this->points[this->paths[i].indices[c]][1] - this->points[this->paths[i].indices[b]][1]; #if 0 printf("Rotate check:\n"); printf(" a/b/c indices = %d %d %d\n", a, b, c); @@ -511,15 +517,17 @@ void DxfData::fixup_path_direction() #endif // FIXME: atan2() usually takes y,x. This variant probably makes the path clockwise.. if (atan2(ax, ay) < atan2(cx, cy)) { - for (int j = 0; j < this->paths[i].points.count()/2; j++) - this->paths[i].points.swap(j, this->paths[i].points.count()-1-j); + std::reverse(this->paths[i].indices.begin(), this->paths[i].indices.end()); } } } -Vector2d *DxfData::addPoint(double x, double y) +/*! + Adds a vertex and returns the index into DxfData::points + */ +int DxfData::addPoint(double x, double y) { - this->points.append(Vector2d(x, y)); - return &this->points.last(); + this->points.push_back(Vector2d(x, y)); + return this->points.size()-1; } diff --git a/src/dxfdata.h b/src/dxfdata.h index a513edf..c467160 100644 --- a/src/dxfdata.h +++ b/src/dxfdata.h @@ -1,7 +1,7 @@ #ifndef DXFDATA_H_ #define DXFDATA_H_ -#include +#include #include #include @@ -11,7 +11,7 @@ class DxfData { public: struct Path { - QList points; + std::vector indices; // indices into DxfData::points bool is_closed, is_inner; Path() : is_closed(false), is_inner(false) { } }; @@ -20,7 +20,7 @@ public: double coords[7][2]; double angle; double length; - QString name; + std::string name; Dim() { for (int i = 0; i < 7; i++) for (int j = 0; j < 2; j++) @@ -31,14 +31,16 @@ public: } }; - QList points; - QList paths; - QList dims; + std::vector points; + std::vector paths; + std::vector dims; DxfData(); - DxfData(double fn, double fs, double fa, QString filename, QString layername = QString(), double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); + DxfData(double fn, double fs, double fa, + const std::string &filename, const std::string &layername = "", + double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); - Vector2d *addPoint(double x, double y); + int addPoint(double x, double y); void fixup_path_direction(); }; diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 636ea6c..7b016f1 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -72,11 +72,11 @@ Value builtin_dxf_dim(const Context *ctx, const std::vector &argnam if (dxf_dim_cache.find(key) != dxf_dim_cache.end()) return dxf_dim_cache.find(key)->second; - DxfData dxf(36, 0, 0, QString::fromStdString(filename), QString::fromStdString(layername), xorigin, yorigin, scale); + DxfData dxf(36, 0, 0, filename, layername, xorigin, yorigin, scale); - for (int i = 0; i < dxf.dims.count(); i++) + for (size_t i = 0; i < dxf.dims.size(); i++) { - if (!name.empty() && dxf.dims[i].name != QString::fromStdString(name)) + if (!name.empty() && dxf.dims[i].name != name) continue; DxfData::Dim *d = &dxf.dims[i]; @@ -155,17 +155,17 @@ Value builtin_dxf_cross(const Context *ctx, const std::vector &argn if (dxf_cross_cache.find(key) != dxf_cross_cache.end()) return dxf_cross_cache.find(key)->second; - DxfData dxf(36, 0, 0, QString::fromStdString(filename), QString::fromStdString(layername), xorigin, yorigin, scale); + DxfData dxf(36, 0, 0, filename, layername, xorigin, yorigin, scale); double coords[4][2]; - for (int i = 0, j = 0; i < dxf.paths.count(); i++) { - if (dxf.paths[i].points.count() != 2) + for (size_t i = 0, j = 0; i < dxf.paths.size(); i++) { + if (dxf.paths[i].indices.size() != 2) continue; - coords[j][0] = (*dxf.paths[i].points[0])[0]; - coords[j++][1] = (*dxf.paths[i].points[0])[1]; - coords[j][0] = (*dxf.paths[i].points[1])[0]; - coords[j++][1] = (*dxf.paths[i].points[1])[1]; + coords[j][0] = dxf.points[dxf.paths[i].indices[0]][0]; + coords[j++][1] = dxf.points[dxf.paths[i].indices[0]][1]; + coords[j][0] = dxf.points[dxf.paths[i].indices[1]][0]; + coords[j++][1] = dxf.points[dxf.paths[i].indices[1]][1]; if (j == 4) { double x1 = coords[0][0], y1 = coords[0][1]; diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc index 825132f..6585e76 100644 --- a/src/dxftess-cgal.cc +++ b/src/dxftess-cgal.cc @@ -106,17 +106,17 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool /* do_tr try { // read path data and copy all relevant infos - for (int i = 0; i < dxf.paths.count(); i++) + for (int i = 0; i < dxf.paths.size(); i++) { if (!dxf.paths[i].is_closed) continue; Vertex_handle first, prev; struct point_info_t *first_pi = NULL, *prev_pi = NULL; - for (int j = 1; j < dxf.paths[i].points.count(); j++) + for (int j = 1; j < dxf.paths[i].indices.size(); j++) { - double x = (*dxf.paths[i].points[j])[0]; - double y = (*dxf.paths[i].points[j])[1]; + double x = dxf.points[dxf.paths[i].indices[j]][0]; + double y = dxf.points[dxf.paths[i].indices[j]][1]; if (point_info.has(x, y)) { // FIXME: How can the same path set contain the same point twice? @@ -127,7 +127,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool /* do_tr } struct point_info_t *pi = &point_info.align(x, y); - *pi = point_info_t(x, y, i, j, dxf.paths[i].points.count()-1); + *pi = point_info_t(x, y, i, j, dxf.paths[i].indices.size()-1); Vertex_handle vh = cdt.insert(CDTPoint(x, y)); if (first_pi == NULL) { diff --git a/src/dxftess-glu.cc b/src/dxftess-glu.cc index 3132fe9..23d8a45 100644 --- a/src/dxftess-glu.cc +++ b/src/dxftess-glu.cc @@ -227,17 +227,17 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian Grid3d< QPair > point_to_path(GRID_COARSE); - for (int i = 0; i < dxf.paths.count(); i++) { + for (int i = 0; i < dxf.paths.size(); i++) { if (!dxf.paths[i].is_closed) continue; gluTessBeginContour(tobj); - for (int j = 1; j < dxf.paths[i].points.count(); j++) { - point_to_path.data((*dxf.paths[i].points[j])[0], - (*dxf.paths[i].points[j])[1], + for (int j = 1; j < dxf.paths[i].indices.size(); j++) { + point_to_path.data(dxf.points[dxf.paths[i].indices[j]][0], + dxf.points[dxf.paths[i].indices[j]][1], h) = QPair(i, j); vl.append(tess_vdata()); - vl.last().v[0] = (*dxf.paths[i].points[j])[0]; - vl.last().v[1] = (*dxf.paths[i].points[j])[1]; + vl.last().v[0] = dxf.points[dxf.paths[i].indices[j]][0]; + vl.last().v[1] = dxf.points[dxf.paths[i].indices[j]][1]; vl.last().v[2] = h; gluTessVertex(tobj, vl.last().v, vl.last().v); } @@ -248,7 +248,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian gluDeleteTess(tobj); #if 0 - for (int i = 0; i < tess_tri.count(); i++) { + for (int i = 0; i < tess_tri.size(); i++) { printf("~~~\n"); printf(" %f %f %f\n", tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]); printf(" %f %f %f\n", tess_tri[i].p[1][0], tess_tri[i].p[1][1], tess_tri[i].p[1][2]); @@ -258,7 +258,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian // GLU tessing sometimes generates degenerated triangles. We must find and remove // them so we can use the triangle array with CGAL.. - for (int i = 0; i < tess_tri.count(); i++) { + for (int i = 0; i < tess_tri.size(); i++) { if (point_on_line(tess_tri[i].p[0], tess_tri[i].p[1], tess_tri[i].p[2]) || point_on_line(tess_tri[i].p[1], tess_tri[i].p[2], tess_tri[i].p[0]) || point_on_line(tess_tri[i].p[2], tess_tri[i].p[0], tess_tri[i].p[1])) { @@ -279,7 +279,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian bool added_triangles = true; typedef QPair QPair_ii; QHash tri_by_atan2; - for (int i = 0; i < tess_tri.count(); i++) + for (int i = 0; i < tess_tri.size(); i++) for (int j = 0; j < 3; j++) { int ai = (int)round(atan2(fabs(tess_tri[i].p[(j+1)%3][0] - tess_tri[i].p[j][0]), fabs(tess_tri[i].p[(j+1)%3][1] - tess_tri[i].p[j][1])) / 0.001); @@ -289,9 +289,9 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian { added_triangles = false; #ifdef DEBUG_TRIANGLE_SPLITTING - printf("*** Triangle splitting (%d) ***\n", tess_tri.count()+1); + printf("*** Triangle splitting (%d) ***\n", tess_tri.size()+1); #endif - for (int i = 0; i < tess_tri.count(); i++) + for (int i = 0; i < tess_tri.size(); i++) for (int k = 0; k < 3; k++) { QHash possible_neigh; @@ -303,7 +303,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian possible_neigh[jl] = jl; } #ifdef DEBUG_TRIANGLE_SPLITTING - printf("%d/%d: %d\n", i, k, possible_neigh.count()); + printf("%d/%d: %d\n", i, k, possible_neigh.size()); #endif foreach (const QPair_ii &jl, possible_neigh) { int j = jl.first; @@ -321,7 +321,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian for (int m = 0; m < 2; m++) { int ai = (int)round(atan2(fabs(tess_tri.last().p[(m+1)%3][0] - tess_tri.last().p[m][0]), fabs(tess_tri.last().p[(m+1)%3][1] - tess_tri.last().p[m][1])) / 0.001 ); - tri_by_atan2.insertMulti(ai, QPair(tess_tri.count()-1, m)); + tri_by_atan2.insertMulti(ai, QPair(tess_tri.size()-1, m)); } tess_tri[i].p[(k+1)%3] = tess_tri[j].p[l]; for (int m = 0; m < 2; m++) { @@ -337,7 +337,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_trian } #endif - for (int i = 0; i < tess_tri.count(); i++) + for (int i = 0; i < tess_tri.size(); i++) { #if 0 printf("---\n"); diff --git a/src/dxftess.cc b/src/dxftess.cc index 73d235f..d2cb172 100644 --- a/src/dxftess.cc +++ b/src/dxftess.cc @@ -37,17 +37,17 @@ without tesselating. Vertex ordering of the resulting polygons will follow the paths' is_inner flag. */ -void dxf_border_to_ps(PolySet *ps, DxfData *dxf) +void dxf_border_to_ps(PolySet *ps, const DxfData &dxf) { - for (int i = 0; i < dxf->paths.count(); i++) { - const DxfData::Path &pt = dxf->paths[i]; - if (!pt.is_closed) + for (size_t i = 0; i < dxf.paths.size(); i++) { + const DxfData::Path &path = dxf.paths[i]; + if (!path.is_closed) continue; ps->borders.push_back(PolySet::Polygon()); - for (int j = 1; j < pt.points.count(); j++) { - double x = (*pt.points[j])[0], y = (*pt.points[j])[1], z = 0.0; + for (size_t j = 1; j < path.indices.size(); j++) { + double x = dxf.points[path.indices[j]][0], y = dxf.points[path.indices[j]][1], z = 0.0; ps->grid.align(x, y, z); - if (pt.is_inner) { + if (path.is_inner) { ps->borders.back().push_back(Vector3d(x, y, z)); } else { ps->borders.back().insert(ps->borders.back().begin(), Vector3d(x, y, z)); diff --git a/src/dxftess.h b/src/dxftess.h index 4aa47c2..d3af36e 100644 --- a/src/dxftess.h +++ b/src/dxftess.h @@ -4,6 +4,6 @@ class DxfData; class PolySet; void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool do_triangle_splitting, double h); -void dxf_border_to_ps(PolySet *ps, DxfData *dxf); +void dxf_border_to_ps(PolySet *ps, const DxfData &dxf); #endif diff --git a/src/export.cc b/src/export.cc index 17a14c8..0c60ea3 100644 --- a/src/export.cc +++ b/src/export.cc @@ -134,11 +134,11 @@ void export_dxf(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialo << "ENTITIES\n"; DxfData *dd =root_N->convertToDxfData(); - for (int i=0; ipaths.size(); i++) + for (size_t i=0; ipaths.size(); i++) { - for (int j=1; jpaths[i].points.size(); j++) { - const Vector2d &p1 = *dd->paths[i].points[j-1]; - const Vector2d &p2 = *dd->paths[i].points[j]; + for (size_t j=1; jpaths[i].indices.size(); j++) { + const Vector2d &p1 = dd->points[dd->paths[i].indices[j-1]]; + const Vector2d &p2 = dd->points[dd->paths[i].indices[j]]; double x1 = p1[0]; double y1 = p1[1]; double x2 = p2[0]; diff --git a/src/import.cc b/src/import.cc index 0f107f7..8354198 100644 --- a/src/import.cc +++ b/src/import.cc @@ -198,10 +198,10 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c if (this->type == TYPE_DXF) { - DxfData dd(this->fn, this->fs, this->fa, QString::fromStdString(this->filename), QString::fromStdString(this->layername), this->origin_x, this->origin_y, this->scale); + DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale); p->is2d = true; dxf_tesselate(p, dd, 0, true, false, 0); - dxf_border_to_ps(p, &dd); + dxf_border_to_ps(p, dd); } return p; diff --git a/src/primitives.cc b/src/primitives.cc index 1a04cad..50a197d 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -521,39 +521,37 @@ sphere_next_r2: p->unlink(); return NULL; } - dd.points.append(Vector2d(x, y)); + dd.points.push_back(Vector2d(x, y)); } if (this->paths.vec.size() == 0) { - dd.paths.append(DxfData::Path()); + dd.paths.push_back(DxfData::Path()); for (size_t i=0; ipoints.vec.size(); i++) { assert(i < dd.points.size()); // FIXME: Not needed, but this used to be an 'if' - Vector2d *p = &dd.points[i]; - dd.paths.last().points.append(p); + dd.paths.back().indices.push_back(i); } - if (dd.paths.last().points.size() > 0) { - dd.paths.last().points.append(dd.paths.last().points.first()); - dd.paths.last().is_closed = true; + if (dd.paths.back().indices.size() > 0) { + dd.paths.back().indices.push_back(dd.paths.back().indices.front()); + dd.paths.back().is_closed = true; } } else { for (size_t i=0; ipaths.vec.size(); i++) { - dd.paths.append(DxfData::Path()); + dd.paths.push_back(DxfData::Path()); for (size_t j=0; jpaths.vec[i]->vec.size(); j++) { int idx = this->paths.vec[i]->vec[j]->num; if (idx < dd.points.size()) { - Vector2d *p = &dd.points[idx]; - dd.paths.last().points.append(p); + dd.paths.back().indices.push_back(idx); } } - if (dd.paths.last().points.isEmpty()) { - dd.paths.removeLast(); + if (dd.paths.back().indices.empty()) { + dd.paths.pop_back(); } else { - dd.paths.last().points.append(dd.paths.last().points.first()); - dd.paths.last().is_closed = true; + dd.paths.back().indices.push_back(dd.paths.back().indices.front()); + dd.paths.back().is_closed = true; } } } @@ -561,7 +559,7 @@ sphere_next_r2: p->is2d = true; p->convexity = convexity; dxf_tesselate(p, dd, 0, true, false, 0); - dxf_border_to_ps(p, &dd); + dxf_border_to_ps(p, dd); } return p; -- cgit v0.10.1 From 83233b035f8f2a0984580640f9545718f245d81b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 22:57:58 +0200 Subject: Added note about 2D union bug diff --git a/doc/TODO.txt b/doc/TODO.txt index dd46b7b..5fe22bb 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -6,6 +6,7 @@ o Tesselation via GLU sometimes produces strange results o Export STL: Exports existing CGAL model even though the current model is changed, but not CGAL rendered o Look into the polygon winding and rotate_extrude() problem reported by Britton o CGAL Aff_transformation_3 doesn't support non-affine transformations (non-aff-matrix.scad) +o 2D union of polygons with a touching vertex doesn't work. see testdata/scad/bugs/polygon-touch.scad STL Import BUGS --------------- diff --git a/testdata/scad/bugs/polygon-touch.scad b/testdata/scad/bugs/polygon-touch.scad new file mode 100644 index 0000000..afa2938 --- /dev/null +++ b/testdata/scad/bugs/polygon-touch.scad @@ -0,0 +1,5 @@ +# Somehow the 2D union/tessellation algorithm doesn't support touching polygons +# Changing translate([-10,-10,0]) to translate([-9.99,-9.99,0]) works + +square([10,10]); +translate([-10,-10,0]) square([10,10]); -- cgit v0.10.1 From a5b03ddcf9026dbc60881572419f096ba9ecadab Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Sep 2011 23:12:38 +0200 Subject: Got rid of more Qt dependencies diff --git a/src/dxfdata.cc b/src/dxfdata.cc index 430a1c3..0caa0f1 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -24,6 +24,7 @@ * */ +#include "myqhash.h" #include "dxfdata.h" #include "grid.h" #include "printutils.h" @@ -31,8 +32,6 @@ #include #include -#include -#include #include "mathc99.h" #include #include @@ -67,7 +66,7 @@ DxfData::DxfData(double fn, double fs, double fa, Grid2d< std::vector > grid(GRID_COARSE); std::vector lines; // Global lines - QHash< QString, std::vector > blockdata; // Lines in blocks + boost::unordered_map< std::string, std::vector > blockdata; // Lines in blocks bool in_entities_section = false; bool in_blocks_section = false; @@ -78,17 +77,17 @@ DxfData::DxfData(double fn, double fs, double fa, if (!in_entities_section && !in_blocks_section) \ break; \ if (in_entities_section && \ - !(layername.empty() || layername == layer)) \ + !(layername.empty() || layername == layer)) \ break; \ grid.align(_p1x, _p1y); \ grid.align(_p2x, _p2y); \ - grid.data(_p1x, _p1y).push_back(lines.size()); \ - grid.data(_p2x, _p2y).push_back(lines.size()); \ + grid.data(_p1x, _p1y).push_back(lines.size()); \ + grid.data(_p2x, _p2y).push_back(lines.size()); \ if (in_entities_section) \ - lines.push_back( \ + lines.push_back( \ Line(addPoint(_p1x, _p1y), addPoint(_p2x, _p2y))); \ - if (in_blocks_section && !current_block.empty()) \ - blockdata[QString::fromStdString(current_block)].push_back( \ + if (in_blocks_section && !current_block.empty()) \ + blockdata[current_block].push_back( \ Line(addPoint(_p1x, _p1y), addPoint(_p2x, _p2y))); \ } while (0) @@ -105,8 +104,8 @@ DxfData::DxfData(double fn, double fs, double fa, for (int j = 0; j < 2; j++) coords[i][j] = 0; - QHash unsupported_entities_list; - + typedef boost::unordered_map EntityList; + EntityList unsupported_entities_list; // // Parse DXF file. Will populate this->points, this->dims, lines and blockdata @@ -238,13 +237,13 @@ DxfData::DxfData(double fn, double fs, double fa, else if (mode == "INSERT") { // scale is stored in ellipse_start|stop_angle, rotation in arc_start_angle; // due to the parser code not checking entity type - int n = blockdata[QString::fromStdString(iddata)].size(); + int n = blockdata[iddata].size(); for (int i = 0; i < n; i++) { double a = arc_start_angle * M_PI / 180.0; - double lx1 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[0]][0] * ellipse_start_angle; - double ly1 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[0]][1] * ellipse_stop_angle; - double lx2 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[1]][0] * ellipse_start_angle; - double ly2 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[1]][1] * ellipse_stop_angle; + double lx1 = this->points[blockdata[iddata][i].idx[0]][0] * ellipse_start_angle; + double ly1 = this->points[blockdata[iddata][i].idx[0]][1] * ellipse_stop_angle; + double lx2 = this->points[blockdata[iddata][i].idx[1]][0] * ellipse_start_angle; + double ly2 = this->points[blockdata[iddata][i].idx[1]][1] * ellipse_stop_angle; double px1 = (cos(a)*lx1 - sin(a)*ly1) * scale + xverts[0]; double py1 = (sin(a)*lx1 + cos(a)*ly1) * scale + yverts[0]; double px2 = (cos(a)*lx2 - sin(a)*ly2) * scale + xverts[0]; @@ -273,7 +272,7 @@ DxfData::DxfData(double fn, double fs, double fa, } else if (in_blocks_section || (in_entities_section && (layername.empty() || layername == layer))) { - unsupported_entities_list[QString::fromStdString(mode)]++; + unsupported_entities_list[mode]++; } mode = data.toStdString(); layer.erase(); @@ -358,15 +357,13 @@ DxfData::DxfData(double fn, double fs, double fa, } } - QHashIterator i(unsupported_entities_list); - while (i.hasNext()) { - i.next(); + BOOST_FOREACH(const EntityList::value_type &i, unsupported_entities_list) { if (layername.empty()) { - PRINTA("WARNING: Unsupported DXF Entity `%1' (%2x) in `%3'.", - i.key(), QString::number(i.value()), QString::fromStdString(filename)); + PRINTF("WARNING: Unsupported DXF Entity `%s' (%x) in `%s'.", + i.first.c_str(), i.second, filename.c_str()); } else { - PRINTA("WARNING: Unsupported DXF Entity `%1' (%2x) in layer `%3' of `%4'.", - i.key(), QString::number(i.value()), QString::fromStdString(layername), QString::fromStdString(filename)); + PRINTF("WARNING: Unsupported DXF Entity `%s' (%x) in layer `%s' of `%s'.", + i.first.c_str(), i.second, layername.c_str(), filename.c_str()); } } diff --git a/src/dxfdata.h b/src/dxfdata.h index c467160..bada031 100644 --- a/src/dxfdata.h +++ b/src/dxfdata.h @@ -2,7 +2,6 @@ #define DXFDATA_H_ #include -#include #include using Eigen::Vector2d; -- cgit v0.10.1 From 821c7df1fe34006ebeb0150cc0a166563d583f25 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 00:03:16 +0200 Subject: Extracted handle_dep() to separate source file diff --git a/openscad.pro b/openscad.pro index bd2215e..8abadc9 100644 --- a/openscad.pro +++ b/openscad.pro @@ -147,6 +147,7 @@ HEADERS += src/renderer.h \ src/colornode.h \ src/rendernode.h \ src/openscad.h \ + src/handle_dep.h \ src/polyset.h \ src/printutils.h \ src/value.h \ @@ -166,6 +167,7 @@ HEADERS += src/renderer.h \ SOURCES += src/openscad.cc \ src/mainwin.cc \ + src/handle_dep.cc \ src/ThrownTogetherRenderer.cc \ src/glview.cc \ src/export.cc \ diff --git a/src/dxfdata.cc b/src/dxfdata.cc index 0caa0f1..3e224e3 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -28,7 +28,8 @@ #include "dxfdata.h" #include "grid.h" #include "printutils.h" -#include "openscad.h" // handle_dep() +#include "handle_dep.h" +#include "openscad.h" // get_fragments_from_r() #include #include @@ -55,7 +56,7 @@ DxfData::DxfData(double fn, double fs, double fa, const std::string &filename, const std::string &layername, double xorigin, double yorigin, double scale) { - handle_dep(QString::fromStdString(filename)); // Register ourselves as a dependency + handle_dep(filename); // Register ourselves as a dependency QFile f(QString::fromStdString(filename)); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { diff --git a/src/import.cc b/src/import.cc index 8354198..447c139 100644 --- a/src/import.cc +++ b/src/import.cc @@ -33,7 +33,7 @@ #include "dxfdata.h" #include "dxftess.h" #include "printutils.h" -#include "openscad.h" // handle_dep() +#include "handle_dep.h" // handle_dep() #include #include @@ -116,7 +116,7 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c if (this->type == TYPE_STL) { - handle_dep(QString::fromStdString(this->filename)); + handle_dep(this->filename); QFile f(QString::fromStdString(this->filename)); if (!f.open(QIODevice::ReadOnly)) { PRINTF("WARNING: Can't open import file `%s'.", this->filename.c_str()); diff --git a/src/lexer.l b/src/lexer.l index 5e62b19..4c0ddea 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -26,7 +26,8 @@ %{ -#include "openscad.h" +#include "handle_dep.h" +#include "openscad.h" // librarydir #include "printutils.h" #include "parser_yacc.h" #include @@ -102,7 +103,7 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { if (!finfo.exists()) { finfo = QFileInfo(QDir(librarydir), filename); } - handle_dep(finfo.absoluteFilePath()); + handle_dep(finfo.absoluteFilePath().toStdString()); parserlval.text = strdup(finfo.absoluteFilePath().toLocal8Bit()); return TOK_USE; } @@ -116,7 +117,7 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { } PRINTF("DEPRECATED: Support for implicit include will be removed in future releases. Use `include ' instead."); - handle_dep(finfo.absoluteFilePath()); + handle_dep(finfo.absoluteFilePath().toStdString()); yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r"); if (!yyin) { PRINTF("WARNING: Can't open input file `%s'.", filename); @@ -206,7 +207,7 @@ void includefile() finfo = QFileInfo(QDir(librarydir), filename); } - handle_dep(finfo.absoluteFilePath()); + handle_dep(finfo.absoluteFilePath().toStdString()); yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r"); if (!yyin) { PRINTA("WARNING: Can't open input file `%1'.", filename); diff --git a/src/mainwin.cc b/src/mainwin.cc index 4b5ba89..30738d2 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -667,7 +667,7 @@ void MainWindow::compile(bool procevents) // Parse this->last_compiled_doc = editor->toPlainText(); this->root_module = parse((this->last_compiled_doc + "\n" + - commandline_commands).toAscii().data(), + QString::fromStdString(commandline_commands)).toAscii().data(), this->fileName.isEmpty() ? "" : QFileInfo(this->fileName).absolutePath().toLocal8Bit(), diff --git a/src/openscad.cc b/src/openscad.cc index 5ec0659..a75d629 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -24,6 +24,7 @@ * */ +#include "myqhash.h" #include "openscad.h" #include "MainWindow.h" #include "node.h" @@ -34,6 +35,7 @@ #include "builtin.h" #include "nodedumper.h" #include "printutils.h" +#include "handle_dep.h" #include #include @@ -52,6 +54,7 @@ #include #include #include +#include #ifdef Q_WS_MAC #include "EventFilter.h" @@ -80,9 +83,7 @@ static void version() exit(1); } -QString commandline_commands; -const char *make_command = NULL; -QSet dependencies; +std::string commandline_commands; QString currentdir; QString examplesdir; QString librarydir; @@ -90,19 +91,6 @@ QString librarydir; using std::string; using std::vector; -void handle_dep(QString filename) -{ - if (filename.startsWith("/")) - dependencies.insert(filename); - else - dependencies.insert(QDir::currentPath() + QString("/") + filename); - if (!QFile(filename).exists() && make_command) { - char buffer[4096]; - snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); - system(buffer); // FIXME: Handle error - } -} - int main(int argc, char **argv) { int rc = 0; @@ -200,8 +188,8 @@ int main(int argc, char **argv) const vector &commands = vm["D"].as >(); for (vector::const_iterator i = commands.begin(); i != commands.end(); i++) { - commandline_commands.append(i->c_str()); - commandline_commands.append(";\n"); + commandline_commands += *i; + commandline_commands += ";\n"; } } @@ -300,15 +288,16 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open input file `%s'!\n", filename); exit(1); } else { - QString text; + std::stringstream text; char buffer[513]; int ret; while ((ret = fread(buffer, 1, 512, fp)) > 0) { buffer[ret] = 0; - text += buffer; + text << buffer; } fclose(fp); - root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + text << commandline_commands; + root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); } QDir::setCurrent(fileInfo.absolutePath()); @@ -322,17 +311,10 @@ int main(int argc, char **argv) QDir::setCurrent(original_path.absolutePath()); if (deps_output_file) { - fp = fopen(deps_output_file, "wt"); - if (!fp) { - fprintf(stderr, "Can't open dependencies file `%s' for writing!\n", deps_output_file); + if (!write_deps(deps_output_file, + stl_output_file ? stl_output_file : off_output_file)) { exit(1); } - fprintf(fp, "%s:", stl_output_file ? stl_output_file : off_output_file); - QSetIterator i(dependencies); - while (i.hasNext()) - fprintf(fp, " \\\n\t%s", i.next().toUtf8().data()); - fprintf(fp, "\n"); - fclose(fp); } if (stl_output_file) { diff --git a/src/openscad.h b/src/openscad.h index e022668..9d97bac 100644 --- a/src/openscad.h +++ b/src/openscad.h @@ -41,12 +41,11 @@ extern class AbstractModule *parse(const char *text, const char *path, int debug); extern int get_fragments_from_r(double r, double fn, double fs, double fa); -#include -extern QString commandline_commands; +#include +extern std::string commandline_commands; extern int parser_error_pos; -extern void handle_dep(QString filename); - +#include // The CWD when application started. We shouldn't change CWD, but until we stop // doing this, use currentdir to get the original CWD. extern QString currentdir; diff --git a/src/surface.cc b/src/surface.cc index b7dfa0f..22598bf 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -31,7 +31,7 @@ #include "builtin.h" #include "dxftess.h" #include "printutils.h" -#include "openscad.h" // handle_dep() +#include "handle_dep.h" // handle_dep() #include "visitor.h" #include @@ -101,7 +101,7 @@ void register_builtin_surface() PolySet *SurfaceNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const { PolySet *p = new PolySet(); - handle_dep(QString::fromStdString(filename)); + handle_dep(filename); QFile f(QString::fromStdString(filename)); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c274435..af64772 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -79,6 +79,8 @@ include_directories(../src) add_definitions(-DOPENSCAD_VERSION=test) set(COMMON_SOURCES + ../src/handle_dep.cc + ../src/qhash.cc ../src/export.cc ../src/value.cc ../src/expr.cc diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc index a93d564..89f1bc9 100644 --- a/tests/cgalpngtest.cc +++ b/tests/cgalpngtest.cc @@ -40,6 +40,7 @@ #include "CGAL_renderer.h" #include "cgal.h" #include "OffscreenView.h" +#include "handle_dep.h" #include #include @@ -49,29 +50,15 @@ #include #include #include +#include -QString commandline_commands; -const char *make_command = NULL; -QSet dependencies; +std::string commandline_commands; QString currentdir; QString examplesdir; QString librarydir; using std::string; -void handle_dep(QString filename) -{ - if (filename.startsWith("/")) - dependencies.insert(filename); - else - dependencies.insert(QDir::currentPath() + QString("/") + filename); - if (!QFile(filename).exists() && make_command) { - char buffer[4096]; - snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); - system(buffer); // FIXME: Handle error - } -} - // FIXME: enforce some maximum cache size (old version had 100K vertices as limit) QHash cache; @@ -153,15 +140,16 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open input file `%s'!\n", filename); exit(1); } else { - QString text; + std::stringstream text; char buffer[513]; int ret; while ((ret = fread(buffer, 1, 512, fp)) > 0) { buffer[ret] = 0; - text += buffer; + text << buffer; } fclose(fp); - root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + text << commandline_commands; + root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); if (!root_module) { exit(1); } diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc index 9d4ef5d..44e87f9 100644 --- a/tests/cgaltest.cc +++ b/tests/cgaltest.cc @@ -25,6 +25,7 @@ #include "myqhash.h" #include "openscad.h" +#include "handle_dep.h" #include "node.h" #include "module.h" #include "context.h" @@ -44,29 +45,15 @@ #include #include #include +#include -QString commandline_commands; -const char *make_command = NULL; -QSet dependencies; +std::string commandline_commands; QString currentdir; QString examplesdir; QString librarydir; using std::string; -void handle_dep(QString filename) -{ - if (filename.startsWith("/")) - dependencies.insert(filename); - else - dependencies.insert(QDir::currentPath() + QString("/") + filename); - if (!QFile(filename).exists() && make_command) { - char buffer[4096]; - snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); - system(buffer); // FIXME: Handle error - } -} - // FIXME: enforce some maximum cache size (old version had 100K vertices as limit) QHash cache; @@ -143,15 +130,16 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open input file `%s'!\n", filename); exit(1); } else { - QString text; + std::stringstream text; char buffer[513]; int ret; while ((ret = fread(buffer, 1, 512, fp)) > 0) { buffer[ret] = 0; - text += buffer; + text << buffer; } fclose(fp); - root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + text << commandline_commands; + root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); if (!root_module) { exit(1); } diff --git a/tests/csgtermtest.cc b/tests/csgtermtest.cc index 42d22a0..26b809a 100644 --- a/tests/csgtermtest.cc +++ b/tests/csgtermtest.cc @@ -23,9 +23,11 @@ * */ +#include "myqhash.h" #include "CSGTermEvaluator.h" #include "CSGTextCache.h" #include "openscad.h" +#include "handle_dep.h" #include "node.h" #include "module.h" #include "context.h" @@ -42,29 +44,15 @@ #include #include #include +#include using std::cout; -QString commandline_commands; -const char *make_command = NULL; -QSet dependencies; +std::string commandline_commands; QString currentdir; QString examplesdir; QString librarydir; -void handle_dep(QString filename) -{ - if (filename.startsWith("/")) - dependencies.insert(filename); - else - dependencies.insert(QDir::currentPath() + QString("/") + filename); - if (!QFile(filename).exists() && make_command) { - char buffer[4096]; - snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); - system(buffer); // FIXME: Handle error - } -} - int main(int argc, char **argv) { if (argc != 2) { @@ -131,15 +119,16 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open input file `%s'!\n", filename); exit(1); } else { - QString text; + std::stringstream text; char buffer[513]; int ret; while ((ret = fread(buffer, 1, 512, fp)) > 0) { buffer[ret] = 0; - text += buffer; + text << buffer; } fclose(fp); - root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + text << commandline_commands; + root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); if (!root_module) { exit(1); } diff --git a/tests/csgtexttest.cc b/tests/csgtexttest.cc index c259e2d..3c4451d 100644 --- a/tests/csgtexttest.cc +++ b/tests/csgtexttest.cc @@ -26,6 +26,7 @@ #include "CSGTextRenderer.h" #include "CSGTextCache.h" #include "openscad.h" +#include "handle_dep.h" #include "node.h" #include "module.h" #include "context.h" @@ -41,27 +42,13 @@ #include #include #include +#include -QString commandline_commands; -const char *make_command = NULL; -QSet dependencies; +std::string commandline_commands; QString currentdir; QString examplesdir; QString librarydir; -void handle_dep(QString filename) -{ - if (filename.startsWith("/")) - dependencies.insert(filename); - else - dependencies.insert(QDir::currentPath() + QString("/") + filename); - if (!QFile(filename).exists() && make_command) { - char buffer[4096]; - snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); - system(buffer); // FIXME: Handle error - } -} - void csgTree(CSGTextCache &cache, const AbstractNode &root) { CSGTextRenderer renderer(cache); @@ -135,15 +122,16 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open input file `%s'!\n", filename); exit(1); } else { - QString text; + std::stringstream text; char buffer[513]; int ret; while ((ret = fread(buffer, 1, 512, fp)) > 0) { buffer[ret] = 0; - text += buffer; + text << buffer; } fclose(fp); - root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + text << commandline_commands; + root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); if (!root_module) { exit(1); } diff --git a/tests/dumptest.cc b/tests/dumptest.cc index 3f6068a..9af7154 100644 --- a/tests/dumptest.cc +++ b/tests/dumptest.cc @@ -25,6 +25,7 @@ */ #include "openscad.h" +#include "handle_dep.h" #include "node.h" #include "module.h" #include "context.h" @@ -41,29 +42,15 @@ #include #include #include +#include using std::string; -QString commandline_commands; -const char *make_command = NULL; -QSet dependencies; +std::string commandline_commands; QString currentdir; QString examplesdir; QString librarydir; -void handle_dep(QString filename) -{ - if (filename.startsWith("/")) - dependencies.insert(filename); - else - dependencies.insert(QDir::currentPath() + QString("/") + filename); - if (!QFile(filename).exists() && make_command) { - char buffer[4096]; - snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); - system(buffer); // FIXME: Handle error - } -} - int main(int argc, char **argv) { if (argc != 2) { @@ -130,15 +117,16 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open input file `%s'!\n", filename); exit(1); } else { - QString text; + std::stringstream text; char buffer[513]; int ret; while ((ret = fread(buffer, 1, 512, fp)) > 0) { buffer[ret] = 0; - text += buffer; + text << buffer; } fclose(fp); - root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + text << commandline_commands; + root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); if (!root_module) { exit(1); } diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index cbf07e8..b946b4f 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -1,5 +1,6 @@ #include #include "openscad.h" +#include "handle_dep.h" #include "builtin.h" #include "context.h" #include "node.h" @@ -21,36 +22,16 @@ #include #include #include +#include using std::cerr; using std::cout; -QString commandline_commands; +std::string commandline_commands; QString librarydir; -QSet dependencies; -const char *make_command = NULL; //#define DEBUG -void handle_dep(QString filename) -{ - if (filename.startsWith("/")) - dependencies.insert(filename); - else - dependencies.insert(QDir::currentPath() + QString("/") + filename); - if (!QFile(filename).exists() && make_command) { - char buffer[4096]; - snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data()); - system(buffer); // FIXME: Handle error - } -} - -// static void renderfunc(void *vp) -// { -// glClearColor(1.0, 0.0, 0.0, 0.0); -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); -// } - struct CsgInfo { CSGTerm *root_norm_term; // Normalized CSG products @@ -127,15 +108,16 @@ int main(int argc, char *argv[]) fprintf(stderr, "Can't open input file `%s'!\n", filename); exit(1); } else { - QString text; + std::stringstream text; char buffer[513]; int ret; while ((ret = fread(buffer, 1, 512, fp)) > 0) { buffer[ret] = 0; - text += buffer; + text << buffer; } fclose(fp); - root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false); + text << commandline_commands; + root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); if (!root_module) { exit(1); } -- cgit v0.10.1 From 8789133f801d3447d2ebc070659a00a2a235a22b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 01:39:19 +0200 Subject: Added handle_dep sources diff --git a/src/handle_dep.cc b/src/handle_dep.cc new file mode 100644 index 0000000..2a05b4a --- /dev/null +++ b/src/handle_dep.cc @@ -0,0 +1,42 @@ +#include "handle_dep.h" +#include "myqhash.h" +#include +#include +#include +#include +#include +#include // for system() + +QSet dependencies; +const char *make_command = NULL; + +void handle_dep(const std::string &filename) +{ + if (filename[0] == '/') + dependencies.insert(filename); + else { + QString dep = QDir::currentPath() + QString("/") + QString::fromStdString(filename); + dependencies.insert(dep.toStdString()); + } + if (!QFile(QString::fromStdString(filename)).exists() && make_command) { + std::stringstream buf; + buf << make_command << " '" << QString::fromStdString(filename).replace("'", "'\\''").toUtf8().data() << "'"; + system(buf.str().c_str()); // FIXME: Handle error + } +} + +bool write_deps(const std::string &filename, const std::string &output_file) +{ + FILE *fp = fopen(filename.c_str(), "wt"); + if (!fp) { + fprintf(stderr, "Can't open dependencies file `%s' for writing!\n", filename.c_str()); + return false; + } + fprintf(fp, "%s:", output_file.c_str()); + QSetIterator i(dependencies); + while (i.hasNext()) + fprintf(fp, " \\\n\t%s", i.next().c_str()); + fprintf(fp, "\n"); + fclose(fp); + return true; +} diff --git a/src/handle_dep.h b/src/handle_dep.h new file mode 100644 index 0000000..1074a64 --- /dev/null +++ b/src/handle_dep.h @@ -0,0 +1,10 @@ +#ifndef HANDLE_DEP_H_ +#define HANDLE_DEP_H_ + +#include + +extern const char *make_command; +void handle_dep(const std::string &filename); +bool write_deps(const std::string &filename, const std::string &output_file); + +#endif -- cgit v0.10.1 From 781dab0493b62c368b948b0d7ce1be714c36f3a2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 01:57:26 +0200 Subject: Filename case fix diff --git a/openscad.pro b/openscad.pro index 8abadc9..d3923e5 100644 --- a/openscad.pro +++ b/openscad.pro @@ -214,12 +214,12 @@ HEADERS += src/cgal.h \ src/cgalfwd.h \ src/CGALEvaluator.h \ src/PolySetCGALEvaluator.h \ - src/cgalrenderer.h \ + src/CGALRenderer.h \ src/CGAL_Nef_polyhedron.h SOURCES += src/CGALEvaluator.cc \ src/PolySetCGALEvaluator.cc \ - src/cgalrenderer.cc \ + src/CGALRenderer.cc \ src/CGAL_Nef_polyhedron.cc \ src/CGAL_Nef_polyhedron_DxfData.cc \ src/cgaladv_convexhull2.cc \ diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc new file mode 100644 index 0000000..da5d859 --- /dev/null +++ b/src/CGALRenderer.cc @@ -0,0 +1,134 @@ +/* + * OpenSCAD (www.openscad.org) + * Copyright (C) 2009-2011 Clifford Wolf and + * Marius Kintel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * As a special exception, you have permission to link this program + * with the CGAL library and distribute executables, as long as you + * follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from CGAL. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "cgalrenderer.h" +#include "polyset.h" +#include "CGAL_renderer.h" +#include "dxfdata.h" +#include "dxftess.h" +#include "CGAL_Nef_polyhedron.h" +#include "cgal.h" + +//#include "Preferences.h" + +CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) +{ + if (root.dim == 2) { + DxfData *dd = root.convertToDxfData(); + this->polyhedron = NULL; + this->polyset = new PolySet(); + this->polyset->is2d = true; + dxf_tesselate(this->polyset, *dd, 0, true, false, 0); + delete dd; + } + else if (root.dim == 3) { + this->polyset = NULL; + this->polyhedron = new Polyhedron(); + // FIXME: Make independent of Preferences + // this->polyhedron->setColor(Polyhedron::CGAL_NEF3_MARKED_FACET_COLOR, + // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).red(), + // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).green(), + // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).blue()); + // this->polyhedron->setColor(Polyhedron::CGAL_NEF3_UNMARKED_FACET_COLOR, + // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).red(), + // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(), + // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue()); + + CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(*this->root.p3, this->polyhedron); + this->polyhedron->init(); + } +} + +CGALRenderer::~CGALRenderer() +{ + if (this->polyset) this->polyset->unlink(); + delete this->polyhedron; +} + +void CGALRenderer::draw(bool showfaces, bool showedges) const +{ + if (this->root.dim == 2) { + // Draw 2D polygons + glDisable(GL_LIGHTING); +// FIXME: const QColor &col = Preferences::inst()->color(Preferences::CGAL_FACE_2D_COLOR); + const QColor &col = QColor(0x00, 0xbf, 0x99); + glColor3f(col.redF(), col.greenF(), col.blueF()); + + for (int i=0; i < this->polyset->polygons.size(); i++) { + glBegin(GL_POLYGON); + for (int j=0; j < this->polyset->polygons[i].size(); j++) { + const Vector3d &p = this->polyset->polygons[i][j]; + glVertex3d(p[0], p[1], -0.1); + } + glEnd(); + } + + typedef CGAL_Nef_polyhedron2::Explorer Explorer; + typedef Explorer::Face_const_iterator fci_t; + typedef Explorer::Halfedge_around_face_const_circulator heafcc_t; + typedef Explorer::Point Point; + Explorer E = this->root.p2->explorer(); + + // Draw 2D edges + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glLineWidth(2); +// FIXME: const QColor &col2 = Preferences::inst()->color(Preferences::CGAL_EDGE_2D_COLOR); + const QColor &col2 = QColor(0xff, 0x00, 0x00); + glColor3f(col2.redF(), col2.greenF(), col2.blueF()); + + // Extract the boundary, including inner boundaries of the polygons + for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit) { + bool fset = false; + double fx = 0.0, fy = 0.0; + heafcc_t fcirc(E.halfedge(fit)), fend(fcirc); + CGAL_For_all(fcirc, fend) { + if(E.is_standard(E.target(fcirc))) { + Point p = E.point(E.target(fcirc)); + double x = to_double(p.x()), y = to_double(p.y()); + if (!fset) { + glBegin(GL_LINE_STRIP); + fx = x, fy = y; + fset = true; + } + glVertex3d(x, y, -0.1); + } + } + if (fset) { + glVertex3d(fx, fy, -0.1); + glEnd(); + } + } + + glEnable(GL_DEPTH_TEST); + } + else if (this->root.dim == 3) { + if (showfaces) this->polyhedron->set_style(SNC_BOUNDARY); + else this->polyhedron->set_style(SNC_SKELETON); + + this->polyhedron->draw(showfaces && showedges); + } +} diff --git a/src/CGALRenderer.h b/src/CGALRenderer.h new file mode 100644 index 0000000..5f854ea --- /dev/null +++ b/src/CGALRenderer.h @@ -0,0 +1,20 @@ +#ifndef CGALRENDERER_H_ +#define CGALRENDERER_H_ + +#include "renderer.h" +#include "CGAL_Nef_polyhedron.h" + +class CGALRenderer : public Renderer +{ +public: + CGALRenderer(const CGAL_Nef_polyhedron &root); + ~CGALRenderer(); + void draw(bool showfaces, bool showedges) const; + +public: + const CGAL_Nef_polyhedron &root; + class Polyhedron *polyhedron; + class PolySet *polyset; +}; + +#endif diff --git a/src/cgalrenderer.cc b/src/cgalrenderer.cc deleted file mode 100644 index da5d859..0000000 --- a/src/cgalrenderer.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * OpenSCAD (www.openscad.org) - * Copyright (C) 2009-2011 Clifford Wolf and - * Marius Kintel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * As a special exception, you have permission to link this program - * with the CGAL library and distribute executables, as long as you - * follow the requirements of the GNU GPL in regard to all of the - * software in the executable aside from CGAL. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "cgalrenderer.h" -#include "polyset.h" -#include "CGAL_renderer.h" -#include "dxfdata.h" -#include "dxftess.h" -#include "CGAL_Nef_polyhedron.h" -#include "cgal.h" - -//#include "Preferences.h" - -CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) -{ - if (root.dim == 2) { - DxfData *dd = root.convertToDxfData(); - this->polyhedron = NULL; - this->polyset = new PolySet(); - this->polyset->is2d = true; - dxf_tesselate(this->polyset, *dd, 0, true, false, 0); - delete dd; - } - else if (root.dim == 3) { - this->polyset = NULL; - this->polyhedron = new Polyhedron(); - // FIXME: Make independent of Preferences - // this->polyhedron->setColor(Polyhedron::CGAL_NEF3_MARKED_FACET_COLOR, - // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).red(), - // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).green(), - // Preferences::inst()->color(Preferences::CGAL_FACE_BACK_COLOR).blue()); - // this->polyhedron->setColor(Polyhedron::CGAL_NEF3_UNMARKED_FACET_COLOR, - // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).red(), - // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).green(), - // Preferences::inst()->color(Preferences::CGAL_FACE_FRONT_COLOR).blue()); - - CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(*this->root.p3, this->polyhedron); - this->polyhedron->init(); - } -} - -CGALRenderer::~CGALRenderer() -{ - if (this->polyset) this->polyset->unlink(); - delete this->polyhedron; -} - -void CGALRenderer::draw(bool showfaces, bool showedges) const -{ - if (this->root.dim == 2) { - // Draw 2D polygons - glDisable(GL_LIGHTING); -// FIXME: const QColor &col = Preferences::inst()->color(Preferences::CGAL_FACE_2D_COLOR); - const QColor &col = QColor(0x00, 0xbf, 0x99); - glColor3f(col.redF(), col.greenF(), col.blueF()); - - for (int i=0; i < this->polyset->polygons.size(); i++) { - glBegin(GL_POLYGON); - for (int j=0; j < this->polyset->polygons[i].size(); j++) { - const Vector3d &p = this->polyset->polygons[i][j]; - glVertex3d(p[0], p[1], -0.1); - } - glEnd(); - } - - typedef CGAL_Nef_polyhedron2::Explorer Explorer; - typedef Explorer::Face_const_iterator fci_t; - typedef Explorer::Halfedge_around_face_const_circulator heafcc_t; - typedef Explorer::Point Point; - Explorer E = this->root.p2->explorer(); - - // Draw 2D edges - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glLineWidth(2); -// FIXME: const QColor &col2 = Preferences::inst()->color(Preferences::CGAL_EDGE_2D_COLOR); - const QColor &col2 = QColor(0xff, 0x00, 0x00); - glColor3f(col2.redF(), col2.greenF(), col2.blueF()); - - // Extract the boundary, including inner boundaries of the polygons - for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit) { - bool fset = false; - double fx = 0.0, fy = 0.0; - heafcc_t fcirc(E.halfedge(fit)), fend(fcirc); - CGAL_For_all(fcirc, fend) { - if(E.is_standard(E.target(fcirc))) { - Point p = E.point(E.target(fcirc)); - double x = to_double(p.x()), y = to_double(p.y()); - if (!fset) { - glBegin(GL_LINE_STRIP); - fx = x, fy = y; - fset = true; - } - glVertex3d(x, y, -0.1); - } - } - if (fset) { - glVertex3d(fx, fy, -0.1); - glEnd(); - } - } - - glEnable(GL_DEPTH_TEST); - } - else if (this->root.dim == 3) { - if (showfaces) this->polyhedron->set_style(SNC_BOUNDARY); - else this->polyhedron->set_style(SNC_SKELETON); - - this->polyhedron->draw(showfaces && showedges); - } -} diff --git a/src/cgalrenderer.h b/src/cgalrenderer.h deleted file mode 100644 index 5f854ea..0000000 --- a/src/cgalrenderer.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef CGALRENDERER_H_ -#define CGALRENDERER_H_ - -#include "renderer.h" -#include "CGAL_Nef_polyhedron.h" - -class CGALRenderer : public Renderer -{ -public: - CGALRenderer(const CGAL_Nef_polyhedron &root); - ~CGALRenderer(); - void draw(bool showfaces, bool showedges) const; - -public: - const CGAL_Nef_polyhedron &root; - class Polyhedron *polyhedron; - class PolySet *polyset; -}; - -#endif -- cgit v0.10.1 From 3d204ad27be09a368f2da62cb5c930c6b7edbf55 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 01:59:06 +0200 Subject: Filename case fix diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc index da5d859..c9cfd6d 100644 --- a/src/CGALRenderer.cc +++ b/src/CGALRenderer.cc @@ -24,7 +24,7 @@ * */ -#include "cgalrenderer.h" +#include "CGALRenderer.h" #include "polyset.h" #include "CGAL_renderer.h" #include "dxfdata.h" diff --git a/src/mainwin.cc b/src/mainwin.cc index 30738d2..c112d55 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -84,7 +84,7 @@ using namespace boost::lambda; #include "CGALEvaluator.h" #include "PolySetCGALEvaluator.h" -#include "cgalrenderer.h" +#include "CGALRenderer.h" #include "CGAL_Nef_polyhedron.h" #include "cgal.h" diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc index 89f1bc9..31bbbe1 100644 --- a/tests/cgalpngtest.cc +++ b/tests/cgalpngtest.cc @@ -36,7 +36,7 @@ #include "CGAL_Nef_polyhedron.h" #include "CGALEvaluator.h" #include "PolySetCGALEvaluator.h" -#include "cgalrenderer.h" +#include "CGALRenderer.h" #include "CGAL_renderer.h" #include "cgal.h" #include "OffscreenView.h" -- cgit v0.10.1 From 2af8a70b71c540b19d87ffb84eb26e7e2f7d0726 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 02:53:30 +0200 Subject: Activated opencsgtest diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index af64772..9b8ee59 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -221,7 +221,7 @@ add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) # Add opencsg tests to CTest LIST(APPEND OPENCSGTEST_FILES ${CGALPNGTEST_FILES}) -#add_cmdline_test(opencsgtest png ${OPENCSGTEST_FILES}) +add_cmdline_test(opencsgtest png ${OPENCSGTEST_FILES}) # Add dxfexport tests to CTest #add_cmdline_test(${CMAKE_SOURCE_DIR}/../test-code/exportdxf dxf ${SCAD_FILES}) diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index b946b4f..7e85322 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -202,7 +202,7 @@ int main(int argc, char *argv[]) Vector3d cameradir(1, 1, -0.5); - Vector3d camerapos = center - radius*1.5*cameradir; + Vector3d camerapos = center - radius*1.8*cameradir; csgInfo.glview->setCamera(camerapos, center); glewInit(); diff --git a/tests/regression/opencsgtest/background-modifier-expected.png b/tests/regression/opencsgtest/background-modifier-expected.png deleted file mode 100644 index 12ba8a1..0000000 Binary files a/tests/regression/opencsgtest/background-modifier-expected.png and /dev/null differ diff --git a/tests/regression/opencsgtest/circle-tests-expected.png b/tests/regression/opencsgtest/circle-tests-expected.png index 6a826c9..7066eb9 100644 Binary files a/tests/regression/opencsgtest/circle-tests-expected.png and b/tests/regression/opencsgtest/circle-tests-expected.png differ diff --git a/tests/regression/opencsgtest/color-tests-expected.png b/tests/regression/opencsgtest/color-tests-expected.png new file mode 100644 index 0000000..b2ef8dd Binary files /dev/null and b/tests/regression/opencsgtest/color-tests-expected.png differ diff --git a/tests/regression/opencsgtest/cube-expected.png b/tests/regression/opencsgtest/cube-expected.png deleted file mode 100644 index 2de1a5f..0000000 Binary files a/tests/regression/opencsgtest/cube-expected.png and /dev/null differ diff --git a/tests/regression/opencsgtest/cube-tests-expected.png b/tests/regression/opencsgtest/cube-tests-expected.png new file mode 100644 index 0000000..8f0a361 Binary files /dev/null and b/tests/regression/opencsgtest/cube-tests-expected.png differ diff --git a/tests/regression/opencsgtest/cylinder-expected.png b/tests/regression/opencsgtest/cylinder-expected.png deleted file mode 100644 index aea350c..0000000 Binary files a/tests/regression/opencsgtest/cylinder-expected.png and /dev/null differ diff --git a/tests/regression/opencsgtest/cylinder-tests-expected.png b/tests/regression/opencsgtest/cylinder-tests-expected.png new file mode 100644 index 0000000..17c10b8 Binary files /dev/null and b/tests/regression/opencsgtest/cylinder-tests-expected.png differ diff --git a/tests/regression/opencsgtest/difference-tests-expected.png b/tests/regression/opencsgtest/difference-tests-expected.png new file mode 100644 index 0000000..d88d98b Binary files /dev/null and b/tests/regression/opencsgtest/difference-tests-expected.png differ diff --git a/tests/regression/opencsgtest/example001-expected.png b/tests/regression/opencsgtest/example001-expected.png deleted file mode 100644 index 6086195..0000000 Binary files a/tests/regression/opencsgtest/example001-expected.png and /dev/null differ diff --git a/tests/regression/opencsgtest/highlight-modifier-expected.png b/tests/regression/opencsgtest/highlight-modifier-expected.png deleted file mode 100644 index 042923f..0000000 Binary files a/tests/regression/opencsgtest/highlight-modifier-expected.png and /dev/null differ diff --git a/tests/regression/opencsgtest/import_dxf-tests-expected.png b/tests/regression/opencsgtest/import_dxf-tests-expected.png new file mode 100644 index 0000000..6e568c7 Binary files /dev/null and b/tests/regression/opencsgtest/import_dxf-tests-expected.png differ diff --git a/tests/regression/opencsgtest/intersection-tests-expected.png b/tests/regression/opencsgtest/intersection-tests-expected.png new file mode 100644 index 0000000..fc23560 Binary files /dev/null and b/tests/regression/opencsgtest/intersection-tests-expected.png differ diff --git a/tests/regression/opencsgtest/polygon-tests-expected.png b/tests/regression/opencsgtest/polygon-tests-expected.png new file mode 100644 index 0000000..4d88973 Binary files /dev/null and b/tests/regression/opencsgtest/polygon-tests-expected.png differ diff --git a/tests/regression/opencsgtest/sphere-expected.png b/tests/regression/opencsgtest/sphere-expected.png deleted file mode 100644 index 63636d4..0000000 Binary files a/tests/regression/opencsgtest/sphere-expected.png and /dev/null differ diff --git a/tests/regression/opencsgtest/sphere-tests-expected.png b/tests/regression/opencsgtest/sphere-tests-expected.png new file mode 100644 index 0000000..06161f3 Binary files /dev/null and b/tests/regression/opencsgtest/sphere-tests-expected.png differ diff --git a/tests/regression/opencsgtest/square-tests-expected.png b/tests/regression/opencsgtest/square-tests-expected.png index d5106e9..4f9db9d 100644 Binary files a/tests/regression/opencsgtest/square-tests-expected.png and b/tests/regression/opencsgtest/square-tests-expected.png differ diff --git a/tests/regression/opencsgtest/union-tests-expected.png b/tests/regression/opencsgtest/union-tests-expected.png new file mode 100644 index 0000000..caa1467 Binary files /dev/null and b/tests/regression/opencsgtest/union-tests-expected.png differ -- cgit v0.10.1 From 661a344ab8cbe17b5164afedd856ec10a8fde151 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 02:56:11 +0200 Subject: clarification diff --git a/doc/testing.txt b/doc/testing.txt index 417a3b9..5268e84 100644 --- a/doc/testing.txt +++ b/doc/testing.txt @@ -20,7 +20,7 @@ Adding a new regression test: 4) run the test with the environment variable TEST_GENERATE=1, e.g.: $ TEST_GENERATE=1 ctest -R mytest (this will generate a mytest-expected.txt file which is used for regression testing) -5) manually verify that the output is correct (test-data/scad/mytest-expected.txt) +5) manually verify that the output is correct (tests/regression//mytest-expected.) 6) run the test normally and verify that it passes: $ ctest -R mytest -- cgit v0.10.1 From 08b784f444fe3fee20f170cc709c8cd62d7afd5e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 02:58:09 +0200 Subject: more clarification diff --git a/doc/testing.txt b/doc/testing.txt index 5268e84..b64d5a4 100644 --- a/doc/testing.txt +++ b/doc/testing.txt @@ -16,12 +16,13 @@ Adding a new regression test: 1) create a test file at an appropriate location under testdata/ 2) if the test is non-obvious, create a human readable description of the test in the same directory (e.g testdata/scad/mytest.txt) -3) if a new test app was written, this must be added to tests/CMakeLists -4) run the test with the environment variable TEST_GENERATE=1, e.g.: +3) if a new test app was written, this must be added to tests/CMakeLists.txt +4) Add the tests to the test apps for which you want them to run (in tests/CMakeLists.txt) +5) run the test with the environment variable TEST_GENERATE=1, e.g.: $ TEST_GENERATE=1 ctest -R mytest (this will generate a mytest-expected.txt file which is used for regression testing) -5) manually verify that the output is correct (tests/regression//mytest-expected.) -6) run the test normally and verify that it passes: +6) manually verify that the output is correct (tests/regression//mytest-expected.) +7) run the test normally and verify that it passes: $ ctest -R mytest Note that test files which don't have an *-expected. file will -- cgit v0.10.1 From bdd7c1f583c8b37a5cbd302d66f8b5e55c5c85b8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 18:25:17 +0200 Subject: Added modifier tests. root modifier is still not working for cmd-line tools diff --git a/testdata/scad/features/disable-modifier.scad b/testdata/scad/features/disable-modifier.scad new file mode 100644 index 0000000..b47e074 --- /dev/null +++ b/testdata/scad/features/disable-modifier.scad @@ -0,0 +1,4 @@ +difference() { + *sphere(r=10); + cylinder(h=30, r=6, center=true); +} diff --git a/testdata/scad/features/root-modifier.scad b/testdata/scad/features/root-modifier.scad new file mode 100644 index 0000000..6c36433 --- /dev/null +++ b/testdata/scad/features/root-modifier.scad @@ -0,0 +1,4 @@ +difference() { + sphere(r=10); + !cylinder(h=30, r=6, center=true); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9b8ee59..a985517 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -215,7 +215,11 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/background-modifier.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/highlight-modifier.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/root-modifier.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/disable-modifier.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/background-modifier-expected.png b/tests/regression/cgalpngtest/background-modifier-expected.png new file mode 100644 index 0000000..e003a87 Binary files /dev/null and b/tests/regression/cgalpngtest/background-modifier-expected.png differ diff --git a/tests/regression/cgalpngtest/disable-modifier-expected.png b/tests/regression/cgalpngtest/disable-modifier-expected.png new file mode 100644 index 0000000..550a71d Binary files /dev/null and b/tests/regression/cgalpngtest/disable-modifier-expected.png differ diff --git a/tests/regression/cgalpngtest/highlight-modifier-expected.png b/tests/regression/cgalpngtest/highlight-modifier-expected.png new file mode 100644 index 0000000..29a4117 Binary files /dev/null and b/tests/regression/cgalpngtest/highlight-modifier-expected.png differ diff --git a/tests/regression/opencsgtest/background-modifier-expected.png b/tests/regression/opencsgtest/background-modifier-expected.png new file mode 100644 index 0000000..24149d0 Binary files /dev/null and b/tests/regression/opencsgtest/background-modifier-expected.png differ diff --git a/tests/regression/opencsgtest/disable-modifier-expected.png b/tests/regression/opencsgtest/disable-modifier-expected.png new file mode 100644 index 0000000..1e4b471 Binary files /dev/null and b/tests/regression/opencsgtest/disable-modifier-expected.png differ diff --git a/tests/regression/opencsgtest/highlight-modifier-expected.png b/tests/regression/opencsgtest/highlight-modifier-expected.png new file mode 100644 index 0000000..78d0309 Binary files /dev/null and b/tests/regression/opencsgtest/highlight-modifier-expected.png differ -- cgit v0.10.1 From 723c6b7cf28c54b93746dc99d58e16180f831e3a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 18:53:09 +0200 Subject: bugfix: root modifier now works with test apps diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc index 31bbbe1..8e3859b 100644 --- a/tests/cgalpngtest.cc +++ b/tests/cgalpngtest.cc @@ -71,6 +71,15 @@ void cgalTree(Tree &tree) evaluate.execute(); } +AbstractNode *find_root_tag(AbstractNode *n) +{ + foreach(AbstractNode *v, n->children) { + if (v->modinst->tag_root) return v; + if (AbstractNode *vroot = find_root_tag(v)) return vroot; + } + return NULL; +} + struct CsgInfo { OffscreenView *glview; @@ -131,7 +140,6 @@ int main(int argc, char **argv) AbstractModule *root_module; ModuleInstantiation root_inst; - AbstractNode *root_node; QFileInfo fileInfo(filename); handle_dep(filename); @@ -158,7 +166,10 @@ int main(int argc, char **argv) QDir::setCurrent(fileInfo.absolutePath()); AbstractNode::resetIndexCounter(); - root_node = root_module->evaluate(&root_ctx, &root_inst); + AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst); + AbstractNode *root_node; + // Do we have an explicit root node (! modifier)? + if (!(root_node = find_root_tag(absolute_root_node))) root_node = absolute_root_node; Tree tree(root_node); diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc index 44e87f9..f2fc169 100644 --- a/tests/cgaltest.cc +++ b/tests/cgaltest.cc @@ -66,6 +66,15 @@ void cgalTree(Tree &tree) evaluate.execute(); } +AbstractNode *find_root_tag(AbstractNode *n) +{ + foreach(AbstractNode *v, n->children) { + if (v->modinst->tag_root) return v; + if (AbstractNode *vroot = find_root_tag(v)) return vroot; + } + return NULL; +} + int main(int argc, char **argv) { if (argc != 2) { @@ -121,7 +130,6 @@ int main(int argc, char **argv) AbstractModule *root_module; ModuleInstantiation root_inst; - AbstractNode *root_node; QFileInfo fileInfo(filename); handle_dep(filename); @@ -148,7 +156,10 @@ int main(int argc, char **argv) QDir::setCurrent(fileInfo.absolutePath()); AbstractNode::resetIndexCounter(); - root_node = root_module->evaluate(&root_ctx, &root_inst); + AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst); + AbstractNode *root_node; + // Do we have an explicit root node (! modifier)? + if (!(root_node = find_root_tag(absolute_root_node))) root_node = absolute_root_node; Tree tree(root_node); diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index 7e85322..06b7647 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -43,6 +43,15 @@ struct CsgInfo OffscreenView *glview; }; +AbstractNode *find_root_tag(AbstractNode *n) +{ + foreach(AbstractNode *v, n->children) { + if (v->modinst->tag_root) return v; + if (AbstractNode *vroot = find_root_tag(v)) return vroot; + } + return NULL; +} + int main(int argc, char *argv[]) { if (argc != 2) { @@ -99,7 +108,6 @@ int main(int argc, char *argv[]) AbstractModule *root_module; ModuleInstantiation root_inst; - AbstractNode *root_node; QFileInfo fileInfo(filename); handle_dep(filename); @@ -126,7 +134,10 @@ int main(int argc, char *argv[]) QDir::setCurrent(fileInfo.absolutePath()); AbstractNode::resetIndexCounter(); - root_node = root_module->evaluate(&root_ctx, &root_inst); + AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst); + AbstractNode *root_node; + // Do we have an explicit root node (! modifier)? + if (!(root_node = find_root_tag(absolute_root_node))) root_node = absolute_root_node; Tree tree(root_node); diff --git a/tests/regression/cgalpngtest/root-modifier-expected.png b/tests/regression/cgalpngtest/root-modifier-expected.png new file mode 100644 index 0000000..550a71d Binary files /dev/null and b/tests/regression/cgalpngtest/root-modifier-expected.png differ diff --git a/tests/regression/opencsgtest/root-modifier-expected.png b/tests/regression/opencsgtest/root-modifier-expected.png new file mode 100644 index 0000000..1e4b471 Binary files /dev/null and b/tests/regression/opencsgtest/root-modifier-expected.png differ -- cgit v0.10.1 From a3ac7627fdc01e1a0399f75a6824a8192d5187ec Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 19:44:50 +0200 Subject: Removed dependency on Qt from control module diff --git a/src/control.cc b/src/control.cc index 2e2f525..6eaff58 100644 --- a/src/control.cc +++ b/src/control.cc @@ -29,6 +29,7 @@ #include "context.h" #include "builtin.h" #include "printutils.h" +#include enum control_type_e { CHILD, @@ -47,11 +48,15 @@ public: virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; }; -void for_eval(AbstractNode *node, size_t l, const std::vector &call_argnames, const std::vector &call_argvalues, const std::vector arg_children, const Context *arg_context) +void for_eval(AbstractNode *node, size_t l, + const std::vector &call_argnames, + const std::vector &call_argvalues, + const std::vector &arg_children, + const Context *arg_context) { if (call_argnames.size() > l) { - std::string it_name = call_argnames[l]; - Value it_values = call_argvalues[l]; + const std::string &it_name = call_argnames[l]; + const Value &it_values = call_argvalues[l]; Context c(arg_context); if (it_values.type == Value::RANGE) { double range_begin = it_values.range_begin; @@ -81,8 +86,7 @@ void for_eval(AbstractNode *node, size_t l, const std::vector &call } else { foreach (ModuleInstantiation *v, arg_children) { AbstractNode *n = v->evaluate(arg_context); - if (n != NULL) - node->children.push_back(n); + if (n != NULL) node->children.push_back(n); } } } @@ -118,15 +122,14 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation if (type == ECHO) { - QString msg = QString("ECHO: "); + std::stringstream msg; + msg << "ECHO: "; for (size_t i = 0; i < inst->argnames.size(); i++) { - if (i > 0) - msg += QString(", "); - if (!inst->argnames[i].empty()) - msg += QString::fromStdString(inst->argnames[i]) + QString(" = "); - msg += QString::fromStdString(inst->argvalues[i].toString()); + if (i > 0) msg << ", "; + if (!inst->argnames[i].empty()) msg << inst->argnames[i] << " = "; + msg << inst->argvalues[i]; } - PRINT(msg); + PRINTF("%s", msg.str().c_str()); } if (type == ASSIGN) -- cgit v0.10.1 From 2a18b857f0dccca7d9f697f7cbcae6759610429c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 20:34:17 +0200 Subject: QList -> std::vector diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 4915bf8..f4765a3 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -172,7 +172,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) node.matrix[1], node.matrix[5], node.matrix[13], node.matrix[15]); DxfData *dd = N.convertToDxfData(); - for (int i=0; i < dd->points.size(); i++) { + for (size_t i=0; i < dd->points.size(); i++) { CGAL_Kernel2::Point_2 p = CGAL_Kernel2::Point_2(dd->points[i][0], dd->points[i][1]); p = t.transform(p); dd->points[i][0] = to_double(p.x()); @@ -301,7 +301,7 @@ public: { CGAL_Polybuilder B(hds, true); - QList vertices; + std::vector vertices; Grid3d vertices_idx(GRID_FINE); for (size_t i = 0; i < ps.polygons.size(); i++) { @@ -310,7 +310,7 @@ public: const Vector3d &p = poly->at(j); if (!vertices_idx.has(p[0], p[1], p[2])) { vertices_idx.data(p[0], p[1], p[2]) = vertices.size(); - vertices.append(CGALPoint(p[0], p[1], p[2])); + vertices.push_back(CGALPoint(p[0], p[1], p[2])); } } } -- cgit v0.10.1 From 5417b4fa65098a41299bb2d693d646a5f4d06051 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 20:35:23 +0200 Subject: Ported use for Qt's foreach to BOOST_FOREACH diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 652881f..8c5c2f9 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -11,6 +11,7 @@ #include "printutils.h" #include "openscad.h" // get_fragments_from_r() +#include PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, AbstractPolyNode::render_mode_e) { @@ -251,7 +252,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, // Before extruding, union all (2D) children nodes // to a single DxfData, then tesselate this into a PolySet CGAL_Nef_polyhedron sum; - foreach (AbstractNode * v, node.getChildren()) { + BOOST_FOREACH (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); if (sum.empty()) sum = N.copy(); @@ -348,7 +349,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, // Before extruding, union all (2D) children nodes // to a single DxfData, then tesselate this into a PolySet CGAL_Nef_polyhedron sum; - foreach (AbstractNode * v, node.getChildren()) { + BOOST_FOREACH (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); if (sum.empty()) sum = N.copy(); @@ -371,10 +372,10 @@ PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, D PolySet *ps = new PolySet(); ps->convexity = node.convexity; - for (int i = 0; i < dxf.paths.size(); i++) + for (size_t i = 0; i < dxf.paths.size(); i++) { double max_x = 0; - for (int j = 0; j < dxf.paths[i].indices.size(); j++) { + for (size_t j = 0; j < dxf.paths[i].indices.size(); j++) { max_x = fmax(max_x, dxf.points[dxf.paths[i].indices[j]][0]); } @@ -384,13 +385,13 @@ PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, D points = new double**[fragments]; for (int j=0; j < fragments; j++) { points[j] = new double*[dxf.paths[i].indices.size()]; - for (int k=0; k < dxf.paths[i].indices.size(); k++) + for (size_t k=0; k < dxf.paths[i].indices.size(); k++) points[j][k] = new double[3]; } for (int j = 0; j < fragments; j++) { double a = (j*2*M_PI) / fragments; - for (int k = 0; k < dxf.paths[i].indices.size(); k++) { + for (size_t k = 0; k < dxf.paths[i].indices.size(); k++) { if (dxf.points[dxf.paths[i].indices[k]][0] == 0) { points[j][k][0] = 0; points[j][k][1] = 0; diff --git a/src/cgaladv.cc b/src/cgaladv.cc index 908000d..6c4c222 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -130,11 +130,8 @@ AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiat if (node->level <= 1) node->level = 1; - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); return node; } diff --git a/src/color.cc b/src/color.cc index c64745c..a65a8e4 100644 --- a/src/color.cc +++ b/src/color.cc @@ -82,11 +82,8 @@ AbstractNode *ColorModule::evaluate(const Context *ctx, const ModuleInstantiatio node->color[3] = alpha.num; } - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n != NULL) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); return node; } diff --git a/src/control.cc b/src/control.cc index 6eaff58..36689a0 100644 --- a/src/control.cc +++ b/src/control.cc @@ -48,10 +48,9 @@ public: virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; }; -void for_eval(AbstractNode *node, size_t l, +void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l, const std::vector &call_argnames, const std::vector &call_argvalues, - const std::vector &arg_children, const Context *arg_context) { if (call_argnames.size() > l) { @@ -70,24 +69,22 @@ void for_eval(AbstractNode *node, size_t l, if (range_step > 0 && (range_begin-range_end)/range_step < 10000) { for (double i = range_begin; i <= range_end; i += range_step) { c.set_variable(it_name, Value(i)); - for_eval(node, l+1, call_argnames, call_argvalues, arg_children, &c); + for_eval(node, inst, l+1, call_argnames, call_argvalues, &c); } } } else if (it_values.type == Value::VECTOR) { for (size_t i = 0; i < it_values.vec.size(); i++) { c.set_variable(it_name, *it_values.vec[i]); - for_eval(node, l+1, call_argnames, call_argvalues, arg_children, &c); + for_eval(node, inst, l+1, call_argnames, call_argvalues, &c); } } else { - for_eval(node, l+1, call_argnames, call_argvalues, arg_children, &c); + for_eval(node, inst, l+1, call_argnames, call_argvalues, &c); } } else { - foreach (ModuleInstantiation *v, arg_children) { - AbstractNode *n = v->evaluate(arg_context); - if (n != NULL) node->children.push_back(n); - } + std::vector evaluatednodes = inst.evaluateChildren(arg_context); + node.children.insert(node.children.end(), evaluatednodes.begin(), evaluatednodes.end()); } } @@ -139,34 +136,25 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation if (!inst->argnames[i].empty()) c.set_variable(inst->argnames[i], inst->argvalues[i]); } - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(&c); - if (n != NULL) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } if (type == FOR || type == INT_FOR) { - for_eval(node, 0, inst->argnames, inst->argvalues, inst->children, inst->ctx); + for_eval(*node, *inst, 0, inst->argnames, inst->argvalues, inst->ctx); } if (type == IF) { const IfElseModuleInstantiation *ifelse = dynamic_cast(inst); if (ifelse->argvalues.size() > 0 && ifelse->argvalues[0].type == Value::BOOL && ifelse->argvalues[0].b) { - foreach (ModuleInstantiation *v, ifelse->children) { - AbstractNode *n = v->evaluate(ifelse->ctx); - if (n != NULL) - node->children.push_back(n); - } + std::vector evaluatednodes = ifelse->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } else { - foreach (ModuleInstantiation *v, ifelse->else_children) { - AbstractNode *n = v->evaluate(ifelse->ctx); - if (n != NULL) - node->children.push_back(n); - } + std::vector evaluatednodes = ifelse->evaluateElseChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } } diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index 94792ef..14d69c4 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -109,11 +109,8 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI } if (node->filename.empty()) { - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } return node; diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index 44a70a5..338a73e 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -85,11 +85,8 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI node->scale = 1; if (node->filename.empty()) { - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } return node; diff --git a/src/mainwin.cc b/src/mainwin.cc index c112d55..170bb05 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -76,6 +76,7 @@ #endif #include +#include #include #include using namespace boost::lambda; @@ -578,7 +579,7 @@ void MainWindow::load() AbstractNode *MainWindow::find_root_tag(AbstractNode *n) { - foreach(AbstractNode *v, n->children) { + BOOST_FOREACH (AbstractNode *v, n->children) { if (v->modinst->tag_root) return v; if (AbstractNode *vroot = find_root_tag(v)) return vroot; } diff --git a/src/module.cc b/src/module.cc index 2852c4e..365eff5 100644 --- a/src/module.cc +++ b/src/module.cc @@ -42,11 +42,7 @@ AbstractNode *AbstractModule::evaluate(const Context*, const ModuleInstantiation { AbstractNode *node = new AbstractNode(inst); - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n) - node->children.push_back(n); - } + node->children = inst->evaluateChildren(); return node; } @@ -60,16 +56,13 @@ std::string AbstractModule::dump(const std::string &indent, const std::string &n ModuleInstantiation::~ModuleInstantiation() { - foreach (Expression *v, argexpr) - delete v; - foreach (ModuleInstantiation *v, children) - delete v; + BOOST_FOREACH (Expression *v, argexpr) delete v; + BOOST_FOREACH (ModuleInstantiation *v, children) delete v; } IfElseModuleInstantiation::~IfElseModuleInstantiation() { - foreach (ModuleInstantiation *v, else_children) - delete v; + BOOST_FOREACH (ModuleInstantiation *v, else_children) delete v; } std::string ModuleInstantiation::dump(const std::string &indent) const @@ -106,7 +99,7 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const } else { ModuleInstantiation *that = (ModuleInstantiation*)this; that->argvalues.clear(); - foreach (Expression *v, that->argexpr) { + BOOST_FOREACH (Expression *v, that->argexpr) { that->argvalues.push_back(v->evaluate(ctx)); } that->ctx = ctx; @@ -117,18 +110,34 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const return node; } -Module::~Module() +std::vector ModuleInstantiation::evaluateChildren(const Context *ctx) const { - foreach (Expression *v, assignments_expr) - delete v; - BOOST_FOREACH(FunctionContainer::value_type &f, functions) { - delete f.second; + if (!ctx) ctx = this->ctx; + std::vector childnodes; + BOOST_FOREACH (ModuleInstantiation *v, this->children) { + AbstractNode *n = v->evaluate(this->ctx); + if (n != NULL) childnodes.push_back(n); } - BOOST_FOREACH(AbstractModuleContainer::value_type &m, modules) { - delete m.second; + return childnodes; +} + +std::vector IfElseModuleInstantiation::evaluateElseChildren(const Context *ctx) const +{ + if (!ctx) ctx = this->ctx; + std::vector childnodes; + BOOST_FOREACH (ModuleInstantiation *v, this->else_children) { + AbstractNode *n = v->evaluate(this->ctx); + if (n != NULL) childnodes.push_back(n); } - foreach (ModuleInstantiation *v, children) - delete v; + return childnodes; +} + +Module::~Module() +{ + BOOST_FOREACH (Expression *v, assignments_expr) delete v; + BOOST_FOREACH (FunctionContainer::value_type &f, functions) delete f.second; + BOOST_FOREACH (AbstractModuleContainer::value_type &m, modules) delete m.second; + BOOST_FOREACH (ModuleInstantiation *v, children) delete v; } AbstractNode *Module::evaluate(const Context *ctx, const ModuleInstantiation *inst) const diff --git a/src/module.h b/src/module.h index 5262bfc..c28ab34 100644 --- a/src/module.h +++ b/src/module.h @@ -26,11 +26,13 @@ public: std::string dump(const std::string &indent) const; class AbstractNode *evaluate(const Context *ctx) const; + std::vector evaluateChildren(const Context *ctx = NULL) const; }; class IfElseModuleInstantiation : public ModuleInstantiation { public: virtual ~IfElseModuleInstantiation(); + std::vector evaluateElseChildren(const Context *ctx = NULL) const; std::vector else_children; }; diff --git a/src/projection.cc b/src/projection.cc index ce702e4..5a7ea6e 100644 --- a/src/projection.cc +++ b/src/projection.cc @@ -73,11 +73,8 @@ AbstractNode *ProjectionModule::evaluate(const Context *ctx, const ModuleInstant if (cut.type == Value::BOOL) node->cut_mode = cut.b; - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); return node; } diff --git a/src/render.cc b/src/render.cc index 15b4863..48a8535 100644 --- a/src/render.cc +++ b/src/render.cc @@ -62,11 +62,8 @@ AbstractNode *RenderModule::evaluate(const Context *ctx, const ModuleInstantiati if (v.type == Value::NUMBER) node->convexity = (int)v.num; - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n != NULL) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); return node; } diff --git a/src/transform.cc b/src/transform.cc index 8975fd5..3308e0c 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -239,11 +239,8 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti } } - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n != NULL) - node->children.push_back(n); - } + vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); return node; } -- cgit v0.10.1 From a376c0b1f745e73498675f9fbf8cea833b8a11d7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 20:56:22 +0200 Subject: bugfix: context mixup after last foreach fix diff --git a/src/module.cc b/src/module.cc index 365eff5..0b17ff7 100644 --- a/src/module.cc +++ b/src/module.cc @@ -115,7 +115,7 @@ std::vector ModuleInstantiation::evaluateChildren(const Context * if (!ctx) ctx = this->ctx; std::vector childnodes; BOOST_FOREACH (ModuleInstantiation *v, this->children) { - AbstractNode *n = v->evaluate(this->ctx); + AbstractNode *n = v->evaluate(ctx); if (n != NULL) childnodes.push_back(n); } return childnodes; -- cgit v0.10.1 From c9ba59bf02debd1c6409c1ac5a75a951f18a14a0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 21:02:33 +0200 Subject: Implemented support for for() with scalar argument, e.g. for (i=23) echo(i) diff --git a/doc/visitor-changes.txt b/doc/visitor-changes.txt index 2fdc944..4e864bf 100644 --- a/doc/visitor-changes.txt +++ b/doc/visitor-changes.txt @@ -1,3 +1,4 @@ Changes in visitor branch: o import_dxf(): layername="" imports all layers. Importing a single layer with a zero-length name is no longer supported. FIXME: The same prob. goes for dims o cylinder(): the r parameter will now always be used in place of a missing r1 or r2 +o for() with scalar argument now works, e.g.: for (i=23) echo(i) diff --git a/src/control.cc b/src/control.cc index 36689a0..26458fb 100644 --- a/src/control.cc +++ b/src/control.cc @@ -80,6 +80,7 @@ void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l, } } else { + c.set_variable(it_name, it_values); for_eval(node, inst, l+1, call_argnames, call_argvalues, &c); } } else { -- cgit v0.10.1 From 59b0d164889aedcda06bc7e5fcc87912c105dc24 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Sep 2011 23:20:50 +0200 Subject: bugfix: Don't try to export empty polyhedrons diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc index f2fc169..a882638 100644 --- a/tests/cgaltest.cc +++ b/tests/cgaltest.cc @@ -170,9 +170,10 @@ int main(int argc, char **argv) CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node); QDir::setCurrent(original_path.absolutePath()); - QTextStream outstream(stdout); - export_stl(&N, outstream, NULL); - + if (!N.empty()) { + QTextStream outstream(stdout); + export_stl(&N, outstream, NULL); + } destroy_builtin_functions(); destroy_builtin_modules(); -- cgit v0.10.1 From b93c5c50ca87f391abc1db08c85f22e309b967a8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 00:04:12 +0200 Subject: Added for-tests diff --git a/testdata/scad/features/for-tests.scad b/testdata/scad/features/for-tests.scad new file mode 100644 index 0000000..e68b1bc --- /dev/null +++ b/testdata/scad/features/for-tests.scad @@ -0,0 +1,18 @@ +for() cylinder(r=4); +translate([10,0,0]) for(i=3) cylinder(r=i); +for(r=[1:5]) translate([r*10-30,10,0]) cylinder(r=r); +for(r=[5:1]) translate([r*10-30,20,0]) cylinder(r=r); +for(r=[1:2:6]) translate([r*10-30,30,0]) difference() {cylinder(r=r, center=true); cylinder(r=r/2, h=2, center=true);} + +// Negative range, negative step +for(r=[5:-1:1]) translate([r*10-60,40,0]) cylinder(r=r); +// Negative range, positive step +for(r=[5:1:1]) translate([r*10-30,40,0]) cylinder(r=r); +// Zero step +for(r=[1:0:5]) translate([r*10+60,40,0]) cylinder(r=r); +// Negative step +for(r=[1:-1:5]) translate([r*10-30,50,0]) cylinder(r=r); +// Illegal step value +for(r=[1:true:5]) translate([r*10-60,50,0]) cylinder(r=r); + +// FIXME: Nested for diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a985517..7d3338e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -219,7 +219,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/background-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/highlight-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/root-modifier.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/disable-modifier.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/disable-modifier.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/for-tests-expected.png b/tests/regression/cgalpngtest/for-tests-expected.png new file mode 100644 index 0000000..1fb61dd Binary files /dev/null and b/tests/regression/cgalpngtest/for-tests-expected.png differ diff --git a/tests/regression/opencsgtest/for-tests-expected.png b/tests/regression/opencsgtest/for-tests-expected.png new file mode 100644 index 0000000..96815d6 Binary files /dev/null and b/tests/regression/opencsgtest/for-tests-expected.png differ -- cgit v0.10.1 From 81f9c7b5178adf3e7acd670914b7e01c65a0c6b8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 06:18:12 +0200 Subject: removed Qt foreach diff --git a/src/csgops.cc b/src/csgops.cc index 334db16..98d68c7 100644 --- a/src/csgops.cc +++ b/src/csgops.cc @@ -44,11 +44,8 @@ public: AbstractNode *CsgModule::evaluate(const Context*, const ModuleInstantiation *inst) const { CsgNode *node = new CsgNode(inst, type); - foreach (ModuleInstantiation *v, inst->children) { - AbstractNode *n = v->evaluate(inst->ctx); - if (n != NULL) - node->children.push_back(n); - } + std::vector evaluatednodes = inst->evaluateChildren(); + node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); return node; } -- cgit v0.10.1 From ea8a1a670c8eb5a24f36e6c282ba34f32eeea5f1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 16:25:13 +0200 Subject: bugfixes: Don't iterate over empty for loops, don't iterate over for loops with illegal values diff --git a/src/control.cc b/src/control.cc index 26458fb..01d7f03 100644 --- a/src/control.cc +++ b/src/control.cc @@ -79,11 +79,11 @@ void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l, for_eval(node, inst, l+1, call_argnames, call_argvalues, &c); } } - else { + else if (it_values.type != Value::UNDEFINED) { c.set_variable(it_name, it_values); for_eval(node, inst, l+1, call_argnames, call_argvalues, &c); } - } else { + } else if (l > 0) { std::vector evaluatednodes = inst.evaluateChildren(arg_context); node.children.insert(node.children.end(), evaluatednodes.begin(), evaluatednodes.end()); } -- cgit v0.10.1 From f0da6bf639f39212afbb6bdeb2fc2ce3d1844258 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 16:27:00 +0200 Subject: Changes to for() diff --git a/doc/visitor-changes.txt b/doc/visitor-changes.txt index 4e864bf..e9df8eb 100644 --- a/doc/visitor-changes.txt +++ b/doc/visitor-changes.txt @@ -1,4 +1,7 @@ Changes in visitor branch: o import_dxf(): layername="" imports all layers. Importing a single layer with a zero-length name is no longer supported. FIXME: The same prob. goes for dims o cylinder(): the r parameter will now always be used in place of a missing r1 or r2 -o for() with scalar argument now works, e.g.: for (i=23) echo(i) +o for(): + - with scalar argument now works, e.g.: for (i=23) echo(i) + - empty for loop is not evaluated, e.g. for () echo(i) + - for loop with illegal value is not evaluated, e.g. for ([0:true:2]) -- cgit v0.10.1 From d6947ce5c7b280a43842723f9a095f7aa9012c3f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 16:37:07 +0200 Subject: Updated for-tests after discovering a few bugs diff --git a/testdata/scad/features/for-tests.scad b/testdata/scad/features/for-tests.scad index e68b1bc..2434d1d 100644 --- a/testdata/scad/features/for-tests.scad +++ b/testdata/scad/features/for-tests.scad @@ -1,18 +1,36 @@ -for() cylinder(r=4); +// Null +translate([-10,0,0]) for() cylinder(r=4); + +// Scalar translate([10,0,0]) for(i=3) cylinder(r=i); + +// Range for(r=[1:5]) translate([r*10-30,10,0]) cylinder(r=r); + +// Reverse for(r=[5:1]) translate([r*10-30,20,0]) cylinder(r=r); + +// Step for(r=[1:2:6]) translate([r*10-30,30,0]) difference() {cylinder(r=r, center=true); cylinder(r=r/2, h=2, center=true);} +// Fractional step +for(r=[1.5:0.2:2.5]) translate([r*10-30,30,0]) cube([1, 4*r, 2], center=true); + // Negative range, negative step for(r=[5:-1:1]) translate([r*10-60,40,0]) cylinder(r=r); + // Negative range, positive step for(r=[5:1:1]) translate([r*10-30,40,0]) cylinder(r=r); + // Zero step + for(r=[1:0:5]) translate([r*10+60,40,0]) cylinder(r=r); + // Negative step for(r=[1:-1:5]) translate([r*10-30,50,0]) cylinder(r=r); + // Illegal step value for(r=[1:true:5]) translate([r*10-60,50,0]) cylinder(r=r); -// FIXME: Nested for +// Vector +for(r=[1,2,5]) translate([r*10-30,0,0]) cylinder(r=r); diff --git a/tests/regression/cgalpngtest/for-tests-expected.png b/tests/regression/cgalpngtest/for-tests-expected.png index 1fb61dd..bf1970a 100644 Binary files a/tests/regression/cgalpngtest/for-tests-expected.png and b/tests/regression/cgalpngtest/for-tests-expected.png differ diff --git a/tests/regression/opencsgtest/for-tests-expected.png b/tests/regression/opencsgtest/for-tests-expected.png index 96815d6..968659d 100644 Binary files a/tests/regression/opencsgtest/for-tests-expected.png and b/tests/regression/opencsgtest/for-tests-expected.png differ -- cgit v0.10.1 From ff753020026f5c3b9f2f0b1951c0b45709cdee5d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 16:38:50 +0200 Subject: Added for-nested-tests diff --git a/testdata/scad/features/for-nested-tests.scad b/testdata/scad/features/for-nested-tests.scad new file mode 100644 index 0000000..e3b5877 --- /dev/null +++ b/testdata/scad/features/for-nested-tests.scad @@ -0,0 +1,3 @@ +for(x=[0:3], y=[0:0.5:1], z=[0,2,3]) { + translate(10*[x,y,z]) sphere(r=3); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7d3338e..a18c6fc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -220,7 +220,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/highlight-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/root-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/disable-modifier.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-nested-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/for-nested-tests-expected.png b/tests/regression/cgalpngtest/for-nested-tests-expected.png new file mode 100644 index 0000000..e7178c2 Binary files /dev/null and b/tests/regression/cgalpngtest/for-nested-tests-expected.png differ diff --git a/tests/regression/opencsgtest/for-nested-tests-expected.png b/tests/regression/opencsgtest/for-nested-tests-expected.png new file mode 100644 index 0000000..c9cdb74 Binary files /dev/null and b/tests/regression/opencsgtest/for-nested-tests-expected.png differ -- cgit v0.10.1 From 4a952c3cc05704c64126f8b533501f62dcf7c416 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 17:02:37 +0200 Subject: bugfix: Forgot to enable PolySetCGALEvaluator diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index 06b7647..ebcfdd3 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -145,7 +145,7 @@ int main(int argc, char *argv[]) QHash cache; CGALEvaluator cgalevaluator(cache, tree); PolySetCGALEvaluator psevaluator(cgalevaluator); - CSGTermEvaluator evaluator(tree); + CSGTermEvaluator evaluator(tree, &psevaluator); CSGTerm *root_raw_term = evaluator.evaluateCSGTerm(*root_node, csgInfo.highlight_terms, csgInfo.background_terms); -- cgit v0.10.1 From a75d95b8dee0e9ffc609d1458efc13fea22d1263 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 17:03:25 +0200 Subject: Slightly modified to yield better test coverage diff --git a/testdata/scad/features/linear_extrude-tests.scad b/testdata/scad/features/linear_extrude-tests.scad index af050fb..7138e94 100644 --- a/testdata/scad/features/linear_extrude-tests.scad +++ b/testdata/scad/features/linear_extrude-tests.scad @@ -1,7 +1,8 @@ linear_extrude(height=10) square([10,10]); -translate([19,5,0]) linear_extrude(height=10) circle(5); -translate([31.5,2.5,0]) linear_extrude(height=10) polygon(points = [[-5,-2.5], [5,-2.5], [0,2.5]]); +translate([19,5,0]) linear_extrude(height=10, center=true) difference() {circle(5); circle(3);} +translate([31.5,2.5,0]) linear_extrude(height=10, twist=-45) polygon(points = [[-5,-2.5], [5,-2.5], [0,2.5]]); -translate([0,-12,0]) linear_extrude(height=20, twist=45) square([10,10]); -translate([19,-7,0]) linear_extrude(height=20, twist=90) circle(5); -translate([31.5,-9.5,0]) linear_extrude(height=20, twist=180) polygon(points = [[-5,-2.5], [5,-2.5], [0,2.5]]); +translate([0,20,0]) linear_extrude(height=20, twist=45, slices=2) square([10,10]); +translate([19,20,0]) linear_extrude(height=20, twist=45, slices=10) square([10,10]); + +// FIXME: Test dxf version \ No newline at end of file -- cgit v0.10.1 From d5fefdf37c3c8966f77fe7168facdea167cd70e9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 17:03:39 +0200 Subject: Added linear_extrude-tests diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a18c6fc..cf9ce31 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -214,6 +214,7 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/union-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/linear_extrude-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/background-modifier.scad diff --git a/tests/regression/cgalpngtest/linear_extrude-tests-expected.png b/tests/regression/cgalpngtest/linear_extrude-tests-expected.png new file mode 100644 index 0000000..4ed4361 Binary files /dev/null and b/tests/regression/cgalpngtest/linear_extrude-tests-expected.png differ diff --git a/tests/regression/opencsgtest/linear_extrude-tests-expected.png b/tests/regression/opencsgtest/linear_extrude-tests-expected.png new file mode 100644 index 0000000..579479e Binary files /dev/null and b/tests/regression/opencsgtest/linear_extrude-tests-expected.png differ -- cgit v0.10.1 From a63612e57b6ea2f6d32746ebb1489f9621619259 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 17:15:56 +0200 Subject: Added rotate_extrude-tests diff --git a/testdata/scad/features/rotate_extrude-tests.scad b/testdata/scad/features/rotate_extrude-tests.scad index 7bbcef0..32eaf34 100644 --- a/testdata/scad/features/rotate_extrude-tests.scad +++ b/testdata/scad/features/rotate_extrude-tests.scad @@ -1,2 +1,23 @@ +// Normal rotate_extrude() translate([20,0,0]) circle(r=10); +// Sweep of polygon with hole +translate([50,-20,0]) { + difference() { + rotate_extrude() translate([20,0,0]) difference() { + circle(r=10); circle(r=8); + } + translate([-50,0,0]) cube([100,100,100], center=true); + } +} + +// Alternative, difference between two solid sweeps +translate([50,50,0]) { + difference() { + difference() { + rotate_extrude() translate([20,0,0]) circle(r=10); + rotate_extrude() translate([20,0,0]) circle(r=8); + } + translate([-50,0,0]) cube([100,100,100], center=true); + } +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cf9ce31..6897d8f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -215,6 +215,7 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/difference-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/linear_extrude-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/rotate_extrude-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/background-modifier.scad diff --git a/tests/regression/cgalpngtest/rotate_extrude-tests-expected.png b/tests/regression/cgalpngtest/rotate_extrude-tests-expected.png new file mode 100644 index 0000000..ee60a72 Binary files /dev/null and b/tests/regression/cgalpngtest/rotate_extrude-tests-expected.png differ diff --git a/tests/regression/opencsgtest/rotate_extrude-tests-expected.png b/tests/regression/opencsgtest/rotate_extrude-tests-expected.png new file mode 100644 index 0000000..96452e1 Binary files /dev/null and b/tests/regression/opencsgtest/rotate_extrude-tests-expected.png differ -- cgit v0.10.1 From ae24edb79041b897f0ed8eb58ba94f4a639b4019 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 17:55:17 +0200 Subject: Added intersection_for-tests diff --git a/testdata/scad/features/intersection_for-tests.scad b/testdata/scad/features/intersection_for-tests.scad new file mode 100644 index 0000000..ad058ac --- /dev/null +++ b/testdata/scad/features/intersection_for-tests.scad @@ -0,0 +1,5 @@ +intersection_for(i = [[0, 0, 0], + [10, 20, 300], + [200, 40, 57], + [20, 88, 57]]) + rotate(i) cube([100, 20, 20], center = true); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6897d8f..863164f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -223,7 +223,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/root-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/disable-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-nested-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-nested-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection_for-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/intersection_for-tests-expected.png b/tests/regression/cgalpngtest/intersection_for-tests-expected.png new file mode 100644 index 0000000..dc4c56a Binary files /dev/null and b/tests/regression/cgalpngtest/intersection_for-tests-expected.png differ diff --git a/tests/regression/opencsgtest/intersection_for-tests-expected.png b/tests/regression/opencsgtest/intersection_for-tests-expected.png new file mode 100644 index 0000000..08c8e06 Binary files /dev/null and b/tests/regression/opencsgtest/intersection_for-tests-expected.png differ -- cgit v0.10.1 From 06001a466599f4199a1a57a2cd45a2cf41c3db82 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 18:00:20 +0200 Subject: Added surface-tests diff --git a/testdata/scad/features/surface-tests.scad b/testdata/scad/features/surface-tests.scad index 32072fa..98918d7 100644 --- a/testdata/scad/features/surface-tests.scad +++ b/testdata/scad/features/surface-tests.scad @@ -1 +1 @@ -surface("surface.dat"); +surface("surface.dat", center=true); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 863164f..fa61db8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -216,6 +216,7 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/linear_extrude-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/rotate_extrude-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/surface-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/background-modifier.scad diff --git a/tests/regression/cgalpngtest/surface-tests-expected.png b/tests/regression/cgalpngtest/surface-tests-expected.png new file mode 100644 index 0000000..cc29f66 Binary files /dev/null and b/tests/regression/cgalpngtest/surface-tests-expected.png differ diff --git a/tests/regression/opencsgtest/surface-tests-expected.png b/tests/regression/opencsgtest/surface-tests-expected.png new file mode 100644 index 0000000..2655afb Binary files /dev/null and b/tests/regression/opencsgtest/surface-tests-expected.png differ -- cgit v0.10.1 From 23af865389ff16987033364c32a711413022b8b8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 18:20:43 +0200 Subject: Added transform-tests diff --git a/testdata/scad/features/transform-tests.scad b/testdata/scad/features/transform-tests.scad new file mode 100644 index 0000000..a591695 --- /dev/null +++ b/testdata/scad/features/transform-tests.scad @@ -0,0 +1,18 @@ +module mycyl() { + cylinder(r1=10, r2=0, h=20); +} + +translate([25,0,0]) scale([1,2,0.5]) mycyl(); +translate([20,-30,0]) scale(0.5) mycyl(); +translate([0,-20,0]) rotate([90,0,0]) mycyl(); +rotate(v=[-1,0,0], a=45) mycyl(); +multmatrix([[1,0,0,-25], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1]]) mycyl(); +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() \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fa61db8..a869cdf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -218,6 +218,7 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/rotate_extrude-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/surface-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/transform-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/color-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/background-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/highlight-modifier.scad diff --git a/tests/regression/cgalpngtest/transform-tests-expected.png b/tests/regression/cgalpngtest/transform-tests-expected.png new file mode 100644 index 0000000..08cfce8 Binary files /dev/null and b/tests/regression/cgalpngtest/transform-tests-expected.png differ diff --git a/tests/regression/opencsgtest/transform-tests-expected.png b/tests/regression/opencsgtest/transform-tests-expected.png new file mode 100644 index 0000000..9c763ba Binary files /dev/null and b/tests/regression/opencsgtest/transform-tests-expected.png differ -- cgit v0.10.1 From 5ca65805de57ac160304d2788491be433b04e12e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Sep 2011 23:06:35 +0200 Subject: Reenabled minkowski sums diff --git a/src/cgaladvnode.h b/src/cgaladvnode.h new file mode 100644 index 0000000..a3f8bea --- /dev/null +++ b/src/cgaladvnode.h @@ -0,0 +1,34 @@ +#ifndef CGALADVNODE_H_ +#define CGALADVNODE_H_ + +#include "node.h" +#include "visitor.h" +#include "value.h" + +enum cgaladv_type_e { + MINKOWSKI, + GLIDE, + SUBDIV, + HULL +}; + +class CgaladvNode : public AbstractNode +{ +public: + CgaladvNode(const ModuleInstantiation *mi, cgaladv_type_e type) : AbstractNode(mi), type(type) { + convexity = 1; + } + virtual ~CgaladvNode() { } + virtual Response accept(class State &state, Visitor &visitor) const { + return visitor.visit(state, *this); + } + virtual std::string toString() const; + virtual std::string name() const; + + Value path; + std::string subdiv_type; + int convexity, level; + cgaladv_type_e type; +}; + +#endif -- cgit v0.10.1 From fdd96a177c0fb3a94d317cb3e584b4881c09ea0e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 14:56:04 +0200 Subject: Added minkowski and 2d-3d tests diff --git a/testdata/scad/features/2d-3d.scad b/testdata/scad/features/2d-3d.scad new file mode 100644 index 0000000..ca9f966 --- /dev/null +++ b/testdata/scad/features/2d-3d.scad @@ -0,0 +1,3 @@ +// Test a mix of toplevel 2D and 3D objects +cube(); +translate([2,0,0]) square(); diff --git a/testdata/scad/features/minkowski-tests.scad b/testdata/scad/features/minkowski-tests.scad deleted file mode 100644 index 6d0dade..0000000 --- a/testdata/scad/features/minkowski-tests.scad +++ /dev/null @@ -1,67 +0,0 @@ - -// Rounded box using 3d minkowski -module roundedBox3dSimple() { - minkowski() { - cube([10,10,5]); - cylinder(r=5, h=5); - } -} - -// Currently segfaults -module roundedBox3dCut() { - minkowski() { - difference() { - cube([10,10,5]); - cube([5,5,5]); - } - cylinder(r=5, h=5); - } -} - -// Currently segfaults -module roundedBox3dHole() { - minkowski() { - difference() { - cube([10,10,5]); - translate([2,2,-2]) cube([6,6,10]); - } - cylinder(r=2); - } -} - -// Works correctly -module roundedBox2dSimple() { - minkowski() { - square([10,10]); - circle(r=5); - } -} - -// Works correctly -module roundedBox2dCut() { - minkowski() { - difference() { - square([10,10]); - square([5,5]); - } - circle(r=5); - } -} - -// Not quite correct, result does not contain a hole, since the impl currently returns the outer boundary of the polygon_with_holes. -module roundedBox2dHole() { - minkowski() { - difference() { - square([10,10]); - translate([2,2]) square([6,6]); - } - circle(r=2); - } -} - -translate([-25,0,0]) roundedBox2dHole(); -translate([0,0,0]) roundedBox2dCut(); -translate([25,0,0]) roundedBox2dSimple(); -translate([-25,25,0]) roundedBox3dHole(); -translate([0,25,0]) roundedBox3dCut(); -translate([25,25,0]) roundedBox3dSimple(); diff --git a/testdata/scad/features/minkowski2-tests.scad b/testdata/scad/features/minkowski2-tests.scad new file mode 100644 index 0000000..08f3d98 --- /dev/null +++ b/testdata/scad/features/minkowski2-tests.scad @@ -0,0 +1,31 @@ +module roundedBox2dSimple() { + minkowski() { + square([10,10]); + circle(r=5); + } +} + +module roundedBox2dCut() { + minkowski() { + difference() { + square([10,10]); + square([5,5]); + } + circle(r=5); + } +} + +// Not quite correct, result does not contain a hole, since the impl currently returns the outer boundary of the polygon_with_holes. +module roundedBox2dHole() { + minkowski() { + difference() { + square([10,10], center=true); + square([8,8], center=true); + } + circle(r=2); + } +} + +translate([-20,5,0]) roundedBox2dHole(); +translate([0,0,0]) roundedBox2dCut(); +translate([25,0,0]) roundedBox2dSimple(); diff --git a/testdata/scad/features/minkowski3-tests.scad b/testdata/scad/features/minkowski3-tests.scad new file mode 100644 index 0000000..0e53563 --- /dev/null +++ b/testdata/scad/features/minkowski3-tests.scad @@ -0,0 +1,30 @@ +module roundedBox3dSimple() { + minkowski() { + cube([10,10,5]); + cylinder(r=5, h=5); + } +} + +module roundedBox3dCut() { + minkowski() { + difference() { + cube([10,10,5]); + cube([5,5,5]); + } + cylinder(r=5, h=5); + } +} + +module roundedBox3dHole() { + minkowski() { + difference() { + cube([10,10,5], center=true); + cube([8,8,10], center=true); + } + cylinder(r=2); + } +} + +translate([-20,30,0]) roundedBox3dHole(); +translate([0,25,0]) roundedBox3dCut(); +translate([25,25,0]) roundedBox3dSimple(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a869cdf..6c8e24b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -205,6 +205,7 @@ add_cmdline_test(cgaltest stl ${CGALTEST_FILES}) # Add cgalpngtest tests to CTest LIST(APPEND CGALPNGTEST_FILES + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/2d-3d.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/circle-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/square-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/polygon-tests.scad @@ -216,6 +217,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/linear_extrude-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/rotate_extrude-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/minkowski2-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/minkowski3-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/surface-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/transform-tests.scad diff --git a/tests/regression/cgalpngtest/2d-3d-expected.png b/tests/regression/cgalpngtest/2d-3d-expected.png new file mode 100644 index 0000000..4d202ac Binary files /dev/null and b/tests/regression/cgalpngtest/2d-3d-expected.png differ diff --git a/tests/regression/cgalpngtest/minkowski2-tests-expected.png b/tests/regression/cgalpngtest/minkowski2-tests-expected.png new file mode 100644 index 0000000..ebdbc74 Binary files /dev/null and b/tests/regression/cgalpngtest/minkowski2-tests-expected.png differ diff --git a/tests/regression/cgalpngtest/minkowski3-tests-expected.png b/tests/regression/cgalpngtest/minkowski3-tests-expected.png new file mode 100644 index 0000000..6d74961 Binary files /dev/null and b/tests/regression/cgalpngtest/minkowski3-tests-expected.png differ diff --git a/tests/regression/opencsgtest/2d-3d-expected.png b/tests/regression/opencsgtest/2d-3d-expected.png new file mode 100644 index 0000000..47418f0 Binary files /dev/null and b/tests/regression/opencsgtest/2d-3d-expected.png differ diff --git a/tests/regression/opencsgtest/minkowski2-tests-expected.png b/tests/regression/opencsgtest/minkowski2-tests-expected.png new file mode 100644 index 0000000..062f1ed Binary files /dev/null and b/tests/regression/opencsgtest/minkowski2-tests-expected.png differ diff --git a/tests/regression/opencsgtest/minkowski3-tests-expected.png b/tests/regression/opencsgtest/minkowski3-tests-expected.png new file mode 100644 index 0000000..1f0d572 Binary files /dev/null and b/tests/regression/opencsgtest/minkowski3-tests-expected.png differ -- cgit v0.10.1 From 1e4e18c52451d2f04050cb44441b615398882c56 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 14:57:24 +0200 Subject: minkowski sums should now work again diff --git a/openscad.pro b/openscad.pro index d3923e5..a7dd59e 100644 --- a/openscad.pro +++ b/openscad.pro @@ -142,6 +142,7 @@ HEADERS += src/renderer.h \ src/dxflinextrudenode.h \ src/dxfrotextrudenode.h \ src/projectionnode.h \ + src/cgaladvnode.h \ src/importnode.h \ src/transformnode.h \ src/colornode.h \ diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index f4765a3..0d67152 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -5,6 +5,7 @@ #include "printutils.h" #include "csgnode.h" +#include "cgaladvnode.h" #include "transformnode.h" #include "polyset.h" #include "dxfdata.h" @@ -47,7 +48,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr assert(false && "Dimension of Nef polyhedron must be 2 or 3"); } if (src.empty()) return; // Empty polyhedron. This can happen for e.g. square([0,0]) - assert(target.dim == src.dim); + if (target.dim != src.dim) return; // If someone tries to e.g. union 2d and 3d objects switch (op) { case CGE_UNION: @@ -203,14 +204,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) } // FIXME: EvaluateNode: Union over children + some magic -// FIXME: CgaladvNode: Iterate over children. Special operation - -// FIXME: Subtypes of AbstractPolyNode: -// ProjectionNode -// DxfLinearExtrudeNode -// DxfRotateExtrudeNode -// (SurfaceNode) -// (PrimitiveNode) + Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) { if (state.isPrefix() && isCached(node)) return PruneTraversal; @@ -242,6 +236,32 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) return ContinueTraversal; } +Response CGALEvaluator::visit(State &state, const CgaladvNode &node) +{ + if (state.isPrefix() && isCached(node)) return PruneTraversal; + if (state.isPostfix()) { + if (!isCached(node)) { + CGALEvaluator::CsgOp op; + switch (node.type) { + case MINKOWSKI: + op = CGE_MINKOWSKI; + break; + case GLIDE: + case SUBDIV: + // FIXME: Not implemented + return PruneTraversal; + break; + case HULL: + op = CGE_HULL; + break; + } + applyToChildren(node, op); + } + addToParent(state, node); + } + return ContinueTraversal; +} + /*! Adds ourself to out parent's list of traversed children. Call this for _every_ node which affects output during the postfix traversal. diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index 8af64e3..a985065 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -29,6 +29,7 @@ public: virtual Response visit(State &state, const CsgNode &node); virtual Response visit(State &state, const TransformNode &node); virtual Response visit(State &state, const AbstractPolyNode &node); + virtual Response visit(State &state, const CgaladvNode &node); CGAL_Nef_polyhedron evaluateCGALMesh(const AbstractNode &node); CGAL_Nef_polyhedron evaluateCGALMesh(const PolySet &polyset); diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index 0c8c627..afe7119 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -1,6 +1,8 @@ #include "CGAL_Nef_polyhedron.h" #include "cgal.h" #include "polyset.h" +#include "dxfdata.h" +#include "dxftess.h" #include CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other) @@ -48,38 +50,48 @@ int CGAL_Nef_polyhedron::weight() const */ PolySet *CGAL_Nef_polyhedron::convertToPolyset() { + assert(!this->empty()); PolySet *ps = new PolySet(); - CGAL_Polyhedron P; - this->p3->convert_to_Polyhedron(P); - - typedef CGAL_Polyhedron::Vertex Vertex; - typedef CGAL_Polyhedron::Vertex_const_iterator VCI; - typedef CGAL_Polyhedron::Facet_const_iterator FCI; - typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; - - for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { - HFCC hc = fi->facet_begin(); - HFCC hc_end = hc; - Vertex v1, v2, v3; - v1 = *VCI((hc++)->vertex()); - v3 = *VCI((hc++)->vertex()); - do { - v2 = v3; + if (this->dim == 2) { + DxfData *dd = this->convertToDxfData(); + ps->is2d = true; + dxf_tesselate(ps, *dd, 0, true, false, 0); + dxf_border_to_ps(ps, *dd); + delete dd; + } + else if (this->dim == 3) { + CGAL_Polyhedron P; + this->p3->convert_to_Polyhedron(P); + + typedef CGAL_Polyhedron::Vertex Vertex; + typedef CGAL_Polyhedron::Vertex_const_iterator VCI; + typedef CGAL_Polyhedron::Facet_const_iterator FCI; + typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; + + for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { + HFCC hc = fi->facet_begin(); + HFCC hc_end = hc; + Vertex v1, v2, v3; + v1 = *VCI((hc++)->vertex()); v3 = *VCI((hc++)->vertex()); - double x1 = CGAL::to_double(v1.point().x()); - double y1 = CGAL::to_double(v1.point().y()); - double z1 = CGAL::to_double(v1.point().z()); - double x2 = CGAL::to_double(v2.point().x()); - double y2 = CGAL::to_double(v2.point().y()); - double z2 = CGAL::to_double(v2.point().z()); - double x3 = CGAL::to_double(v3.point().x()); - double y3 = CGAL::to_double(v3.point().y()); - double z3 = CGAL::to_double(v3.point().z()); - ps->append_poly(); - ps->append_vertex(x1, y1, z1); - ps->append_vertex(x2, y2, z2); - ps->append_vertex(x3, y3, z3); - } while (hc != hc_end); + do { + v2 = v3; + v3 = *VCI((hc++)->vertex()); + double x1 = CGAL::to_double(v1.point().x()); + double y1 = CGAL::to_double(v1.point().y()); + double z1 = CGAL::to_double(v1.point().z()); + double x2 = CGAL::to_double(v2.point().x()); + double y2 = CGAL::to_double(v2.point().y()); + double z2 = CGAL::to_double(v2.point().z()); + double x3 = CGAL::to_double(v3.point().x()); + double y3 = CGAL::to_double(v3.point().y()); + double z3 = CGAL::to_double(v3.point().z()); + ps->append_poly(); + ps->append_vertex(x1, y1, z1); + ps->append_vertex(x2, y2, z2); + ps->append_vertex(x3, y3, z3); + } while (hc != hc_end); + } } return ps; } diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index b75babe..b59f4db 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -7,7 +7,9 @@ #include "transformnode.h" #include "colornode.h" #include "rendernode.h" +#include "cgaladvnode.h" #include "printutils.h" +#include "PolySetEvaluator.h" #include #include @@ -88,7 +90,7 @@ static CSGTerm *evaluate_csg_term_from_ps(const State &state, vector &background, PolySet *ps, const ModuleInstantiation *modinst, - const AbstractPolyNode &node) + const AbstractNode &node) { std::stringstream stream; stream << node.name() << node.index(); @@ -184,6 +186,25 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node) return ContinueTraversal; } +Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node) +{ + if (state.isPostfix()) { + CSGTerm *t1 = NULL; + // FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this. + PolySet *ps = NULL; + if (this->psevaluator) { + ps = this->psevaluator->evaluatePolySet(node, AbstractPolyNode::RENDER_OPENCSG); + } + if (ps) { + t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, + ps, node.modinst, node); + } + this->stored_term[node.index()] = t1; + addToParent(state, node); + } + return ContinueTraversal; +} + /*! Adds ourself to out parent's list of traversed children. Call this for _every_ node which affects output during the postfix traversal. diff --git a/src/CSGTermEvaluator.h b/src/CSGTermEvaluator.h index 6bff7f5..ac22906 100644 --- a/src/CSGTermEvaluator.h +++ b/src/CSGTermEvaluator.h @@ -29,6 +29,7 @@ public: virtual Response visit(State &state, const TransformNode &node); virtual Response visit(State &state, const ColorNode &node); virtual Response visit(State &state, const RenderNode &node); + virtual Response visit(State &state, const CgaladvNode &node); class CSGTerm *evaluateCSGTerm(const AbstractNode &node, vector &highlights, diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 8c5c2f9..c42d806 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -5,6 +5,7 @@ #include "projectionnode.h" #include "dxflinextrudenode.h" #include "dxfrotextrudenode.h" +#include "cgaladvnode.h" #include "dxfdata.h" #include "dxftess.h" #include "module.h" @@ -367,6 +368,15 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, return ps; } +PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e) +{ + CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node); + PolySet *ps = NULL; + if (!N.empty()) ps = N.convertToPolyset(); + return ps; +} + + PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, DxfData &dxf) { PolySet *ps = new PolySet(); diff --git a/src/PolySetCGALEvaluator.h b/src/PolySetCGALEvaluator.h index a39e4ff..cf3c5b2 100644 --- a/src/PolySetCGALEvaluator.h +++ b/src/PolySetCGALEvaluator.h @@ -16,6 +16,7 @@ public: virtual PolySet *evaluatePolySet(const ProjectionNode &node, AbstractPolyNode::render_mode_e); virtual PolySet *evaluatePolySet(const DxfLinearExtrudeNode &node, AbstractPolyNode::render_mode_e); virtual PolySet *evaluatePolySet(const DxfRotateExtrudeNode &node, AbstractPolyNode::render_mode_e); + virtual PolySet *evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e); protected: PolySet *extrudeDxfData(const DxfLinearExtrudeNode &node, class DxfData &dxf); diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h index dcc67db..9a72ff7 100644 --- a/src/PolySetEvaluator.h +++ b/src/PolySetEvaluator.h @@ -16,6 +16,7 @@ public: virtual PolySet *evaluatePolySet(const class ProjectionNode &, AbstractPolyNode::render_mode_e) = 0; virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; virtual PolySet *evaluatePolySet(const class DxfRotateExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; + virtual PolySet *evaluatePolySet(const class CgaladvNode &, AbstractPolyNode::render_mode_e) = 0; void clearCache() { this->cache.clear(); diff --git a/src/cgaladv.cc b/src/cgaladv.cc index 6c4c222..8ffd626 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -24,24 +24,16 @@ * */ +#include "cgaladvnode.h" #include "module.h" -#include "node.h" #include "context.h" #include "builtin.h" #include "printutils.h" -#include "visitor.h" #include #include #include using namespace boost::assign; // bring 'operator+=()' into scope -enum cgaladv_type_e { - MINKOWSKI, - GLIDE, - SUBDIV, - HULL -}; - class CgaladvModule : public AbstractModule { public: @@ -50,42 +42,6 @@ public: virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; }; -class CgaladvNode : public AbstractNode -{ -public: - CgaladvNode(const ModuleInstantiation *mi, cgaladv_type_e type) : AbstractNode(mi), type(type) { - convexity = 1; - } - virtual ~CgaladvNode() { } - virtual Response accept(class State &state, Visitor &visitor) const { - return visitor.visit(state, *this); - } - virtual std::string toString() const; - virtual std::string name() const { - switch (this->type) { - case MINKOWSKI: - return "minkowski"; - break; - case GLIDE: - return "glide"; - break; - case SUBDIV: - return "subdiv"; - break; - case HULL: - return "hull"; - break; - default: - assert(false); - } - } - - Value path; - std::string subdiv_type; - int convexity, level; - cgaladv_type_e type; -}; - AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const { CgaladvNode *node = new CgaladvNode(inst, type); @@ -144,6 +100,26 @@ void register_builtin_cgaladv() builtin_modules["hull"] = new CgaladvModule(HULL); } +std::string CgaladvNode::name() const +{ + switch (this->type) { + case MINKOWSKI: + return "minkowski"; + break; + case GLIDE: + return "glide"; + break; + case SUBDIV: + return "subdiv"; + break; + case HULL: + return "hull"; + break; + default: + assert(false); + } +} + std::string CgaladvNode::toString() const { std::stringstream stream; -- cgit v0.10.1 From 1d7a05744a36406d188f4d274403df69310f6bdb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 15:48:47 +0200 Subject: Fixes crash bug reported by Brad Pitcher diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 0d67152..89a9e6b 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -504,7 +504,13 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) double x = ps.polygons[i][j][0]; double y = ps.polygons[i][j][1]; if (this->grid.has(x, y)) { - this->polygons[this->poly_n].append(this->grid.data(x, y)); + int idx = this->grid.data(x, y); + // Filter away two vertices with the same index (due to grid) + // This could be done in a more general way, but we'd rather redo the entire + // grid concept instead. + if (this->polygons[this->poly_n].indexOf(idx) == -1) { + this->polygons[this->poly_n].append(this->grid.data(x, y)); + } } else { this->grid.align(x, y) = point_n; this->polygons[this->poly_n].append(point_n); @@ -512,8 +518,13 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) point_n++; } } - add_edges(this->poly_n); - this->poly_n++; + if (this->polygons[this->poly_n].size() >= 3) { + add_edges(this->poly_n); + this->poly_n++; + } + else { + this->polygons.remove(this->poly_n); + } } } @@ -599,9 +610,9 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) }; PolyReducer pr(ps); - // printf("Number of polygons before reduction: %d\n", pr.polygons.size()); + PRINTF("Number of polygons before reduction: %d\n", pr.polygons.size()); pr.reduce(); - // printf("Number of polygons after reduction: %d\n", pr.polygons.size()); + PRINTF("Number of polygons after reduction: %d\n", pr.polygons.size()); return CGAL_Nef_polyhedron(pr.toNef()); #endif #if 0 -- cgit v0.10.1 From 1cf876734fa85d06dfbe6458e49165709f4fcf9c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 15:49:11 +0200 Subject: Crash bug by Brad Pitcher diff --git a/testdata/scad/bugs/gridbug.scad b/testdata/scad/bugs/gridbug.scad new file mode 100644 index 0000000..678a22a --- /dev/null +++ b/testdata/scad/bugs/gridbug.scad @@ -0,0 +1,9 @@ +// This crashes OpenSCAD including 2011.06 in PolyReducer due to two vertices of +// a triangle evaluating to the same index +linear_extrude(height=2) + polygon(points=[[0, 0], + [1, 0], + [1.0014, 1], + [1, 1], + [0, 1]], + paths=[[0,1,2,3,4]]); -- cgit v0.10.1 From 80f998377f14410bdb4d38927b370e7a2a4ccddb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 18:19:29 +0200 Subject: bugfix: When canceling the file open dialog, don't open a new window diff --git a/src/mainwin.cc b/src/mainwin.cc index 170bb05..e1ab8f0 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -862,6 +862,7 @@ void MainWindow::compileCSG(bool procevents) PRINTF("WARNING: OpenCSG rendering has been disabled."); } else { + PRINTF("Normalized CSG tree has %d elements", root_chain->polysets.size()); this->opencsgRenderer = new OpenCSGRenderer(this->root_chain, this->highlights_chain, this->background_chain, @@ -896,7 +897,9 @@ void MainWindow::actionOpen() { QString new_filename = QFileDialog::getOpenFileName(this, "Open File", "", "OpenSCAD Designs (*.scad)"); #ifdef ENABLE_MDI - new MainWindow(new_filename); + if (!new_filename.isEmpty()) { + new MainWindow(new_filename); + } #else if (!new_filename.isEmpty()) { if (!maybeSave()) -- cgit v0.10.1 From 15542c374d50944f59a8c0194b39c4e2d655fab1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 18:28:01 +0200 Subject: Added render-tests diff --git a/testdata/scad/features/render-tests.scad b/testdata/scad/features/render-tests.scad new file mode 100644 index 0000000..56531c6 --- /dev/null +++ b/testdata/scad/features/render-tests.scad @@ -0,0 +1,31 @@ +module edgeprofile() +{ + difference() { + cube([20, 20, 150], center = true); + translate([-10, -10, 0]) cylinder(h = 80, r = 10, center = true); + } +} + +module rendered_edgeprofile() +{ + render(convexity = 2) edgeprofile(); +} + +module mycube() { + difference() { + cube(100, center = true); + translate([ -50, -50, 0 ]) rotate(180, [0, 0, 1]) edgeprofile(); + translate([ 50, -50, 0 ]) rotate(270, [0, 0, 1]) edgeprofile(); + } +} + +module rendered_mycube() { + difference() { + cube(100, center = true); + translate([ -50, -50, 0 ]) rotate(180, [0, 0, 1]) rendered_edgeprofile(); + translate([ 50, -50, 0 ]) rotate(270, [0, 0, 1]) rendered_edgeprofile(); + } +} + +mycube(); +translate([110,0,0]) rendered_mycube(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6c8e24b..e0f2403 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -229,7 +229,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/disable-modifier.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-nested-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection_for-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection_for-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/render-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/render-tests-expected.png b/tests/regression/cgalpngtest/render-tests-expected.png new file mode 100644 index 0000000..8087794 Binary files /dev/null and b/tests/regression/cgalpngtest/render-tests-expected.png differ -- cgit v0.10.1 From a1e36876a57c9235c4fb808f65bac0652361d4d4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 18:28:23 +0200 Subject: Killed some warnings diff --git a/src/value.cc b/src/value.cc index 740cb3d..34566bd 100644 --- a/src/value.cc +++ b/src/value.cc @@ -36,7 +36,7 @@ Value::Value() Value::~Value() { - for (int i = 0; i < this->vec.size(); i++) delete this->vec[i]; + for (size_t i = 0; i < this->vec.size(); i++) delete this->vec[i]; this->vec.clear(); } @@ -72,7 +72,7 @@ Value& Value::operator = (const Value &v) this->type = v.type; this->b = v.b; this->num = v.num; - for (int i = 0; i < v.vec.size(); i++) { + for (size_t i = 0; i < v.vec.size(); i++) { this->vec.push_back(new Value(*v.vec[i])); } this->range_begin = v.range_begin; @@ -111,7 +111,7 @@ Value Value::operator + (const Value &v) const if (this->type == VECTOR && v.type == VECTOR) { Value r; r.type = VECTOR; - for (int i = 0; i < this->vec.size() && i < v.vec.size(); i++) + for (size_t i = 0; i < this->vec.size() && i < v.vec.size(); i++) r.vec.push_back(new Value(*this->vec[i] + *v.vec[i])); return r; } @@ -126,7 +126,7 @@ Value Value::operator - (const Value &v) const if (this->type == VECTOR && v.type == VECTOR) { Value r; r.type = VECTOR; - for (int i = 0; i < this->vec.size() && i < v.vec.size(); i++) + for (size_t i = 0; i < this->vec.size() && i < v.vec.size(); i++) r.vec.push_back(new Value(*this->vec[i] - *v.vec[i])); return r; } @@ -141,14 +141,14 @@ Value Value::operator * (const Value &v) const if (this->type == VECTOR && v.type == NUMBER) { Value r; r.type = VECTOR; - for (int i = 0; i < this->vec.size(); i++) + for (size_t i = 0; i < this->vec.size(); i++) r.vec.push_back(new Value(*this->vec[i] * v)); return r; } if (this->type == NUMBER && v.type == VECTOR) { Value r; r.type = VECTOR; - for (int i = 0; i < v.vec.size(); i++) + for (size_t i = 0; i < v.vec.size(); i++) r.vec.push_back(new Value(*this * *v.vec[i])); return r; } @@ -163,14 +163,14 @@ Value Value::operator / (const Value &v) const if (this->type == VECTOR && v.type == NUMBER) { Value r; r.type = VECTOR; - for (int i = 0; i < this->vec.size(); i++) + for (size_t i = 0; i < this->vec.size(); i++) r.vec.push_back(new Value(*this->vec[i] / v)); return r; } if (this->type == NUMBER && v.type == VECTOR) { Value r; r.type = VECTOR; - for (int i = 0; i < v.vec.size(); i++) + for (size_t i = 0; i < v.vec.size(); i++) r.vec.push_back(new Value(v / *v.vec[i])); return r; } @@ -218,7 +218,7 @@ Value Value::operator == (const Value &v) const if (this->type == VECTOR && v.type == VECTOR) { if (this->vec.size() != v.vec.size()) return Value(false); - for (int i=0; ivec.size(); i++) + for (size_t i=0; ivec.size(); i++) if (!(*this->vec[i] == *v.vec[i]).b) return Value(false); return Value(true); @@ -256,7 +256,7 @@ Value Value::inv() const if (this->type == VECTOR) { Value r; r.type = VECTOR; - for (int i = 0; i < this->vec.size(); i++) + for (size_t i = 0; i < this->vec.size(); i++) r.vec.push_back(new Value(this->vec[i]->inv())); return r; } @@ -314,7 +314,7 @@ void Value::reset_undef() this->type = UNDEFINED; this->b = false; this->num = 0; - for (int i = 0; i < this->vec.size(); i++) delete this->vec[i]; + for (size_t i = 0; i < this->vec.size(); i++) delete this->vec[i]; this->vec.clear(); this->range_begin = 0; this->range_step = 0; @@ -333,7 +333,7 @@ std::string Value::toString() const break; case VECTOR: stream << '['; - for (int i = 0; i < this->vec.size(); i++) { + for (size_t i = 0; i < this->vec.size(); i++) { if (i > 0) stream << ", "; stream << *(this->vec[i]); } -- cgit v0.10.1 From 3b16fdafd2235e8bcaec0c2be06949f61bc4047d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 18:31:05 +0200 Subject: added some debug output diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index ebcfdd3..72f7488 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -155,9 +155,8 @@ int main(int argc, char *argv[]) return 1; } - csgInfo.root_norm_term = root_raw_term->link(); - // CSG normalization + csgInfo.root_norm_term = root_raw_term->link(); while (1) { CSGTerm *n = csgInfo.root_norm_term->normalize(); csgInfo.root_norm_term->unlink(); @@ -170,6 +169,7 @@ int main(int argc, char *argv[]) csgInfo.root_chain = new CSGChain(); csgInfo.root_chain->import(csgInfo.root_norm_term); + fprintf(stderr, "Normalized CSG tree has %d elements\n", csgInfo.root_chain->polysets.size()); if (csgInfo.highlight_terms.size() > 0) { cerr << "Compiling highlights (" << csgInfo.highlight_terms.size() << " CSG Trees)...\n"; -- cgit v0.10.1 From 0e7c6473fa6541fee741d0019ba498747fd6e364 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 18:31:22 +0200 Subject: Implemented render() diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index b59f4db..f280b2b 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -178,9 +178,18 @@ Response CSGTermEvaluator::visit(State &state, const ColorNode &node) // FIXME: If we've got CGAL support, render this node as a CGAL union into a PolySet Response CSGTermEvaluator::visit(State &state, const RenderNode &node) { - PRINT("WARNING: render() statement not implemented"); if (state.isPostfix()) { - applyToChildren(node, CSGT_UNION); + CSGTerm *t1 = NULL; + // FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this. + PolySet *ps = NULL; + if (this->psevaluator) { + ps = this->psevaluator->evaluatePolySet(node, AbstractPolyNode::RENDER_OPENCSG); + } + if (ps) { + t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, + ps, node.modinst, node); + } + this->stored_term[node.index()] = t1; addToParent(state, node); } return ContinueTraversal; diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index c42d806..c7ce979 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -6,6 +6,7 @@ #include "dxflinextrudenode.h" #include "dxfrotextrudenode.h" #include "cgaladvnode.h" +#include "rendernode.h" #include "dxfdata.h" #include "dxftess.h" #include "module.h" @@ -376,6 +377,13 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node, Abstract return ps; } +PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node, AbstractPolyNode::render_mode_e) +{ + CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node); + PolySet *ps = NULL; + if (!N.empty()) ps = N.convertToPolyset(); + return ps; +} PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, DxfData &dxf) { diff --git a/src/PolySetCGALEvaluator.h b/src/PolySetCGALEvaluator.h index cf3c5b2..f5b8665 100644 --- a/src/PolySetCGALEvaluator.h +++ b/src/PolySetCGALEvaluator.h @@ -17,6 +17,7 @@ public: virtual PolySet *evaluatePolySet(const DxfLinearExtrudeNode &node, AbstractPolyNode::render_mode_e); virtual PolySet *evaluatePolySet(const DxfRotateExtrudeNode &node, AbstractPolyNode::render_mode_e); virtual PolySet *evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e); + virtual PolySet *evaluatePolySet(const RenderNode &node, AbstractPolyNode::render_mode_e); protected: PolySet *extrudeDxfData(const DxfLinearExtrudeNode &node, class DxfData &dxf); diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h index 9a72ff7..70ec7ed 100644 --- a/src/PolySetEvaluator.h +++ b/src/PolySetEvaluator.h @@ -17,6 +17,7 @@ public: virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; virtual PolySet *evaluatePolySet(const class DxfRotateExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; virtual PolySet *evaluatePolySet(const class CgaladvNode &, AbstractPolyNode::render_mode_e) = 0; + virtual PolySet *evaluatePolySet(const class RenderNode &, AbstractPolyNode::render_mode_e) = 0; void clearCache() { this->cache.clear(); -- cgit v0.10.1 From 98b0c637a8e377c07763fa1dbc5245bb3452cc68 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 18:32:32 +0200 Subject: OpenCSG version of render-tests now also works diff --git a/tests/regression/opencsgtest/render-tests-expected.png b/tests/regression/opencsgtest/render-tests-expected.png new file mode 100644 index 0000000..40a1703 Binary files /dev/null and b/tests/regression/opencsgtest/render-tests-expected.png differ -- cgit v0.10.1 From 7d1ea6240d7ba950f596a317f1dba47a73aaad18 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 20:36:45 +0200 Subject: Added projection-tests diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e0f2403..41fd0cd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -230,7 +230,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-nested-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection_for-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/render-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/render-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/projection-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/projection-tests-expected.png b/tests/regression/cgalpngtest/projection-tests-expected.png new file mode 100644 index 0000000..800f7ba Binary files /dev/null and b/tests/regression/cgalpngtest/projection-tests-expected.png differ diff --git a/tests/regression/opencsgtest/projection-tests-expected.png b/tests/regression/opencsgtest/projection-tests-expected.png new file mode 100644 index 0000000..8239d3d Binary files /dev/null and b/tests/regression/opencsgtest/projection-tests-expected.png differ -- cgit v0.10.1 From cd6299922d7a79ab8306ed15782b6fa5b0c34c36 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 20:37:07 +0200 Subject: projection() now works diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 89a9e6b..a63d271 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -211,6 +211,7 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) if (state.isPostfix()) { if (!isCached(node)) { // First union all children + // FIXME: What does this actually achieve? kintel 20110906 applyToChildren(node, CGE_UNION); // Then apply polyset operation diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index c7ce979..3a7efdb 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -20,7 +20,14 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr const string &cacheid = this->cgalevaluator.getTree().getString(node); if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps->link(); - CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node); + // Before projecting, union all children + CGAL_Nef_polyhedron sum; + BOOST_FOREACH (AbstractNode * v, node.getChildren()) { + if (v->modinst->tag_background) continue; + CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); + if (sum.empty()) sum = N.copy(); + else sum += N; + } PolySet *ps = new PolySet(); ps->convexity = node.convexity; @@ -71,13 +78,13 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr cube->unlink(); // N.p3 *= CGAL_Nef_polyhedron3(CGAL_Plane(0, 0, 1, 0), CGAL_Nef_polyhedron3::INCLUDED); - N *= Ncube; - if (!N.p3->is_simple()) { + sum *= Ncube; + if (!sum.p3->is_simple()) { PRINTF("WARNING: Body of projection(cut = true) isn't valid 2-manifold! Modify your design.."); goto cant_project_non_simple_polyhedron; } - PolySet *ps3 = N.convertToPolyset(); + PolySet *ps3 = sum.convertToPolyset(); Grid2d conversion_grid(GRID_COARSE); for (size_t i = 0; i < ps3->polygons.size(); i++) { for (size_t j = 0; j < ps3->polygons[i].size(); j++) { @@ -103,12 +110,12 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr } else { - if (!N.p3->is_simple()) { + if (!sum.p3->is_simple()) { PRINTF("WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your design.."); goto cant_project_non_simple_polyhedron; } - PolySet *ps3 = N.convertToPolyset(); + PolySet *ps3 = sum.convertToPolyset(); CGAL_Nef_polyhedron np; for (size_t i = 0; i < ps3->polygons.size(); i++) { -- cgit v0.10.1 From a93e6449804e75e351ac46a84ceff8f034ddd25d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 22:01:42 +0200 Subject: Added hull tests diff --git a/testdata/scad/features/hull-tests.scad b/testdata/scad/features/hull-tests.scad deleted file mode 100644 index 3114ac5..0000000 --- a/testdata/scad/features/hull-tests.scad +++ /dev/null @@ -1,43 +0,0 @@ -// Works correctly -module convex2dSimple() { - hull() { - translate([15,10]) circle(10); - circle(10); - } -} - -// Works correctly -module convex2dHole() { - hull() { - translate([15,10,0]) circle(10); - difference() { - circle(10); - circle(5); - } - } -} - -// 3d not currently implemented -module convex3dSimple() { - hull() { - translate([15,10]) cylinder(r=10); - cylinder(r=10); - } -} - -// 3d not currently implemented -module convex3dHole() { - hull() { - translate([15,10,0]) cylinder(10); - difference() { - cylinder(10); - cylinder(5); - } - } -} - - -convex2dHole(); -translate([40,0,0]) convex2dSimple(); -translate([0,40,0]) convex3dHole(); -translate([40,40,0]) convex3dSimple(); diff --git a/testdata/scad/features/hull2-tests.scad b/testdata/scad/features/hull2-tests.scad new file mode 100644 index 0000000..3bea3c5 --- /dev/null +++ b/testdata/scad/features/hull2-tests.scad @@ -0,0 +1,30 @@ +module convex2dSimple() { + hull() { + translate([15,10]) circle(10); + circle(10); + } +} + +module concave2dSimple() { + hull() { + translate([15,10]) square(2); + translate([15,0]) square(2); + square(2); + } +} + +// Works correctly +module convex2dHole() { + hull() { + translate([15,10,0]) circle(10); + difference() { + circle(10); + circle(5); + } + } +} + + +convex2dHole(); +translate([40,0,0]) convex2dSimple(); +translate([0,-20,0]) concave2dSimple(); diff --git a/testdata/scad/features/hull3-tests.scad b/testdata/scad/features/hull3-tests.scad new file mode 100644 index 0000000..a3e7d92 --- /dev/null +++ b/testdata/scad/features/hull3-tests.scad @@ -0,0 +1,21 @@ +// 3d not currently implemented +module convex3dSimple() { + hull() { + translate([15,10]) cylinder(r=10); + cylinder(r=10); + } +} + +// 3d not currently implemented +module convex3dHole() { + hull() { + translate([15,10,0]) cylinder(10); + difference() { + cylinder(10); + cylinder(5); + } + } +} + +translate([0,40,0]) convex3dHole(); +translate([40,40,0]) convex3dSimple(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 41fd0cd..b0aa6ed 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -144,7 +144,7 @@ include_directories(${CGAL_INCLUDE_DIRS}) # add_executable(cgaltest cgaltest.cc ../src/CGAL_Nef_polyhedron.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc - ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc + ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) set_target_properties(cgaltest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARY}) @@ -156,7 +156,7 @@ add_executable(cgalpngtest cgalpngtest.cc OffscreenView.cc OffscreenContext.mm ../src/CGALRenderer.cc ../src/CGAL_Nef_polyhedron.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc - ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc + ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) set_target_properties(cgalpngtest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") target_link_libraries(cgalpngtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY}) @@ -168,7 +168,7 @@ add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc - ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc + ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) set_target_properties(opencsgtest PROPERTIES COMPILE_FLAGS "-DENABLE_OPENCSG -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") target_link_libraries(opencsgtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENCSG_LIBRARY} ${GLEW_LIBRARY} ${COCOA_LIBRARY} ${OPENGL_LIBRARY}) @@ -219,6 +219,7 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/rotate_extrude-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/minkowski2-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/minkowski3-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/hull2-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/surface-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/import_dxf-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/transform-tests.scad diff --git a/tests/regression/cgalpngtest/hull2-tests-expected.png b/tests/regression/cgalpngtest/hull2-tests-expected.png new file mode 100644 index 0000000..256b349 Binary files /dev/null and b/tests/regression/cgalpngtest/hull2-tests-expected.png differ diff --git a/tests/regression/opencsgtest/hull2-tests-expected.png b/tests/regression/opencsgtest/hull2-tests-expected.png new file mode 100644 index 0000000..66ee6b2 Binary files /dev/null and b/tests/regression/opencsgtest/hull2-tests-expected.png differ -- cgit v0.10.1 From a653b0c60494f9490301579ac9081858ce848f01 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 22:03:52 +0200 Subject: Implemented 2D hull diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index a63d271..0d46cd9 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -63,12 +63,6 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr case CGE_MINKOWSKI: target.minkowski(src); break; - case CGE_HULL: - //FIXME: Port convex hull to a binary operator or process it all in the end somehow - // target.p2 = convexhull2(target.p2, src.p2); - // target.p2 = convexhull2(polys); - // FIXME: Print warning: hull() not supported in 3D - break; } } @@ -100,6 +94,40 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg this->cache.insert(cacheid, N); } +extern CGAL_Nef_polyhedron2 *convexhull2(std::list a); + +void CGALEvaluator::applyHull(const CgaladvNode &node) +{ + if (this->visitedchildren[node.index()].size() > 0) { + std::list polys; + bool all2d = true; + for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin(); + iter != this->visitedchildren[node.index()].end(); + iter++) { + const AbstractNode *chnode = iter->first; + const string &chcacheid = iter->second; + // FIXME: Don't use deep access to modinst members + if (chnode->modinst->tag_background) continue; + assert(isCached(*chnode)); + const CGAL_Nef_polyhedron &ch = this->cache[chcacheid]; + if (ch.dim == 2) { + polys.push_back(ch.p2); + } + else if (ch.dim == 3) { + PRINT("WARNING: hull() is not implemented yet for 3D objects!"); + all2d = false; + } + chnode->progress_report(); + } + + if (all2d) { + CGAL_Nef_polyhedron N(convexhull2(polys)); + const std::string &cacheid = this->tree.getString(node); + this->cache.insert(cacheid, N); + } + } +} + /* Typical visitor behavior: o In prefix: Check if we're cached -> prune @@ -246,17 +274,20 @@ Response CGALEvaluator::visit(State &state, const CgaladvNode &node) switch (node.type) { case MINKOWSKI: op = CGE_MINKOWSKI; + applyToChildren(node, op); break; case GLIDE: + PRINT("WARNING: glide() is not implemented yet!"); + return PruneTraversal; + break; case SUBDIV: - // FIXME: Not implemented + PRINT("WARNING: subdiv() is not implemented yet!"); return PruneTraversal; break; case HULL: - op = CGE_HULL; + applyHull(node); break; } - applyToChildren(node, op); } addToParent(state, node); } diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index a985065..2453c25 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -19,7 +19,7 @@ using std::pair; class CGALEvaluator : public Visitor { public: - enum CsgOp {CGE_UNION, CGE_INTERSECTION, CGE_DIFFERENCE, CGE_MINKOWSKI, CGE_HULL}; + enum CsgOp {CGE_UNION, CGE_INTERSECTION, CGE_DIFFERENCE, CGE_MINKOWSKI}; // FIXME: If a cache is not given, we need to fix this ourselves CGALEvaluator(QHash &cache, const Tree &tree) : cache(cache), tree(tree), psevaluator(*this) {} virtual ~CGALEvaluator() {} @@ -41,6 +41,7 @@ private: bool isCached(const AbstractNode &node) const; void process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, CGALEvaluator::CsgOp op); void applyToChildren(const AbstractNode &node, CGALEvaluator::CsgOp op); + void applyHull(const CgaladvNode &node); string currindent; typedef list > ChildList; diff --git a/src/cgaladv_convexhull2.cc b/src/cgaladv_convexhull2.cc index 448dd4b..492df3c 100644 --- a/src/cgaladv_convexhull2.cc +++ b/src/cgaladv_convexhull2.cc @@ -29,16 +29,15 @@ #include "cgal.h" #include -extern CGAL_Nef_polyhedron2 convexhull2(std::list a); extern CGAL_Poly2 nef2p2(CGAL_Nef_polyhedron2 p); -CGAL_Nef_polyhedron2 convexhull2(std::list a) +CGAL_Nef_polyhedron2 *convexhull2(std::list a) { std::list points; - std::list::iterator i; + std::list::iterator i; for (i=a.begin(); i!=a.end(); i++) { - CGAL_Poly2 ap=nef2p2(*i); + CGAL_Poly2 ap=nef2p2(**i); for (size_t j=0;j a) std::list result; CGAL::convex_hull_2(points.begin(),points.end(),std::back_inserter(result)); - return CGAL_Nef_polyhedron2(result.begin(),result.end(),CGAL_Nef_polyhedron2::INCLUDED); + return new CGAL_Nef_polyhedron2(result.begin(),result.end(),CGAL_Nef_polyhedron2::INCLUDED); } #endif -- cgit v0.10.1 From f9b026a2f0bb3c0a59b430c651e6c9151af3826d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 6 Sep 2011 23:59:08 +0200 Subject: bugfix: fixed crash bugs on empty or 3D child list of linear_extrude() and rotate_extrude() diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 3a7efdb..50dc358 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -264,10 +264,16 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, BOOST_FOREACH (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); - if (sum.empty()) sum = N.copy(); - else sum += N; + if (N.dim != 2) { + PRINT("ERROR: rotate_extrude() is not defined for 3D child objects!"); + } + else { + if (sum.empty()) sum = N.copy(); + else sum += N; + } } + if (sum.empty()) return NULL; dxf = sum.convertToDxfData();; } else { dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); @@ -361,10 +367,16 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, BOOST_FOREACH (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); - if (sum.empty()) sum = N.copy(); - else sum += N; + if (N.dim != 2) { + PRINT("ERROR: rotate_extrude() is not defined for 3D child objects!"); + } + else { + if (sum.empty()) sum = N.copy(); + else sum += N; + } } + if (sum.empty()) return NULL; dxf = sum.convertToDxfData(); } else { dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale); -- cgit v0.10.1 From ac01975b02055c6e66bb8c9d97f0d9bc876913b5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 00:10:21 +0200 Subject: bugfix: fixed crash bugs on empty projection() diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 50dc358..1ac053f 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -28,6 +28,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr if (sum.empty()) sum = N.copy(); else sum += N; } + if (sum.empty()) return NULL; PolySet *ps = new PolySet(); ps->convexity = node.convexity; -- cgit v0.10.1 From 29adaed02441832ce54d0f232f5ecb43eb28355d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 00:11:00 +0200 Subject: Deprecated dxf_linear_extrude(), dxf_rotate_extrude() and the file parameters to linear_extrude() and rotate_extrude() diff --git a/src/context.cc b/src/context.cc index 9722428..0100234 100644 --- a/src/context.cc +++ b/src/context.cc @@ -28,6 +28,7 @@ #include "expression.h" #include "function.h" #include "module.h" +#include "builtin.h" #include "printutils.h" #include #include @@ -147,8 +148,16 @@ Value Context::evaluate_function(const std::string &name, AbstractNode *Context::evaluate_module(const ModuleInstantiation &inst) const { - if (this->modules_p && this->modules_p->find(inst.modname) != this->modules_p->end()) - return this->modules_p->find(inst.modname)->second->evaluate(this, &inst); + if (this->modules_p && this->modules_p->find(inst.modname) != this->modules_p->end()) { + AbstractModule *m = this->modules_p->find(inst.modname)->second; + if (m == builtin_modules["dxf_linear_extrude"]) { + PRINTF("DEPRECATED: The dxf_linear_extrude() module will be removed in future releases. Use a linear_extrude() instead."); + } + if (m == builtin_modules["dxf_rotate_extrude"]) { + PRINTF("DEPRECATED: The dxf_rotate_extrude() module will be removed in future releases. Use a rotate_extrude() instead."); + } + return m->evaluate(this, &inst); + } if (this->usedlibs_p) { BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) { if (m.second->modules.find(inst.modname) != m.second->modules.end()) { diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index 14d69c4..fd37ffa 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -76,8 +76,10 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI Value twist = c.lookup_variable("twist", true); Value slices = c.lookup_variable("slices", true); - if (!file.text.empty()) + if (!file.text.empty()) { + PRINTF("DEPRECATED: Support for reading files in linear_extrude will be removed in future releases. Use a child import() instead."); node->filename = c.getAbsolutePath(file.text); + } node->layername = layer.text; node->height = height.num; diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index 338a73e..5889cee 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -70,8 +70,10 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI Value origin = c.lookup_variable("origin", true); Value scale = c.lookup_variable("scale", true); - if (!file.text.empty()) + if (!file.text.empty()) { + PRINTF("DEPRECATED: Support for reading files in rotate_extrude will be removed in future releases. Use a child import() instead."); node->filename = c.getAbsolutePath(file.text); + } node->layername = layer.text; node->convexity = (int)convexity.num; -- cgit v0.10.1 From 820a886fac9cdfa669e4ca2d19bc2b1933668775 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 00:13:03 +0200 Subject: deprecations diff --git a/RELEASE_NOTES b/RELEASE_NOTES index a95d588..1c98940 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -5,6 +5,12 @@ Bugfixes: o square() crashed if any of the dimensions were zero o Flush Caches didn't flush cached USE'd modules +Deprecations: +o dxf_linear_extrude() and dxf_rotate_extrude() are now deprecated. + Use linear_extrude() and rotate_extrude() instead. +o The file, layer, origin and scale parameters to linear_extrude() and rotate_extrude() + are now deprecated. Use an import() child instead. + OpenSCAD 2011.06 ================ -- cgit v0.10.1 From 9ec9111dcbac7414e503a8a3d01cfb66ce7184c9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 00:47:01 +0200 Subject: Fixed another projection() crash bug; only 3D children diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 1ac053f..ff02359 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -29,6 +29,10 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr else sum += N; } if (sum.empty()) return NULL; + if (sum.dim != 2) { + PRINTF("WARNING: Body of projection() must be a 3D object"); + return NULL; + } PolySet *ps = new PolySet(); ps->convexity = node.convexity; -- cgit v0.10.1 From f40f7ef072927cd9ea18104e66217c31cfd810db Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 00:47:55 +0200 Subject: Added support for an untyped import() module, deprecating the explicitly typed import_*() ones diff --git a/src/context.cc b/src/context.cc index 0100234..b4983f6 100644 --- a/src/context.cc +++ b/src/context.cc @@ -153,9 +153,18 @@ AbstractNode *Context::evaluate_module(const ModuleInstantiation &inst) const if (m == builtin_modules["dxf_linear_extrude"]) { PRINTF("DEPRECATED: The dxf_linear_extrude() module will be removed in future releases. Use a linear_extrude() instead."); } - if (m == builtin_modules["dxf_rotate_extrude"]) { + else if (m == builtin_modules["dxf_rotate_extrude"]) { PRINTF("DEPRECATED: The dxf_rotate_extrude() module will be removed in future releases. Use a rotate_extrude() instead."); } + else if (m == builtin_modules["import_stl"]) { + PRINTF("DEPRECATED: The import_stl() module will be removed in future releases. Use import() instead."); + } + else if (m == builtin_modules["import_dxf"]) { + PRINTF("DEPRECATED: The import_dxf() module will be removed in future releases. Use import() instead."); + } + else if (m == builtin_modules["import_off"]) { + PRINTF("DEPRECATED: The import_off() module will be removed in future releases. Use import() instead."); + } return m->evaluate(this, &inst); } if (this->usedlibs_p) { diff --git a/src/import.cc b/src/import.cc index 447c139..17ad3f2 100644 --- a/src/import.cc +++ b/src/import.cc @@ -49,20 +49,14 @@ class ImportModule : public AbstractModule { public: import_type_e type; - ImportModule(import_type_e type) : type(type) { } + ImportModule(import_type_e type = TYPE_UNKNOWN) : type(type) { } virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; }; AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const { - ImportNode *node = new ImportNode(inst, type); - std::vector argnames; - if (this->type == TYPE_DXF) { - argnames += "file", "layer", "convexity", "origin", "scale"; - } else { - argnames += "file", "convexity"; - } + argnames += "file", "layer", "convexity", "origin", "scale"; std::vector argexpr; // Map old argnames to new argnames for compatibility @@ -77,13 +71,23 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati Context c(ctx); c.args(argnames, argexpr, inst_argnames, inst->argvalues); + Value v = c.lookup_variable("file"); + std::string filename = c.getAbsolutePath(v.text); + import_type_e actualtype = this->type; + if (actualtype == TYPE_UNKNOWN) { + QFileInfo fi(QString::fromStdString(filename)); + if (fi.suffix().toLower() == "stl") actualtype = TYPE_STL; + else if (fi.suffix().toLower() == "off") actualtype = TYPE_OFF; + else if (fi.suffix().toLower() == "dxf") actualtype = TYPE_DXF; + } + + ImportNode *node = new ImportNode(inst, actualtype); + node->fn = c.lookup_variable("$fn").num; node->fs = c.lookup_variable("$fs").num; node->fa = c.lookup_variable("$fa").num; - Value v = c.lookup_variable("file"); - node->filename = c.getAbsolutePath(v.text); -// node->filename = c.getAbsolutePath(c.lookup_variable("file").text); + node->filename = filename; node->layername = c.lookup_variable("layer", true).text; node->convexity = c.lookup_variable("convexity", true).num; @@ -102,13 +106,6 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati return node; } -void register_builtin_import() -{ - builtin_modules["import_stl"] = new ImportModule(TYPE_STL); - builtin_modules["import_off"] = new ImportModule(TYPE_OFF); - builtin_modules["import_dxf"] = new ImportModule(TYPE_DXF); -} - PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const { PolySet *p = new PolySet(); @@ -191,18 +188,22 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c } } - if (this->type == TYPE_OFF) + else if (this->type == TYPE_OFF) { PRINTF("WARNING: OFF import is not implemented yet."); } - if (this->type == TYPE_DXF) + else if (this->type == TYPE_DXF) { DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale); p->is2d = true; dxf_tesselate(p, dd, 0, true, false, 0); dxf_border_to_ps(p, dd); } + else + { + PRINTF("ERROR: Unsupported file format while trying to import file '%s'", this->filename.c_str()); + } return p; } @@ -217,46 +218,27 @@ std::string ImportNode::toString() const stat(this->filename.c_str(), &st); stream << this->name(); - switch (this->type) { - case TYPE_STL: - stream << "(file = \"" << this->filename << "\", " - "cache = \"" << std::hex << (int)st.st_mtime << "." << (int)st.st_size << "\", " - "convexity = " << std::dec << this->convexity << ")"; - break; - case TYPE_OFF: - stream << "(file = \"" << this->filename << "\", " - "cache = \"" << std::hex << (int)st.st_mtime << "." << (int)st.st_size << "\", " - "convexity = " << std::dec << this->convexity << ")"; - break; - case TYPE_DXF: - stream << "(file = \"" << this->filename << "\", " - "cache = \"" << std::hex << (int)st.st_mtime << "." << (int)st.st_size << "\", " - "layer = \"" << this->layername << "\", " - "origin = [ " << std::dec << this->origin_x << " " << this->origin_y << " ], " - "scale = " << this->scale << ", " - "convexity = " << this->convexity << ", " - "$fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs << ")"; - break; - default: - assert(false); - } + stream << "(file = \"" << this->filename << "\", " + "cache = \"" << std::hex << (int)st.st_mtime << "." << (int)st.st_size << "\", " + "layer = \"" << this->layername << "\", " + "origin = [ " << std::dec << this->origin_x << " " << this->origin_y << " ], " + "scale = " << this->scale << ", " + "convexity = " << this->convexity << ", " + "$fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs << ")"; return stream.str(); } std::string ImportNode::name() const { - switch (this->type) { - case TYPE_STL: - return "import_stl"; - break; - case TYPE_OFF: - return "import_off"; - break; - case TYPE_DXF: - return "import_dxf"; - break; - default: - assert(false); - } + return "import"; } + +void register_builtin_import() +{ + builtin_modules["import_stl"] = new ImportModule(TYPE_STL); + builtin_modules["import_off"] = new ImportModule(TYPE_OFF); + builtin_modules["import_dxf"] = new ImportModule(TYPE_DXF); + builtin_modules["import"] = new ImportModule(); +} + diff --git a/src/importnode.h b/src/importnode.h index 3fcdb37..49e9f16 100644 --- a/src/importnode.h +++ b/src/importnode.h @@ -5,6 +5,7 @@ #include "visitor.h" enum import_type_e { + TYPE_UNKNOWN, TYPE_STL, TYPE_OFF, TYPE_DXF -- cgit v0.10.1 From 7213166c08e67a1251a2820cf0c2aed32648c824 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 00:48:38 +0200 Subject: deprecations diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 1c98940..5f529bb 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -10,6 +10,7 @@ o dxf_linear_extrude() and dxf_rotate_extrude() are now deprecated. Use linear_extrude() and rotate_extrude() instead. o The file, layer, origin and scale parameters to linear_extrude() and rotate_extrude() are now deprecated. Use an import() child instead. +o import_dxf(), import_stl() and import_off() are now deprecated. Use import() instead. OpenSCAD 2011.06 ================ -- cgit v0.10.1 From 23e153f51210fb0ac8dac168515b4186b252a653 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 00:48:57 +0200 Subject: Added some corner cases diff --git a/testdata/scad/features/color-tests.scad b/testdata/scad/features/color-tests.scad index 67d65d0..3ef2540 100644 --- a/testdata/scad/features/color-tests.scad +++ b/testdata/scad/features/color-tests.scad @@ -1,3 +1,8 @@ +// Empty +color(); +// No children +color() { } + module object() cube([10,10,10]); translate([12,12,0]) object(); diff --git a/testdata/scad/features/difference-tests.scad b/testdata/scad/features/difference-tests.scad index cc508a5..4d82676 100644 --- a/testdata/scad/features/difference-tests.scad +++ b/testdata/scad/features/difference-tests.scad @@ -1,3 +1,8 @@ +// Empty +difference(); +// No children +difference() { } + difference() { cube([10,10,10], center=true); cylinder(r=4, h=20, center=true); diff --git a/testdata/scad/features/for-tests.scad b/testdata/scad/features/for-tests.scad index 2434d1d..fe36789 100644 --- a/testdata/scad/features/for-tests.scad +++ b/testdata/scad/features/for-tests.scad @@ -1,3 +1,8 @@ +// Empty +for(); +// No children +for(i=2) { } + // Null translate([-10,0,0]) for() cylinder(r=4); diff --git a/testdata/scad/features/hull3-tests.scad b/testdata/scad/features/hull3-tests.scad index a3e7d92..2bd7d73 100644 --- a/testdata/scad/features/hull3-tests.scad +++ b/testdata/scad/features/hull3-tests.scad @@ -19,3 +19,9 @@ module convex3dHole() { translate([0,40,0]) convex3dHole(); translate([40,40,0]) convex3dSimple(); + +// Empty +hull(); +// No children +hull() { } + diff --git a/testdata/scad/features/intersection-tests.scad b/testdata/scad/features/intersection-tests.scad index f673b35..e53f3c9 100644 --- a/testdata/scad/features/intersection-tests.scad +++ b/testdata/scad/features/intersection-tests.scad @@ -1,3 +1,9 @@ +// Empty +intersection(); + +// No children +intersection() { } + intersection() { sphere(r=5); translate([0,0,3]) cube([4,4,6], center=true); diff --git a/testdata/scad/features/intersection_for-tests.scad b/testdata/scad/features/intersection_for-tests.scad index ad058ac..6ab1a89 100644 --- a/testdata/scad/features/intersection_for-tests.scad +++ b/testdata/scad/features/intersection_for-tests.scad @@ -1,3 +1,8 @@ +// Empty +intersection_for(); +// No children +intersection_for(i=1) { } + intersection_for(i = [[0, 0, 0], [10, 20, 300], [200, 40, 57], diff --git a/testdata/scad/features/linear_extrude-tests.scad b/testdata/scad/features/linear_extrude-tests.scad index 7138e94..67de8e6 100644 --- a/testdata/scad/features/linear_extrude-tests.scad +++ b/testdata/scad/features/linear_extrude-tests.scad @@ -1,8 +1,13 @@ +// Empty +rotate_extrude(); +// No children +rotate_extrude() { } +// 3D child +rotate_extrude() { cube(); } + linear_extrude(height=10) square([10,10]); translate([19,5,0]) linear_extrude(height=10, center=true) difference() {circle(5); circle(3);} translate([31.5,2.5,0]) linear_extrude(height=10, twist=-45) polygon(points = [[-5,-2.5], [5,-2.5], [0,2.5]]); translate([0,20,0]) linear_extrude(height=20, twist=45, slices=2) square([10,10]); translate([19,20,0]) linear_extrude(height=20, twist=45, slices=10) square([10,10]); - -// FIXME: Test dxf version \ No newline at end of file diff --git a/testdata/scad/features/minkowski3-tests.scad b/testdata/scad/features/minkowski3-tests.scad index 0e53563..0451b57 100644 --- a/testdata/scad/features/minkowski3-tests.scad +++ b/testdata/scad/features/minkowski3-tests.scad @@ -28,3 +28,8 @@ module roundedBox3dHole() { translate([-20,30,0]) roundedBox3dHole(); translate([0,25,0]) roundedBox3dCut(); translate([25,25,0]) roundedBox3dSimple(); + +// Empty +minkowski(); +// No children +minkowski() { } diff --git a/testdata/scad/features/projection-tests.scad b/testdata/scad/features/projection-tests.scad index 619aa01..e1b05c7 100644 --- a/testdata/scad/features/projection-tests.scad +++ b/testdata/scad/features/projection-tests.scad @@ -1,3 +1,10 @@ +// Empty +projection(); +// No children +projection() { } +// 2D child +projection(cut=true) { square(); } + linear_extrude(height=20) projection(cut=false) sphere(r=10); translate([22,0,0]) linear_extrude(height=20) projection(cut=true) translate([0,0,9]) sphere(r=10); translate([44,0,0]) linear_extrude(height=20) projection(cut=true) translate([0,0,7]) sphere(r=10); diff --git a/testdata/scad/features/render-tests.scad b/testdata/scad/features/render-tests.scad index 56531c6..5fcb026 100644 --- a/testdata/scad/features/render-tests.scad +++ b/testdata/scad/features/render-tests.scad @@ -27,5 +27,10 @@ module rendered_mycube() { } } +// Empty +render(); +// No children +render() { } + mycube(); translate([110,0,0]) rendered_mycube(); diff --git a/testdata/scad/features/rotate_extrude-tests.scad b/testdata/scad/features/rotate_extrude-tests.scad index 32eaf34..347bc78 100644 --- a/testdata/scad/features/rotate_extrude-tests.scad +++ b/testdata/scad/features/rotate_extrude-tests.scad @@ -1,3 +1,10 @@ +// Empty +rotate_extrude(); +// No children +rotate_extrude() { } +// 3D child +rotate_extrude() { cube(); } + // Normal rotate_extrude() translate([20,0,0]) circle(r=10); diff --git a/testdata/scad/features/surface-tests.scad b/testdata/scad/features/surface-tests.scad index 98918d7..5a67293 100644 --- a/testdata/scad/features/surface-tests.scad +++ b/testdata/scad/features/surface-tests.scad @@ -1 +1,2 @@ +surface(); surface("surface.dat", center=true); -- cgit v0.10.1 From 8176b06fd05b6f6c800458e3baf326742ff52458 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 01:12:27 +0200 Subject: bugfix: typo in last commit diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index ff02359..6faecde 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -29,7 +29,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr else sum += N; } if (sum.empty()) return NULL; - if (sum.dim != 2) { + if (sum.dim != 3) { PRINTF("WARNING: Body of projection() must be a 3D object"); return NULL; } -- cgit v0.10.1 From a4ba8d44a4ddab66f7f71ba5029535dd7c9bbab0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 01:12:53 +0200 Subject: Modified test cases with new import() behavior diff --git a/testdata/scad/minimal/allmodules.scad b/testdata/scad/minimal/allmodules.scad index a940947..4395fd7 100644 --- a/testdata/scad/minimal/allmodules.scad +++ b/testdata/scad/minimal/allmodules.scad @@ -15,6 +15,7 @@ dxf_linear_extrude(); linear_extrude(); dxf_rotate_extrude(); rotate_extrude(); +import(); import_stl(); import_off(); import_dxf(); diff --git a/testdata/scad/minimal/import.scad b/testdata/scad/minimal/import.scad new file mode 100644 index 0000000..6f375fe --- /dev/null +++ b/testdata/scad/minimal/import.scad @@ -0,0 +1 @@ +import(); diff --git a/tests/regression/csgtermtest/allmodules-expected.txt b/tests/regression/csgtermtest/allmodules-expected.txt index fd366e0..c375c01 100644 --- a/tests/regression/csgtermtest/allmodules-expected.txt +++ b/tests/regression/csgtermtest/allmodules-expected.txt @@ -1 +1 @@ -(((((((((((((((linear_extrude14 + linear_extrude15) + rotate_extrude16) + rotate_extrude17) + import_stl18) + import_off19) + import_dxf20) + cube22) + sphere23) + cylinder24) + polyhedron25) + square26) + circle27) + polygon28) + projection29) + surface31) +((((((((((((((((linear_extrude14 + linear_extrude15) + rotate_extrude16) + rotate_extrude17) + import18) + import19) + import20) + import21) + cube23) + sphere24) + cylinder25) + polyhedron26) + square27) + circle28) + polygon29) + projection30) + surface32) diff --git a/tests/regression/csgtermtest/import-expected.txt b/tests/regression/csgtermtest/import-expected.txt new file mode 100644 index 0000000..847d6c3 --- /dev/null +++ b/tests/regression/csgtermtest/import-expected.txt @@ -0,0 +1 @@ +import2 diff --git a/tests/regression/csgtermtest/import_dxf-expected.txt b/tests/regression/csgtermtest/import_dxf-expected.txt index edf214d..847d6c3 100644 --- a/tests/regression/csgtermtest/import_dxf-expected.txt +++ b/tests/regression/csgtermtest/import_dxf-expected.txt @@ -1 +1 @@ -import_dxf2 +import2 diff --git a/tests/regression/csgtermtest/import_off-expected.txt b/tests/regression/csgtermtest/import_off-expected.txt index a8c4d8f..847d6c3 100644 --- a/tests/regression/csgtermtest/import_off-expected.txt +++ b/tests/regression/csgtermtest/import_off-expected.txt @@ -1 +1 @@ -import_off2 +import2 diff --git a/tests/regression/csgtermtest/import_stl-expected.txt b/tests/regression/csgtermtest/import_stl-expected.txt index fe69d31..847d6c3 100644 --- a/tests/regression/csgtermtest/import_stl-expected.txt +++ b/tests/regression/csgtermtest/import_stl-expected.txt @@ -1 +1 @@ -import_stl2 +import2 diff --git a/tests/regression/csgtexttest/allmodules-expected.txt b/tests/regression/csgtexttest/allmodules-expected.txt index 2595e02..34fa5ae 100644 --- a/tests/regression/csgtexttest/allmodules-expected.txt +++ b/tests/regression/csgtexttest/allmodules-expected.txt @@ -1 +1 @@ -group1(minkowski2+glide3+subdiv4+hull5+group6+group6+group6+intersection_for9+group6+union11+difference12+intersection13+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import_stl+import_off+import_dxf+group6+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render30+surface+transform32+transform32+transform34+transform32+transform32+color37) +group1(minkowski2+glide3+subdiv4+hull5+group6+group6+group6+intersection_for9+group6+union11+difference12+intersection13+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import+import+import+import+group6+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render31+surface+transform33+transform33+transform35+transform33+transform33+color38) diff --git a/tests/regression/csgtexttest/import-expected.txt b/tests/regression/csgtexttest/import-expected.txt new file mode 100644 index 0000000..a673ddb --- /dev/null +++ b/tests/regression/csgtexttest/import-expected.txt @@ -0,0 +1 @@ +group1(import) diff --git a/tests/regression/csgtexttest/import_dxf-expected.txt b/tests/regression/csgtexttest/import_dxf-expected.txt index ffb96fc..a673ddb 100644 --- a/tests/regression/csgtexttest/import_dxf-expected.txt +++ b/tests/regression/csgtexttest/import_dxf-expected.txt @@ -1 +1 @@ -group1(import_dxf) +group1(import) diff --git a/tests/regression/csgtexttest/import_off-expected.txt b/tests/regression/csgtexttest/import_off-expected.txt index 8a3bafa..a673ddb 100644 --- a/tests/regression/csgtexttest/import_off-expected.txt +++ b/tests/regression/csgtexttest/import_off-expected.txt @@ -1 +1 @@ -group1(import_off) +group1(import) diff --git a/tests/regression/csgtexttest/import_stl-expected.txt b/tests/regression/csgtexttest/import_stl-expected.txt index 47c4707..a673ddb 100644 --- a/tests/regression/csgtexttest/import_stl-expected.txt +++ b/tests/regression/csgtexttest/import_stl-expected.txt @@ -1 +1 @@ -group1(import_stl) +group1(import) diff --git a/tests/regression/dumptest/allmodules-expected.txt b/tests/regression/dumptest/allmodules-expected.txt index 2849d7a..e708c43 100644 --- a/tests/regression/dumptest/allmodules-expected.txt +++ b/tests/regression/dumptest/allmodules-expected.txt @@ -15,9 +15,10 @@ group() { linear_extrude(file = "", cache = "0.0", layer = "", height = 100, origin = [ 0 0 ], scale = 1, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); rotate_extrude(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); rotate_extrude(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); - import_stl(file = "", cache = "0.0", convexity = 1); - import_off(file = "", cache = "0.0", convexity = 1); - import_dxf(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); group(); cube(size = [1, 1, 1], center = false); sphere($fn = 0, $fa = 12, $fs = 1, r = 1); diff --git a/tests/regression/dumptest/import-expected.txt b/tests/regression/dumptest/import-expected.txt new file mode 100644 index 0000000..b424afe --- /dev/null +++ b/tests/regression/dumptest/import-expected.txt @@ -0,0 +1,3 @@ +group() { + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); +} diff --git a/tests/regression/dumptest/import_dxf-expected.txt b/tests/regression/dumptest/import_dxf-expected.txt index 08238d2..b424afe 100644 --- a/tests/regression/dumptest/import_dxf-expected.txt +++ b/tests/regression/dumptest/import_dxf-expected.txt @@ -1,3 +1,3 @@ group() { - import_dxf(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); } diff --git a/tests/regression/dumptest/import_off-expected.txt b/tests/regression/dumptest/import_off-expected.txt index 51293c9..b424afe 100644 --- a/tests/regression/dumptest/import_off-expected.txt +++ b/tests/regression/dumptest/import_off-expected.txt @@ -1,3 +1,3 @@ group() { - import_off(file = "", cache = "0.0", convexity = 1); + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); } diff --git a/tests/regression/dumptest/import_stl-expected.txt b/tests/regression/dumptest/import_stl-expected.txt index 2da7d35..b424afe 100644 --- a/tests/regression/dumptest/import_stl-expected.txt +++ b/tests/regression/dumptest/import_stl-expected.txt @@ -1,3 +1,3 @@ group() { - import_stl(file = "", cache = "0.0", convexity = 1); + import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); } -- cgit v0.10.1 From 226e36a75f43b78c1af38f7354960587f61ecbd2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 02:32:37 +0200 Subject: Adapted to latest import() changes diff --git a/tests/regression/csgtermtest/transform-insert-expected.txt b/tests/regression/csgtermtest/transform-insert-expected.txt index edf214d..847d6c3 100644 --- a/tests/regression/csgtermtest/transform-insert-expected.txt +++ b/tests/regression/csgtermtest/transform-insert-expected.txt @@ -1 +1 @@ -import_dxf2 +import2 diff --git a/tests/regression/csgtexttest/transform-insert-expected.txt b/tests/regression/csgtexttest/transform-insert-expected.txt index ffb96fc..a673ddb 100644 --- a/tests/regression/csgtexttest/transform-insert-expected.txt +++ b/tests/regression/csgtexttest/transform-insert-expected.txt @@ -1 +1 @@ -group1(import_dxf) +group1(import) -- cgit v0.10.1 From 2013390aa3d62f10e7d1a632893b5ed2a05cda61 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 02:33:16 +0200 Subject: Better 2d/3d test for projection diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 6faecde..a648587 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -25,14 +25,12 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr BOOST_FOREACH (AbstractNode * v, node.getChildren()) { if (v->modinst->tag_background) continue; CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v); - if (sum.empty()) sum = N.copy(); - else sum += N; + if (N.dim == 3) { + if (sum.empty()) sum = N.copy(); + else sum += N; + } } if (sum.empty()) return NULL; - if (sum.dim != 3) { - PRINTF("WARNING: Body of projection() must be a 3D object"); - return NULL; - } PolySet *ps = new PolySet(); ps->convexity = node.convexity; -- cgit v0.10.1 From fe0f9dd7555dd05391c956c32e26bed7d5e51a2c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 02:34:04 +0200 Subject: bugfix: removed dubious code for auto-unioning every PolyNode, this caused a crash for illegal projections diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 0d46cd9..9c5a51e 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -231,34 +231,29 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) return ContinueTraversal; } -// FIXME: EvaluateNode: Union over children + some magic - Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) { if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { if (!isCached(node)) { - // First union all children - // FIXME: What does this actually achieve? kintel 20110906 - applyToChildren(node, CGE_UNION); - - // Then apply polyset operation + // Apply polyset operation PolySet *ps = node.evaluate_polyset(AbstractPolyNode::RENDER_CGAL, &this->psevaluator); + CGAL_Nef_polyhedron N; if (ps) { try { - CGAL_Nef_polyhedron N = evaluateCGALMesh(*ps); + N = evaluateCGALMesh(*ps); // print_messages_pop(); node.progress_report(); ps->unlink(); - const std::string &cacheid = this->tree.getString(node); - this->cache.insert(cacheid, N); } catch (...) { // Don't leak the PolySet on ProgressCancelException ps->unlink(); throw; } } + const std::string &cacheid = this->tree.getString(node); + this->cache.insert(cacheid, N); } addToParent(state, node); } -- cgit v0.10.1 From 75784844eaad1aa77757eb7640547146e0a96209 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 22:04:02 +0200 Subject: Implemented OFF export diff --git a/src/export.cc b/src/export.cc index 0c60ea3..9a5eb55 100644 --- a/src/export.cc +++ b/src/export.cc @@ -42,7 +42,7 @@ Saves the current 3D CGAL Nef polyhedron as STL to the given file. The file must be open. */ -void export_stl(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialog *pd) +void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDialog *pd) { CGAL_Polyhedron P; root_N->p3->convert_to_Polyhedron(P); @@ -110,15 +110,17 @@ void export_stl(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialo setlocale(LC_NUMERIC, ""); // Set default locale } -void export_off(CGAL_Nef_polyhedron*, QTextStream&, QProgressDialog*) +void export_off(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDialog*) { - PRINTF("WARNING: OFF import is not implemented yet."); + CGAL_Polyhedron P; + root_N->p3->convert_to_Polyhedron(P); + output << P; } /*! Saves the current 2D CGAL Nef polyhedron as DXF to the given absolute filename. */ -void export_dxf(CGAL_Nef_polyhedron *root_N, QTextStream &output, QProgressDialog *) +void export_dxf(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDialog *) { setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output // Some importers (e.g. Inkscape) needs a BLOCKS section to be present diff --git a/src/export.h b/src/export.h index 0298611..cba0b23 100644 --- a/src/export.h +++ b/src/export.h @@ -3,10 +3,12 @@ #ifdef ENABLE_CGAL +#include + void cgal_nef3_to_polyset(class PolySet *ps, class CGAL_Nef_polyhedron *root_N); -void export_stl(CGAL_Nef_polyhedron *root_N, class QTextStream &output, class QProgressDialog *pd); -void export_off(CGAL_Nef_polyhedron *root_N, class QTextStream &output, QProgressDialog *pd); -void export_dxf(CGAL_Nef_polyhedron *root_N, class QTextStream &output, QProgressDialog *pd); +void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, class QProgressDialog *pd); +void export_off(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDialog *pd); +void export_dxf(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDialog *pd); #endif #endif diff --git a/src/mainwin.cc b/src/mainwin.cc index e1ab8f0..c937279 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -75,6 +75,8 @@ #include "qlanguagefactory.h" #endif +#include + #include #include #include @@ -1403,15 +1405,14 @@ void MainWindow::actionExportSTLorOFF(bool) pd->show(); QApplication::processEvents(); - QFile file(stl_filename); - if (!file.open(QIODevice::ReadWrite)) { + std::ofstream fstream(stl_filename.toUtf8()); + if (!fstream.is_open()) { PRINTA("Can't open file \"%1\" for export", stl_filename); } else { - QTextStream fstream(&file); if (stl_mode) export_stl(this->root_N, fstream, pd); else export_off(this->root_N, fstream, pd); - file.close(); + fstream.close(); PRINTF("%s export finished.", stl_mode ? "STL" : "OFF"); } @@ -1458,14 +1459,13 @@ void MainWindow::actionExportDXF() return; } - QFile file(dxf_filename); - if (!file.open(QIODevice::ReadWrite)) { - PRINTA("Can't open file \"%1\" for export", dxf_filename); + std::ofstream fstream(dxf_filename.toUtf8()); + if (!fstream.is_open()) { + PRINTA("Can't open file \"%s\" for export", dxf_filename); } else { - QTextStream fstream(&file); export_dxf(this->root_N, fstream, NULL); - file.close(); + fstream.close(); PRINTF("DXF export finished."); } diff --git a/src/openscad.cc b/src/openscad.cc index a75d629..7ecf988 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -39,6 +39,7 @@ #include #include +#include #ifdef ENABLE_CGAL #include "CGAL_Nef_polyhedron.h" @@ -318,38 +319,35 @@ int main(int argc, char **argv) } if (stl_output_file) { - QFile file(stl_output_file); - if (!file.open(QIODevice::ReadWrite)) { - PRINTA("Can't open file \"%1\" for export", stl_output_file); + std::ofstream fstream(stl_output_file); + if (!fstream.is_open()) { + PRINTF("Can't open file \"%s\" for export", stl_output_file); } else { - QTextStream fstream(&file); export_stl(&root_N, fstream, NULL); - file.close(); + fstream.close(); } } if (off_output_file) { - QFile file(stl_output_file); - if (!file.open(QIODevice::ReadWrite)) { - PRINTA("Can't open file \"%1\" for export", stl_output_file); + std::ofstream fstream(stl_output_file); + if (!fstream.is_open()) { + PRINTF("Can't open file \"%s\" for export", stl_output_file); } else { - QTextStream fstream(&file); export_off(&root_N, fstream, NULL); - file.close(); + fstream.close(); } } if (dxf_output_file) { - QFile file(dxf_output_file); - if (!file.open(QIODevice::ReadWrite)) { - PRINTA("Can't open file \"%1\" for export", dxf_output_file); + std::ofstream fstream(dxf_output_file); + if (!fstream.is_open()) { + PRINTF("Can't open file \"%s\" for export", dxf_output_file); } else { - QTextStream fstream(&file); export_dxf(&root_N, fstream, NULL); - file.close(); + fstream.close(); } } diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc index a882638..029fcfc 100644 --- a/tests/cgaltest.cc +++ b/tests/cgaltest.cc @@ -171,8 +171,7 @@ int main(int argc, char **argv) QDir::setCurrent(original_path.absolutePath()); if (!N.empty()) { - QTextStream outstream(stdout); - export_stl(&N, outstream, NULL); + export_stl(&N, std::cout, NULL); } destroy_builtin_functions(); destroy_builtin_modules(); -- cgit v0.10.1 From 27a99044d8388ff30080bd0298eb936b8dd1341a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 22:04:59 +0200 Subject: Implemented OFF import, refactored PolySet/Polyhedron conversion diff --git a/openscad.pro b/openscad.pro index a7dd59e..4541eaa 100644 --- a/openscad.pro +++ b/openscad.pro @@ -213,12 +213,14 @@ SOURCES += src/openscad.cc \ cgal { HEADERS += src/cgal.h \ src/cgalfwd.h \ + src/cgalutils.h \ src/CGALEvaluator.h \ src/PolySetCGALEvaluator.h \ src/CGALRenderer.h \ src/CGAL_Nef_polyhedron.h -SOURCES += src/CGALEvaluator.cc \ +SOURCES += src/cgalutils.cc \ + src/CGALEvaluator.cc \ src/PolySetCGALEvaluator.cc \ src/CGALRenderer.cc \ src/CGAL_Nef_polyhedron.cc \ diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 9c5a51e..8e5e222 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -12,6 +12,7 @@ #include "dxftess.h" #include "cgal.h" +#include "cgalutils.h" #include #include @@ -332,93 +333,6 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node } #endif -#ifdef ENABLE_CGAL - -#undef GEN_SURFACE_DEBUG - -class CGAL_Build_PolySet : public CGAL::Modifier_base -{ -public: - typedef CGAL_HDS::Vertex::Point CGALPoint; - - const PolySet &ps; - CGAL_Build_PolySet(const PolySet &ps) : ps(ps) { } - - void operator()(CGAL_HDS& hds) - { - CGAL_Polybuilder B(hds, true); - - std::vector vertices; - Grid3d vertices_idx(GRID_FINE); - - for (size_t i = 0; i < ps.polygons.size(); i++) { - const PolySet::Polygon *poly = &ps.polygons[i]; - for (size_t j = 0; j < poly->size(); j++) { - const Vector3d &p = poly->at(j); - if (!vertices_idx.has(p[0], p[1], p[2])) { - vertices_idx.data(p[0], p[1], p[2]) = vertices.size(); - vertices.push_back(CGALPoint(p[0], p[1], p[2])); - } - } - } - - B.begin_surface(vertices.size(), ps.polygons.size()); -#ifdef GEN_SURFACE_DEBUG - printf("=== CGAL Surface ===\n"); -#endif - - for (size_t i = 0; i < vertices.size(); i++) { - const CGALPoint &p = vertices[i]; - B.add_vertex(p); -#ifdef GEN_SURFACE_DEBUG - printf("%d: %f %f %f\n", i, p[0], p[1], p[2]); -#endif - } - - for (size_t i = 0; i < ps.polygons.size(); i++) { - const PolySet::Polygon *poly = &ps.polygons[i]; - QHash fc; - bool facet_is_degenerated = false; - for (size_t j = 0; j < poly->size(); j++) { - const Vector3d &p = poly->at(j); - int v = vertices_idx.data(p[0], p[1], p[2]); - if (fc[v]++ > 0) - facet_is_degenerated = true; - } - - if (!facet_is_degenerated) - B.begin_facet(); -#ifdef GEN_SURFACE_DEBUG - printf("F:"); -#endif - for (size_t j = 0; j < poly->size(); j++) { - const Vector3d &p = poly->at(j); -#ifdef GEN_SURFACE_DEBUG - printf(" %d (%f,%f,%f)", vertices_idx.data(p[0], p[1], p[2]), p[0], p[1], p[2]); -#endif - if (!facet_is_degenerated) - B.add_vertex_to_facet(vertices_idx.data(p[0], p[1], p[2])); - } -#ifdef GEN_SURFACE_DEBUG - if (facet_is_degenerated) - printf(" (degenerated)"); - printf("\n"); -#endif - if (!facet_is_degenerated) - B.end_facet(); - } - -#ifdef GEN_SURFACE_DEBUG - printf("====================\n"); -#endif - B.end_surface(); - - #undef PointKey - } -}; - -#endif /* ENABLE_CGAL */ - CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) { if (ps.empty()) return CGAL_Nef_polyhedron(); @@ -679,15 +593,12 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) { CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); try { - CGAL_Polyhedron P; - CGAL_Build_PolySet builder(ps); - P.delegate(builder); -#if 0 - std::cout << P; -#endif - CGAL_Nef_polyhedron3 *N = new CGAL_Nef_polyhedron3(P); - return CGAL_Nef_polyhedron(N); - } + CGAL_Polyhedron *P = createPolyhedronFromPolySet(ps); + if (P) { + CGAL_Nef_polyhedron3 *N = new CGAL_Nef_polyhedron3(*P); + return CGAL_Nef_polyhedron(N); + } + } catch (CGAL::Assertion_exception e) { PRINTF("CGAL error: %s", e.what()); CGAL::set_error_behaviour(old_behaviour); diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index afe7119..6dcbdea 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -1,5 +1,6 @@ #include "CGAL_Nef_polyhedron.h" #include "cgal.h" +#include "cgalutils.h" #include "polyset.h" #include "dxfdata.h" #include "dxftess.h" @@ -51,8 +52,9 @@ int CGAL_Nef_polyhedron::weight() const PolySet *CGAL_Nef_polyhedron::convertToPolyset() { assert(!this->empty()); - PolySet *ps = new PolySet(); + PolySet *ps = NULL; if (this->dim == 2) { + ps = new PolySet(); DxfData *dd = this->convertToDxfData(); ps->is2d = true; dxf_tesselate(ps, *dd, 0, true, false, 0); @@ -62,36 +64,7 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() else if (this->dim == 3) { CGAL_Polyhedron P; this->p3->convert_to_Polyhedron(P); - - typedef CGAL_Polyhedron::Vertex Vertex; - typedef CGAL_Polyhedron::Vertex_const_iterator VCI; - typedef CGAL_Polyhedron::Facet_const_iterator FCI; - typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; - - for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { - HFCC hc = fi->facet_begin(); - HFCC hc_end = hc; - Vertex v1, v2, v3; - v1 = *VCI((hc++)->vertex()); - v3 = *VCI((hc++)->vertex()); - do { - v2 = v3; - v3 = *VCI((hc++)->vertex()); - double x1 = CGAL::to_double(v1.point().x()); - double y1 = CGAL::to_double(v1.point().y()); - double z1 = CGAL::to_double(v1.point().z()); - double x2 = CGAL::to_double(v2.point().x()); - double y2 = CGAL::to_double(v2.point().y()); - double z2 = CGAL::to_double(v2.point().z()); - double x3 = CGAL::to_double(v3.point().x()); - double y3 = CGAL::to_double(v3.point().y()); - double z3 = CGAL::to_double(v3.point().z()); - ps->append_poly(); - ps->append_vertex(x1, y1, z1); - ps->append_vertex(x2, y2, z2); - ps->append_vertex(x3, y3, z3); - } while (hc != hc_end); - } + ps = createPolySetFromPolyhedron(P); } return ps; } diff --git a/src/cgalfwd.h b/src/cgalfwd.h index df9b9e2..3fad608 100644 --- a/src/cgalfwd.h +++ b/src/cgalfwd.h @@ -1,8 +1,13 @@ #ifndef CGALFWD_H_ #define CGALFWD_H_ +#ifndef CGAL_FORWARD +#include "cgal.h" +#else #ifdef ENABLE_CGAL +#include + namespace CGAL { class Gmpq; template class Extended_cartesian; @@ -22,6 +27,19 @@ namespace CGAL { typedef CGAL::Cartesian CGAL_Kernel3; typedef CGAL::Nef_polyhedron_3 CGAL_Nef_polyhedron3; +namespace CGAL { +#ifndef CGAL_ALLOCATOR +# define CGAL_ALLOCATOR(T) std::allocator< T > +#endif + class HalfedgeDS_items_2; + template class HalfedgeDS_default; + class Polyhedron_items_3; + template class Polyhedron_3; +} +typedef CGAL::Polyhedron_3, CGAL_ALLOCATOR(int)> CGAL_Polyhedron; + #endif /* ENABLE_CGAL */ #endif + +#endif diff --git a/src/cgalutils.cc b/src/cgalutils.cc new file mode 100644 index 0000000..79e9f1f --- /dev/null +++ b/src/cgalutils.cc @@ -0,0 +1,147 @@ +#ifdef ENABLE_CGAL + +#include "cgalutils.h" +#include "polyset.h" +#include "printutils.h" + +#include "cgal.h" +#include +#include + +PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p) +{ + PolySet *ps = new PolySet(); + + typedef CGAL_Polyhedron::Vertex Vertex; + typedef CGAL_Polyhedron::Vertex_const_iterator VCI; + typedef CGAL_Polyhedron::Facet_const_iterator FCI; + typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; + + for (FCI fi = p.facets_begin(); fi != p.facets_end(); ++fi) { + HFCC hc = fi->facet_begin(); + HFCC hc_end = hc; + Vertex v1, v2, v3; + v1 = *VCI((hc++)->vertex()); + v3 = *VCI((hc++)->vertex()); + do { + v2 = v3; + v3 = *VCI((hc++)->vertex()); + double x1 = CGAL::to_double(v1.point().x()); + double y1 = CGAL::to_double(v1.point().y()); + double z1 = CGAL::to_double(v1.point().z()); + double x2 = CGAL::to_double(v2.point().x()); + double y2 = CGAL::to_double(v2.point().y()); + double z2 = CGAL::to_double(v2.point().z()); + double x3 = CGAL::to_double(v3.point().x()); + double y3 = CGAL::to_double(v3.point().y()); + double z3 = CGAL::to_double(v3.point().z()); + ps->append_poly(); + ps->append_vertex(x1, y1, z1); + ps->append_vertex(x2, y2, z2); + ps->append_vertex(x3, y3, z3); + } while (hc != hc_end); + } + return ps; +} + +#undef GEN_SURFACE_DEBUG + +class CGAL_Build_PolySet : public CGAL::Modifier_base +{ +public: + typedef CGAL_HDS::Vertex::Point CGALPoint; + + const PolySet &ps; + CGAL_Build_PolySet(const PolySet &ps) : ps(ps) { } + + void operator()(CGAL_HDS& hds) + { + CGAL_Polybuilder B(hds, true); + + std::vector vertices; + Grid3d vertices_idx(GRID_FINE); + + for (size_t i = 0; i < ps.polygons.size(); i++) { + const PolySet::Polygon *poly = &ps.polygons[i]; + for (size_t j = 0; j < poly->size(); j++) { + const Vector3d &p = poly->at(j); + if (!vertices_idx.has(p[0], p[1], p[2])) { + vertices_idx.data(p[0], p[1], p[2]) = vertices.size(); + vertices.push_back(CGALPoint(p[0], p[1], p[2])); + } + } + } + + B.begin_surface(vertices.size(), ps.polygons.size()); +#ifdef GEN_SURFACE_DEBUG + printf("=== CGAL Surface ===\n"); +#endif + + for (size_t i = 0; i < vertices.size(); i++) { + const CGALPoint &p = vertices[i]; + B.add_vertex(p); +#ifdef GEN_SURFACE_DEBUG + printf("%d: %f %f %f\n", i, p[0], p[1], p[2]); +#endif + } + + for (size_t i = 0; i < ps.polygons.size(); i++) { + const PolySet::Polygon *poly = &ps.polygons[i]; + QHash fc; + bool facet_is_degenerated = false; + for (size_t j = 0; j < poly->size(); j++) { + const Vector3d &p = poly->at(j); + int v = vertices_idx.data(p[0], p[1], p[2]); + if (fc[v]++ > 0) + facet_is_degenerated = true; + } + + if (!facet_is_degenerated) + B.begin_facet(); +#ifdef GEN_SURFACE_DEBUG + printf("F:"); +#endif + for (size_t j = 0; j < poly->size(); j++) { + const Vector3d &p = poly->at(j); +#ifdef GEN_SURFACE_DEBUG + printf(" %d (%f,%f,%f)", vertices_idx.data(p[0], p[1], p[2]), p[0], p[1], p[2]); +#endif + if (!facet_is_degenerated) + B.add_vertex_to_facet(vertices_idx.data(p[0], p[1], p[2])); + } +#ifdef GEN_SURFACE_DEBUG + if (facet_is_degenerated) + printf(" (degenerated)"); + printf("\n"); +#endif + if (!facet_is_degenerated) + B.end_facet(); + } + +#ifdef GEN_SURFACE_DEBUG + printf("====================\n"); +#endif + B.end_surface(); + + #undef PointKey + } +}; + +CGAL_Polyhedron *createPolyhedronFromPolySet(const PolySet &ps) +{ + CGAL_Polyhedron *P = NULL; + CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); + try { + P = new CGAL_Polyhedron; + CGAL_Build_PolySet builder(ps); + P->delegate(builder); + } + catch (CGAL::Assertion_exception e) { + PRINTF("CGAL error: %s", e.what()); + CGAL::set_error_behaviour(old_behaviour); + } + return P; +} + +#endif /* ENABLE_CGAL */ + diff --git a/src/cgalutils.h b/src/cgalutils.h new file mode 100644 index 0000000..a249697 --- /dev/null +++ b/src/cgalutils.h @@ -0,0 +1,9 @@ +#ifndef CGALUTILS_H_ +#define CGALUTILS_H_ + +#include + +class PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p); +CGAL_Polyhedron *createPolyhedronFromPolySet(const class PolySet &ps); + +#endif diff --git a/src/import.cc b/src/import.cc index 17ad3f2..8c27832 100644 --- a/src/import.cc +++ b/src/import.cc @@ -35,11 +35,16 @@ #include "printutils.h" #include "handle_dep.h" // handle_dep() +#ifdef ENABLE_CGAL +#include "cgalutils.h" +#endif + #include #include #include #include #include +#include #include #include #include @@ -108,11 +113,11 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const { - PolySet *p = new PolySet(); - p->convexity = this->convexity; + PolySet *p = NULL; if (this->type == TYPE_STL) { + p = new PolySet(); handle_dep(this->filename); QFile f(QString::fromStdString(this->filename)); if (!f.open(QIODevice::ReadOnly)) { @@ -190,11 +195,21 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c else if (this->type == TYPE_OFF) { - PRINTF("WARNING: OFF import is not implemented yet."); +#ifdef ENABLE_CGAL + CGAL_Polyhedron poly; + std::ifstream file(this->filename.c_str()); + file >> poly; + file.close(); + + p = createPolySetFromPolyhedron(poly); +#else + PRINTF("WARNING: OFF import requires CGAL."); +#endif } else if (this->type == TYPE_DXF) { + p = new PolySet(); DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale); p->is2d = true; dxf_tesselate(p, dd, 0, true, false, 0); @@ -205,6 +220,7 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c PRINTF("ERROR: Unsupported file format while trying to import file '%s'", this->filename.c_str()); } + if (p) p->convexity = this->convexity; return p; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b0aa6ed..2f43273 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -142,7 +142,7 @@ include_directories(${CGAL_INCLUDE_DIRS}) # # cgaltest # -add_executable(cgaltest cgaltest.cc ../src/CGAL_Nef_polyhedron.cc ../src/CSGTermEvaluator.cc +add_executable(cgaltest cgaltest.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) @@ -153,7 +153,7 @@ target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_ # cgalpngtest # add_executable(cgalpngtest cgalpngtest.cc OffscreenView.cc OffscreenContext.mm - ../src/CGALRenderer.cc ../src/CGAL_Nef_polyhedron.cc + ../src/CGALRenderer.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc @@ -166,7 +166,7 @@ target_link_libraries(cgalpngtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${ # add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc - ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc + ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) -- cgit v0.10.1 From e9068e5adf96df48e2fef723251c7b35bdbffacf Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 22:27:29 +0200 Subject: Updated tests to reflect recently changed import behavior diff --git a/src/import.cc b/src/import.cc index 8c27832..0fdc156 100644 --- a/src/import.cc +++ b/src/import.cc @@ -117,7 +117,6 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c if (this->type == TYPE_STL) { - p = new PolySet(); handle_dep(this->filename); QFile f(QString::fromStdString(this->filename)); if (!f.open(QIODevice::ReadOnly)) { @@ -125,6 +124,7 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c return p; } + p = new PolySet(); QByteArray data = f.read(5); if (data.size() == 5 && QString(data) == QString("solid")) { diff --git a/tests/regression/csgtermtest/allmodules-expected.txt b/tests/regression/csgtermtest/allmodules-expected.txt index c375c01..d7a04fc 100644 --- a/tests/regression/csgtermtest/allmodules-expected.txt +++ b/tests/regression/csgtermtest/allmodules-expected.txt @@ -1 +1 @@ -((((((((((((((((linear_extrude14 + linear_extrude15) + rotate_extrude16) + rotate_extrude17) + import18) + import19) + import20) + import21) + cube23) + sphere24) + cylinder25) + polyhedron26) + square27) + circle28) + polygon29) + projection30) + surface32) +(((((((((((((linear_extrude14 + linear_extrude15) + rotate_extrude16) + rotate_extrude17) + import21) + cube23) + sphere24) + cylinder25) + polyhedron26) + square27) + circle28) + polygon29) + projection30) + surface32) diff --git a/tests/regression/csgtermtest/import-expected.txt b/tests/regression/csgtermtest/import-expected.txt index 847d6c3..a40cf60 100644 --- a/tests/regression/csgtermtest/import-expected.txt +++ b/tests/regression/csgtermtest/import-expected.txt @@ -1 +1 @@ -import2 +No top-level CSG object diff --git a/tests/regression/csgtermtest/import_off-expected.txt b/tests/regression/csgtermtest/import_off-expected.txt index 847d6c3..a40cf60 100644 --- a/tests/regression/csgtermtest/import_off-expected.txt +++ b/tests/regression/csgtermtest/import_off-expected.txt @@ -1 +1 @@ -import2 +No top-level CSG object diff --git a/tests/regression/csgtermtest/import_stl-expected.txt b/tests/regression/csgtermtest/import_stl-expected.txt index 847d6c3..a40cf60 100644 --- a/tests/regression/csgtermtest/import_stl-expected.txt +++ b/tests/regression/csgtermtest/import_stl-expected.txt @@ -1 +1 @@ -import2 +No top-level CSG object -- cgit v0.10.1 From 233521a11df969e838ef41759ff4b531973d1c8a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 22:56:39 +0200 Subject: Added assign-tests diff --git a/testdata/scad/features/assign-tests.scad b/testdata/scad/features/assign-tests.scad new file mode 100644 index 0000000..b86dabe --- /dev/null +++ b/testdata/scad/features/assign-tests.scad @@ -0,0 +1,6 @@ +for(i=[0:5]) { + translate([i*i/2,0,0]) { + cube(i); + translate([0,-5,0]) assign(f=1.0*i/2) cube(f); + } +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2f43273..1ee2ae7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -232,7 +232,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/for-nested-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection_for-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/render-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/projection-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/projection-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/assign-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/assign-tests-expected.png b/tests/regression/cgalpngtest/assign-tests-expected.png new file mode 100644 index 0000000..465a94d Binary files /dev/null and b/tests/regression/cgalpngtest/assign-tests-expected.png differ diff --git a/tests/regression/opencsgtest/assign-tests-expected.png b/tests/regression/opencsgtest/assign-tests-expected.png new file mode 100644 index 0000000..6fe8e10 Binary files /dev/null and b/tests/regression/opencsgtest/assign-tests-expected.png differ -- cgit v0.10.1 From 93c8480ffb3a5d9ab89dd1dea1894415ccf4619a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 7 Sep 2011 22:57:10 +0200 Subject: bugfix: context got lost dugin a recent refactoring job diff --git a/src/control.cc b/src/control.cc index 01d7f03..c39b74a 100644 --- a/src/control.cc +++ b/src/control.cc @@ -137,7 +137,7 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation if (!inst->argnames[i].empty()) c.set_variable(inst->argnames[i], inst->argvalues[i]); } - std::vector evaluatednodes = inst->evaluateChildren(); + std::vector evaluatednodes = inst->evaluateChildren(&c); node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } -- cgit v0.10.1 From 838f1fb8fcb527c5c9628b444f120058bba5479f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 00:08:47 +0200 Subject: Partially removed Qt dependency diff --git a/src/export.cc b/src/export.cc index 9a5eb55..6c427dd 100644 --- a/src/export.cc +++ b/src/export.cc @@ -31,7 +31,6 @@ #include #include -#include #include #ifdef ENABLE_CGAL @@ -75,10 +74,15 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial double x3 = CGAL::to_double(v3.point().x()); double y3 = CGAL::to_double(v3.point().y()); double z3 = CGAL::to_double(v3.point().z()); - QString vs1, vs2, vs3; - vs1.sprintf("%f %f %f", x1, y1, z1); - vs2.sprintf("%f %f %f", x2, y2, z2); - vs3.sprintf("%f %f %f", x3, y3, z3); + std::stringstream stream; + stream << x1 << " " << y1 << " " << z1; + std::string vs1 = stream.str(); + stream.str(""); + stream << x2 << " " << y2 << " " << z2; + std::string vs2 = stream.str(); + stream.str(""); + stream << x3 << " " << y3 << " " << z3; + std::string vs3 = stream.str(); if (vs1 != vs2 && vs1 != vs3 && vs2 != vs3) { double nx = (y1-y2)*(z1-z3) - (z1-z2)*(y1-y3); -- cgit v0.10.1 From fab0f891b79c0c2cbc91120f7648af8a96c6669d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 02:31:27 +0200 Subject: Updated the include tests to provide geometry diff --git a/testdata/scad/features/include test6.scad b/testdata/scad/features/include test6.scad index 7a79456..0d96b26 100644 --- a/testdata/scad/features/include test6.scad +++ b/testdata/scad/features/include test6.scad @@ -1,4 +1,7 @@ module test6() { - echo("included from include test6.scad"); + difference() { + cube(center=true); + cylinder(r=0.4, h=2, center=true); + } } diff --git a/testdata/scad/features/include-test.scad b/testdata/scad/features/include-test.scad deleted file mode 100644 index 5db02d7..0000000 --- a/testdata/scad/features/include-test.scad +++ /dev/null @@ -1,40 +0,0 @@ -//Test that the entire path is pushed onto the stack upto the last '/' -include - -//Test that a non existent path/file doesn't screw things up -include - -//Test with empty path -include - -//Test without preceeding space -include - -//Test with other strange character that is allowed -include>>>>> - -//Test that filenames with spaces work -include - -//Test with empty file -include - -//Test with empty path and file -include - -//Test with empty -include <> - -module test1() -{ - test2(); - test3(); - test4(); - test5(); - test6(); - - //Just to give a top level object - sphere(1); -} - -test1(); diff --git a/testdata/scad/features/include-test5.scad b/testdata/scad/features/include-test5.scad index 4f6e656..e4393cb 100644 --- a/testdata/scad/features/include-test5.scad +++ b/testdata/scad/features/include-test5.scad @@ -1,4 +1,4 @@ module test5() { - echo("included from include-test5.scad"); + sphere(r=0.5, $fn=8); } diff --git a/testdata/scad/features/include-tests.scad b/testdata/scad/features/include-tests.scad new file mode 100644 index 0000000..36c04ca --- /dev/null +++ b/testdata/scad/features/include-tests.scad @@ -0,0 +1,40 @@ +//Test that the entire path is pushed onto the stack upto the last '/' +include + +//Test that a non existent path/file doesn't screw things up +include + +//Test with empty path +include + +//Test without preceeding space +include + +//Test with other strange character that is allowed +include>>>>> + +//Test that filenames with spaces work +include + +//Test with empty file +include + +//Test with empty path and file +include + +//Test with empty +include <> + +module test1() +{ + test2(); + translate([2,0,0]) test3(); + translate([2,-2,0]) test4(); + translate([-2,0,0]) test5(); + translate([-2,-2,0]) test6(); + + //Just to give a top level object + translate([0,-2,0]) sphere(0.7, $fn=16); +} + +test1(); diff --git a/testdata/scad/features/sub1/sub2/sub3/include-test4.scad b/testdata/scad/features/sub1/sub2/sub3/include-test4.scad index 1cb7eab..c13368c 100644 --- a/testdata/scad/features/sub1/sub2/sub3/include-test4.scad +++ b/testdata/scad/features/sub1/sub2/sub3/include-test4.scad @@ -1,4 +1,4 @@ module test4() { - echo("included from include-test4.scad"); + cylinder(r=0.5, $fn=10, center=true); } diff --git a/testdata/scad/features/sub1/sub2/sub3/sub4/include-test2.scad b/testdata/scad/features/sub1/sub2/sub3/sub4/include-test2.scad index 9f4c963..140c4ed 100644 --- a/testdata/scad/features/sub1/sub2/sub3/sub4/include-test2.scad +++ b/testdata/scad/features/sub1/sub2/sub3/sub4/include-test2.scad @@ -6,5 +6,5 @@ include <../include-test4.scad> module test2 () { - echo("included from include-test2.scad"); + cube(center=true); } diff --git a/testdata/scad/features/sub1/sub2/sub3/sub4/include-test3.scad b/testdata/scad/features/sub1/sub2/sub3/sub4/include-test3.scad index 2f67e93..6e3537e 100644 --- a/testdata/scad/features/sub1/sub2/sub3/sub4/include-test3.scad +++ b/testdata/scad/features/sub1/sub2/sub3/sub4/include-test3.scad @@ -1,4 +1,4 @@ module test3() { - echo("included from include-test3.scad"); + cylinder(r1=0.7, r2=0.2, center=true); } -- cgit v0.10.1 From 297a6f61c6a14eb10ee7438eb092395b3d71f81c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 02:31:47 +0200 Subject: Added include-tests diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1ee2ae7..f7fd320 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -233,7 +233,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/intersection_for-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/render-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/projection-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/assign-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/assign-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/include-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) -- cgit v0.10.1 From 869231f752104e67ca254ff7661cc806df0c2439 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 02:32:49 +0200 Subject: Killed some warnings diff --git a/src/csgterm.cc b/src/csgterm.cc index c615a58..f24a41a 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -220,7 +220,7 @@ std::string CSGChain::dump() { std::stringstream dump; - for (int i = 0; i < types.size(); i++) + for (size_t i = 0; i < types.size(); i++) { if (types[i] == CSGTerm::TYPE_UNION) { if (i != 0) dump << "\n"; diff --git a/src/dxfdata.cc b/src/dxfdata.cc index 3e224e3..10f3b0c 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -385,7 +385,7 @@ DxfData::DxfData(double fn, double fs, double fa, int idx = l.second; for (int j = 0; j < 2; j++) { std::vector *lv = &grid.data(this->points[lines[idx].idx[j]][0], this->points[lines[idx].idx[j]][1]); - for (int ki = 0; ki < lv->size(); ki++) { + for (size_t ki = 0; ki < lv->size(); ki++) { int k = lv->at(ki); if (k == idx || lines[k].disabled) continue; @@ -411,7 +411,7 @@ DxfData::DxfData(double fn, double fs, double fa, lines[current_line].disabled = true; enabled_lines.erase(current_line); std::vector *lv = &grid.data(ref_point[0], ref_point[1]); - for (int ki = 0; ki < lv->size(); ki++) { + for (size_t ki = 0; ki < lv->size(); ki++) { int k = lv->at(ki); if (lines[k].disabled) continue; @@ -447,7 +447,7 @@ DxfData::DxfData(double fn, double fs, double fa, lines[current_line].disabled = true; enabled_lines.erase(current_line); std::vector *lv = &grid.data(ref_point[0], ref_point[1]); - for (int ki = 0; ki < lv->size(); ki++) { + for (size_t ki = 0; ki < lv->size(); ki++) { int k = lv->at(ki); if (lines[k].disabled) continue; diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc index 6585e76..e4a4908 100644 --- a/src/dxftess-cgal.cc +++ b/src/dxftess-cgal.cc @@ -106,14 +106,14 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool /* do_tr try { // read path data and copy all relevant infos - for (int i = 0; i < dxf.paths.size(); i++) + for (size_t i = 0; i < dxf.paths.size(); i++) { if (!dxf.paths[i].is_closed) continue; Vertex_handle first, prev; struct point_info_t *first_pi = NULL, *prev_pi = NULL; - for (int j = 1; j < dxf.paths[i].indices.size(); j++) + for (size_t j = 1; j < dxf.paths[i].indices.size(); j++) { double x = dxf.points[dxf.paths[i].indices[j]][0]; double y = dxf.points[dxf.paths[i].indices[j]][1]; diff --git a/src/polyset.cc b/src/polyset.cc index e29563f..db37b49 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -190,7 +190,7 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m glBegin(GL_TRIANGLES); for (double z = -zbase/2; z < zbase; z += zbase) { - for (int i = 0; i < polygons.size(); i++) { + for (size_t i = 0; i < polygons.size(); i++) { const Polygon *poly = &polygons[i]; if (poly->size() == 3) { if (z < 0) { @@ -210,13 +210,13 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m } else { Vector3d center = Vector3d::Zero(); - for (int j = 0; j < poly->size(); j++) { + for (size_t j = 0; j < poly->size(); j++) { center[0] += poly->at(j)[0]; center[1] += poly->at(j)[1]; } center[0] /= poly->size(); center[1] /= poly->size(); - for (int j = 1; j <= poly->size(); j++) { + for (size_t j = 1; j <= poly->size(); j++) { if (z < 0) { gl_draw_triangle(shaderinfo, center, poly->at(j % poly->size()), poly->at(j - 1), false, true, false, z, mirrored); @@ -231,9 +231,9 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m const std::vector *borders_p = &borders; if (borders_p->size() == 0) borders_p = &polygons; - for (int i = 0; i < borders_p->size(); i++) { + for (size_t i = 0; i < borders_p->size(); i++) { const Polygon *poly = &borders_p->at(i); - for (int j = 1; j <= poly->size(); j++) { + for (size_t j = 1; j <= poly->size(); j++) { Vector3d p1 = poly->at(j - 1), p2 = poly->at(j - 1); Vector3d p3 = poly->at(j % poly->size()), p4 = poly->at(j % poly->size()); p1[2] -= zbase/2, p2[2] += zbase/2; @@ -244,7 +244,7 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m } glEnd(); } else { - for (int i = 0; i < polygons.size(); i++) { + for (size_t i = 0; i < polygons.size(); i++) { const Polygon *poly = &polygons[i]; glBegin(GL_TRIANGLES); if (poly->size() == 3) { @@ -256,7 +256,7 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m } else { Vector3d center = Vector3d::Zero(); - for (int j = 0; j < poly->size(); j++) { + for (size_t j = 0; j < poly->size(); j++) { center[0] += poly->at(j)[0]; center[1] += poly->at(j)[1]; center[2] += poly->at(j)[2]; @@ -264,7 +264,7 @@ void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, double *m center[0] /= poly->size(); center[1] /= poly->size(); center[2] /= poly->size(); - for (int j = 1; j <= poly->size(); j++) { + for (size_t j = 1; j <= poly->size(); j++) { gl_draw_triangle(shaderinfo, center, poly->at(j - 1), poly->at(j % poly->size()), false, true, false, 0, mirrored); } } @@ -287,20 +287,20 @@ void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const double zbase = csgmode; for (double z = -zbase/2; z < zbase; z += zbase) { - for (int i = 0; i < borders.size(); i++) { + for (size_t i = 0; i < borders.size(); i++) { const Polygon *poly = &borders[i]; glBegin(GL_LINE_LOOP); - for (int j = 0; j < poly->size(); j++) { + for (size_t j = 0; j < poly->size(); j++) { const Vector3d &p = poly->at(j); glVertex3d(p[0], p[1], z); } glEnd(); } } - for (int i = 0; i < borders.size(); i++) { + for (size_t i = 0; i < borders.size(); i++) { const Polygon *poly = &borders[i]; glBegin(GL_LINES); - for (int j = 0; j < poly->size(); j++) { + for (size_t j = 0; j < poly->size(); j++) { const Vector3d &p = poly->at(j); glVertex3d(p[0], p[1], -zbase/2); glVertex3d(p[0], p[1], +zbase/2); @@ -308,10 +308,10 @@ void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const glEnd(); } } else { - for (int i = 0; i < polygons.size(); i++) { + for (size_t i = 0; i < polygons.size(); i++) { const Polygon *poly = &polygons[i]; glBegin(GL_LINE_LOOP); - for (int j = 0; j < poly->size(); j++) { + for (size_t j = 0; j < poly->size(); j++) { const Vector3d &p = poly->at(j); glVertex3d(p[0], p[1], p[2]); } @@ -323,9 +323,9 @@ void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const BoundingBox PolySet::getBoundingBox() const { BoundingBox bbox; - for (int i = 0; i < polygons.size(); i++) { + for (size_t i = 0; i < polygons.size(); i++) { const Polygon &poly = polygons[i]; - for (int j = 0; j < poly.size(); j++) { + for (size_t j = 0; j < poly.size(); j++) { const Vector3d &p = poly[j]; bbox.extend(p); } -- cgit v0.10.1 From 8895546f0e555f83b8e7a1116aadcccc72d6ef83 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 02:33:32 +0200 Subject: Assert on unknown operation, be safe and kill a warning diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 8e5e222..440637a 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -172,6 +172,8 @@ Response CGALEvaluator::visit(State &state, const CsgNode &node) case CSG_TYPE_INTERSECTION: op = CGE_INTERSECTION; break; + default: + assert(false); } applyToChildren(node, op); } diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index f280b2b..dafa6a6 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -133,6 +133,8 @@ Response CSGTermEvaluator::visit(State &state, const CsgNode &node) case CSG_TYPE_INTERSECTION: op = CSGT_INTERSECTION; break; + default: + assert(false); } applyToChildren(node, op); addToParent(state, node); -- cgit v0.10.1 From e6e04d89db4314054111842b5a8ee27928a774a4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 02:33:54 +0200 Subject: bugfix: Empty renderer was uninitialized, caused a crash diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc index c9cfd6d..b758b93 100644 --- a/src/CGALRenderer.cc +++ b/src/CGALRenderer.cc @@ -60,6 +60,10 @@ CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(*this->root.p3, this->polyhedron); this->polyhedron->init(); } + else { + this->polyhedron = NULL; + this->polyset = NULL; + } } CGALRenderer::~CGALRenderer() -- cgit v0.10.1 From ecb25a3d4606bae8548ec0e9a9d9d1b0a722321d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 02:34:09 +0200 Subject: sync diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 5f529bb..eca6813 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,9 +1,16 @@ OpenSCAD 20xx.yy ================ +Features: +o The MCAD library is now bundled with OpenSCAD +o Added import and export of the OFF file format +o New import() statement reads the correct file format based on the filename extension + (.stl, .dxf and .off is supported) + Bugfixes: o square() crashed if any of the dimensions were zero o Flush Caches didn't flush cached USE'd modules +o STL export should be a bit more robust Deprecations: o dxf_linear_extrude() and dxf_rotate_extrude() are now deprecated. -- cgit v0.10.1 From 54a2eb56a526633fa03c97a6108c717a66b83b07 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 02:56:25 +0200 Subject: Remove unused libraries diff --git a/libraries/boxes.scad b/libraries/boxes.scad deleted file mode 100644 index 86bc099..0000000 --- a/libraries/boxes.scad +++ /dev/null @@ -1,43 +0,0 @@ -// Library: boxes.scad -// Version: 1.0 -// Author: Marius Kintel -// Copyright: 2010 -// License: BSD - -// roundedBox([width, height, depth], float radius, bool sidesonly); - -// EXAMPLE USAGE: -// roundedBox([20, 30, 40], 5, true); - -// size is a vector [w, h, d] -module roundedBox(size, radius, sidesonly) -{ - rot = [ [0,0,0], [90,0,90], [90,90,0] ]; - if (sidesonly) { - cube(size - [2*radius,0,0], true); - cube(size - [0,2*radius,0], true); - for (x = [radius-size[0]/2, -radius+size[0]/2], - y = [radius-size[1]/2, -radius+size[1]/2]) { - translate([x,y,0]) cylinder(r=radius, h=size[2], center=true); - } - } - else { - cube([size[0], size[1]-radius*2, size[2]-radius*2], center=true); - cube([size[0]-radius*2, size[1], size[2]-radius*2], center=true); - cube([size[0]-radius*2, size[1]-radius*2, size[2]], center=true); - - for (axis = [0:2]) { - for (x = [radius-size[axis]/2, -radius+size[axis]/2], - y = [radius-size[(axis+1)%3]/2, -radius+size[(axis+1)%3]/2]) { - rotate(rot[axis]) - translate([x,y,0]) - cylinder(h=size[(axis+2)%3]-2*radius, r=radius, center=true); - } - } - for (x = [radius-size[0]/2, -radius+size[0]/2], - y = [radius-size[1]/2, -radius+size[1]/2], - z = [radius-size[2]/2, -radius+size[2]/2]) { - translate([x,y,z]) sphere(radius); - } - } -} diff --git a/libraries/shapes.scad b/libraries/shapes.scad deleted file mode 100644 index 6b0e284..0000000 --- a/libraries/shapes.scad +++ /dev/null @@ -1,148 +0,0 @@ -/* - * OpenSCAD Shapes Library (www.openscad.org) - * Copyright (C) 2009 Catarina Mota - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ - - -//box(width, height, depth); -//roundedBox(width, height, depth, factor); -//cone(height, radius); -//oval(width, height, depth); -//tube(height, radius, wall); -//ovalTube(width, height, depth, wall); -//hexagon(height, depth); -//octagon(height, depth); -//dodecagon(height, depth); -//hexagram(height, depth); -//rightTriangle(adjacent, opposite, depth); -//equiTriangle(side, depth); -//12ptStar(height, depth); - -//---------------------- - -// size is a vector [w, h, d] -module box(size) { - cube(size, true); -} - -// size is a vector [w, h, d] -module roundedBox(size, radius) { - cube(size - [2*radius,0,0], true); - cube(size - [0,2*radius,0], true); - for (x = [radius-size[0]/2, -radius+size[0]/2], - y = [radius-size[1]/2, -radius+size[1]/2]) { - translate([x,y,0]) cylinder(r=radius, h=size[2], center=true); - } -} - -module cone(height, radius, center = false) { - cylinder(height, radius, 0, center); -} - -module oval(w,h, height, center = false) { - scale([1, h/w, 1]) cylinder(h=height, r=w, center=center); -} - -// wall is wall thickness -module tube(height, radius, wall, center = false) { - difference() { - cylinder(h=height, r=radius, center=center); - cylinder(h=height, r=radius-wall, center=center); - } -} - -// wall is wall thickness -module ovalTube(height, rx, ry, wall, center = false) { - difference() { - scale([1, ry/rx, 1]) cylinder(h=height, r=rx, center=center); - scale([(rx-wall)/rx, (ry-wall)/rx, 1]) cylinder(h=height, r=rx, center=center); - } -} - -// size is the XY plane size, height in Z -module hexagon(size, height) { - boxWidth = size/1.75; - for (r = [-60, 0, 60]) rotate([0,0,r]) cube([boxWidth, size, height], true); -} - -// size is the XY plane size, height in Z -module octagon(size, height) { - intersection() { - cube([size, size, height], true); - rotate([0,0,45]) cube([size, size, height], true); - } -} - -// size is the XY plane size, height in Z -module dodecagon(size, height) { - intersection() { - hexagon(size, height); - rotate([0,0,90]) hexagon(size, height); - } -} - -// size is the XY plane size, height in Z -module hexagram(size, height) { - boxWidth=size/1.75; - for (v = [[0,1],[0,-1],[1,-1]]) { - intersection() { - rotate([0,0,60*v[0]]) cube([size, boxWidth, height], true); - rotate([0,0,60*v[1]]) cube([size, boxWidth, height], true); - } - } -} - -module rightTriangle(adjacent, opposite, height) { - difference() { - translate([-adjacent/2,opposite/2,0]) cube([adjacent, opposite, height], true); - translate([-adjacent,0,0]) { - rotate([0,0,atan(opposite/adjacent)]) dislocateBox(adjacent*2, opposite, height); - } - } -} - -module equiTriangle(side, height) { - difference() { - translate([-side/2,side/2,0]) cube([side, side, height], true); - rotate([0,0,30]) dislocateBox(side*2, side, height); - translate([-side,0,0]) { - rotate([0,0,60]) dislocateBox(side*2, side, height); - } - } -} - -module 12ptStar(size, height) { - starNum = 3; - starAngle = 360/starNum; - for (s = [1:starNum]) { - rotate([0, 0, s*starAngle]) cube([size, size, height], true); - } -} - -//----------------------- -//MOVES THE ROTATION AXIS OF A BOX FROM ITS CENTER TO THE BOTTOM LEFT CORNER -//FIXME: Why are the dimensions changed? -// why not just translate([0,0,-d/2]) cube([w,h,d]); -module dislocateBox(w,h,d) { - translate([w/2,h,0]) { - difference() { - cube([w, h*2, d+1]); - translate([-w,0,0]) cube([w, h*2, d+1]); - } - } -} -- cgit v0.10.1 From 5ac46455f4d2f6930cd3fad5e308a27dfc4f368a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 03:01:55 +0200 Subject: Killed some warnings diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc index b758b93..f8e914b 100644 --- a/src/CGALRenderer.cc +++ b/src/CGALRenderer.cc @@ -81,9 +81,9 @@ void CGALRenderer::draw(bool showfaces, bool showedges) const const QColor &col = QColor(0x00, 0xbf, 0x99); glColor3f(col.redF(), col.greenF(), col.blueF()); - for (int i=0; i < this->polyset->polygons.size(); i++) { + for (size_t i=0; i < this->polyset->polygons.size(); i++) { glBegin(GL_POLYGON); - for (int j=0; j < this->polyset->polygons[i].size(); j++) { + for (size_t j=0; j < this->polyset->polygons[i].size(); j++) { const Vector3d &p = this->polyset->polygons[i][j]; glVertex3d(p[0], p[1], -0.1); } -- cgit v0.10.1 From 4abadeb8e410c96f4ae262a4557a319cad66ec62 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 03:27:07 +0200 Subject: Bundle MCAD library diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4ab4cf0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libraries/MCAD"] + path = libraries/MCAD + url = git@github.com:openscad/MCAD.git diff --git a/libraries/MCAD b/libraries/MCAD new file mode 160000 index 0000000..903569a --- /dev/null +++ b/libraries/MCAD @@ -0,0 +1 @@ +Subproject commit 903569a9a2ae9899805185af487402f864a7fbb8 -- cgit v0.10.1 From 4f7051412bc43d3ad372dd88e898d38e26ecbcf4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 03:27:18 +0200 Subject: Bundle MCAD library diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 340266d..9261d7a 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -80,17 +80,29 @@ echo "Creating directory structure..." case $OS in MACOSX) EXAMPLESDIR=OpenSCAD.app/Contents/Resources/examples + LIBRARYDIR=OpenSCAD.app/Contents/Resources/libraries ;; *) EXAMPLESDIR=openscad-$VERSION/examples/ + LIBRARYDIR=openscad-$VERSION/libraries/ rm -rf openscad-$VERSION mkdir openscad-$VERSION ;; esac -mkdir -p $EXAMPLESDIR -cp examples/* $EXAMPLESDIR -chmod -R 644 $EXAMPLESDIR/* +if [ -n $EXAMPLESDIR ]; then + echo $EXAMPLESDIR + mkdir -p $EXAMPLESDIR + cp examples/* $EXAMPLESDIR + chmod -R 644 $EXAMPLESDIR/* +fi +if [ -n $LIBRARYDIR ]; then + echo $LIBRARYDIR + mkdir -p $LIBRARYDIR + cp -R libraries/* $LIBRARYDIR + chmod -R u=rwx,go=r,+X $LIBRARYDIR/* + rm -rf `find $LIBRARYDIR -name ".git"` +fi echo "Creating archive.." diff --git a/scripts/release-linux.sh b/scripts/release-linux.sh index 35d177f..7675c07 100755 --- a/scripts/release-linux.sh +++ b/scripts/release-linux.sh @@ -87,6 +87,6 @@ chmod 755 -R release/ cp examples/* release/examples/ chmod 644 -R release/examples/* -cp libraries/* release/libraries/ -chmod 644 -R release/libraries/* - +cp -R libraries/* release/libraries/ +chmod -R u=rwx,go=r,+X release/libraries/* +rm -rf `find release/libraries -name ".git"` -- cgit v0.10.1 From a8d88c57fd960d56f5952ecf49903e91a9634ae0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 03:34:00 +0200 Subject: fixed merge conflict diff --git a/src/export.cc b/src/export.cc index 862e82b..3b8b102 100644 --- a/src/export.cc +++ b/src/export.cc @@ -54,17 +54,6 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output -<<<<<<< HEAD -======= - std::ofstream output(filename.toUtf8()); - if (!output.is_open()) { - PRINTA("Can't open STL file \"%1\" for STL export: %2", - filename, QString(strerror(errno))); - set_output_handler(NULL, NULL); - return; - } - ->>>>>>> master output << "solid OpenSCAD_Model\n"; int facet_count = 0; @@ -123,10 +112,6 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial } output << "endsolid OpenSCAD_Model\n"; -<<<<<<< HEAD -======= - output.close(); ->>>>>>> master setlocale(LC_NUMERIC, ""); // Set default locale } -- cgit v0.10.1 From f40daab2d1d329c66e37917baf308f1c249de028 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 03:34:13 +0200 Subject: fixed merge conflict diff --git a/src/export.cc b/src/export.cc index 3b8b102..6c427dd 100644 --- a/src/export.cc +++ b/src/export.cc @@ -32,7 +32,6 @@ #include #include #include -#include #ifdef ENABLE_CGAL #include "CGAL_Nef_polyhedron.h" -- cgit v0.10.1 From c398bc7e3d5eca8240bfd1d16fab88f33aec1cfe Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 03:39:14 +0200 Subject: fixed merge conflict diff --git a/src/openscad.cc b/src/openscad.cc index c4b0d5f..f7db633 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -319,7 +319,7 @@ int main(int argc, char **argv) } if (stl_output_file) { - if (root_N->dim == 3 && !root_N->p3.is_simple()) { + if (root_N.dim == 3 && !root_N.p3->is_simple()) { fprintf(stderr, "Object isn't a valid 2-manifold! Modify your design.\n"); exit(1); } @@ -334,7 +334,7 @@ int main(int argc, char **argv) } if (off_output_file) { - if (root_N->dim == 3 && !root_N->p3.is_simple()) { + if (root_N.dim == 3 && !root_N.p3->is_simple()) { fprintf(stderr, "Object isn't a valid 2-manifold! Modify your design.\n"); exit(1); } -- cgit v0.10.1 From 4396f9c80e7e4291f794f5a4095cef42cb70ad35 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 04:09:44 +0200 Subject: updated to HEAD diff --git a/libraries/MCAD b/libraries/MCAD index 903569a..60490eb 160000 --- a/libraries/MCAD +++ b/libraries/MCAD @@ -1 +1 @@ -Subproject commit 903569a9a2ae9899805185af487402f864a7fbb8 +Subproject commit 60490ebd2c722d70e06a5c12fb55d85b6f1aa1cc -- cgit v0.10.1 From 00695ba68a45702c9b2a3ecde1f0c88478e6e4aa Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 05:13:36 +0200 Subject: Killed some warnings diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index f07b900..a16d920 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -74,8 +74,8 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, bool highlight, bool background) const { std::vector primitives; - int j = 0; - for (int i = 0;; i++) { + size_t j = 0; + for (size_t i = 0;; i++) { bool last = i == chain->polysets.size(); if (last || chain->types[i] == CSGTerm::TYPE_UNION) { if (j+1 != i) { diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 598d542..c3ba2a6 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -62,7 +62,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, { glDepthFunc(GL_LEQUAL); QHash,int> polySetVisitMark; - for (int i = 0; i < chain->polysets.size(); i++) { + for (size_t i = 0; i < chain->polysets.size(); i++) { if (polySetVisitMark[QPair(chain->polysets[i], chain->matrices[i])]++ > 0) continue; double *m = chain->matrices[i]; -- cgit v0.10.1 From 7a139c2558a684beaac426ca2b8066e0961bad99 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 05:13:55 +0200 Subject: Removed some obsolete code diff --git a/src/transform.cc b/src/transform.cc index 3308e0c..f473f6a 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -56,31 +56,6 @@ public: virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; }; -using std::string; -using std::vector; - -static vector split(const string &str, const string &delim) -{ - assert(delim.size() > 0); - - vector strvec; - size_t start = 0, end = 0; - while (end != string::npos) { - end = str.find(delim, start); - // If at end, use length=maxLength. Else use length=end-start. - strvec.push_back(str.substr(start, (end == string::npos) ? string::npos : end - start)); - // If at end, use start=maxSize. Else use start=end+delimiter. - start = ((end > (string::npos - delim.size())) ? string::npos : end + delim.size()); - } - return strvec; -} - -template static bool from_string(T &t, const string &s) -{ - std::istringstream iss(s); - return !(iss >> t).fail(); -} - AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const { TransformNode *node = new TransformNode(inst); @@ -239,13 +214,13 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti } } - vector evaluatednodes = inst->evaluateChildren(); + std::vector evaluatednodes = inst->evaluateChildren(); node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); return node; } -string TransformNode::toString() const +std::string TransformNode::toString() const { std::stringstream stream; @@ -265,7 +240,7 @@ string TransformNode::toString() const return stream.str(); } -string TransformNode::name() const +std::string TransformNode::name() const { return "transform"; } -- cgit v0.10.1 From 512e7bb1bead9cf76c5f17fdda3b83a6e162fb4c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 05:14:29 +0200 Subject: bugfix: command-line crash on parser error diff --git a/src/openscad.cc b/src/openscad.cc index f7db633..1c9c8df 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -299,6 +299,7 @@ int main(int argc, char **argv) fclose(fp); text << commandline_commands; root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false); + if (!root_module) exit(1); } QDir::setCurrent(fileInfo.absolutePath()); -- cgit v0.10.1 From 0188ed74fae0eb4479b9131002304b440e1010e9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 05:14:52 +0200 Subject: Removed duplicate error message on parser error diff --git a/src/mainwin.cc b/src/mainwin.cc index c937279..c4925d5 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -730,18 +730,7 @@ fail: if (parser_error_pos < 0) { PRINT("ERROR: Compilation failed! (no top level object found)"); } else { - int line = 1; - QByteArray pb = this->last_compiled_doc.toAscii(); - char *p = pb.data(); - for (int i = 0; i < parser_error_pos; i++) { - if (p[i] == '\n') - line++; - if (p[i] == 0) { - line = -1; - break; - } - } - PRINTF("ERROR: Compilation failed! (parser error in line %d)", line); + PRINT("ERROR: Compilation failed!"); } if (procevents) QApplication::processEvents(); -- cgit v0.10.1 From 90f7e4f82ed7b3c94875493f9e6354833878509e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 05:20:11 +0200 Subject: bugfix: off export from the command-line was broken diff --git a/src/openscad.cc b/src/openscad.cc index 1c9c8df..c5933f3 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -339,9 +339,9 @@ int main(int argc, char **argv) fprintf(stderr, "Object isn't a valid 2-manifold! Modify your design.\n"); exit(1); } - std::ofstream fstream(stl_output_file); + std::ofstream fstream(off_output_file); if (!fstream.is_open()) { - PRINTF("Can't open file \"%s\" for export", stl_output_file); + PRINTF("Can't open file \"%s\" for export", off_output_file); } else { export_off(&root_N, fstream, NULL); -- cgit v0.10.1 From 673d73cf31fdafa0dc03876cde0db5b4aab10d1c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 06:54:50 +0200 Subject: Don't try exporting a non-3D object to stl or off diff --git a/src/openscad.cc b/src/openscad.cc index c5933f3..c3ee389 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -320,7 +320,11 @@ int main(int argc, char **argv) } if (stl_output_file) { - if (root_N.dim == 3 && !root_N.p3->is_simple()) { + if (root_N.dim != 3) { + fprintf(stderr, "Current top level object is not a 3D object.\n"); + exit(1); + } + if (!root_N.p3->is_simple()) { fprintf(stderr, "Object isn't a valid 2-manifold! Modify your design.\n"); exit(1); } @@ -335,7 +339,11 @@ int main(int argc, char **argv) } if (off_output_file) { - if (root_N.dim == 3 && !root_N.p3->is_simple()) { + if (root_N.dim != 3) { + fprintf(stderr, "Current top level object is not a 3D object.\n"); + exit(1); + } + if (!root_N.p3->is_simple()) { fprintf(stderr, "Object isn't a valid 2-manifold! Modify your design.\n"); exit(1); } -- cgit v0.10.1 From 4d1cf0d0a0f20b8e81a82328efad0960849b0694 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 06:55:12 +0200 Subject: Localization indicator of CGAL errors diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 440637a..34911b1 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -602,7 +602,7 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) } } catch (CGAL::Assertion_exception e) { - PRINTF("CGAL error: %s", e.what()); + PRINTF("CGAL error in CGA_Nef_polyhedron3(): %s", e.what()); CGAL::set_error_behaviour(old_behaviour); return CGAL_Nef_polyhedron(); } diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 79e9f1f..bef873c 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -137,7 +137,7 @@ CGAL_Polyhedron *createPolyhedronFromPolySet(const PolySet &ps) P->delegate(builder); } catch (CGAL::Assertion_exception e) { - PRINTF("CGAL error: %s", e.what()); + PRINTF("CGAL error in CGAL_Build_PolySet: %s", e.what()); CGAL::set_error_behaviour(old_behaviour); } return P; diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc index e4a4908..a587987 100644 --- a/src/dxftess-cgal.cc +++ b/src/dxftess-cgal.cc @@ -158,7 +158,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool /* do_tr } catch (CGAL::Assertion_exception e) { - PRINTF("CGAL error: %s", e.what()); + PRINTF("CGAL error in dxf_tesselate(): %s", e.what()); CGAL::set_error_behaviour(old_behaviour); return; } -- cgit v0.10.1 From 5ce3d4ff8df274bbbb1b5dbd272179ad5765ded1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 08:21:53 +0200 Subject: Added child-tests diff --git a/testdata/scad/features/child-tests.scad b/testdata/scad/features/child-tests.scad new file mode 100644 index 0000000..e4e3572 --- /dev/null +++ b/testdata/scad/features/child-tests.scad @@ -0,0 +1,34 @@ +$fn=16; + +module parent() { + for (i=[0:2]) { + translate([2.5*i,0,0]) child(i); + } +} + +// Normal +parent() { + sphere(); + cylinder(h=2, center=true); + cube(2, center=true); +} + +// No children +parent(); + +// Too few children +translate([0,3,0]) parent() { sphere(); } + +// No parameter to child +module parent2() { + child(); +} + +translate([2.5,3,0]) parent2() { cylinder(h=2, center=true); sphere(); } + +// Negative parameter to child +module parent3() { + child(-1); +} + +translate([5,3,0]) parent3() { cube(); sphere(); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f7fd320..1934b86 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -234,7 +234,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/render-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/projection-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/assign-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/include-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/include-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/child-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/child-tests-expected.png b/tests/regression/cgalpngtest/child-tests-expected.png new file mode 100644 index 0000000..ed6207c Binary files /dev/null and b/tests/regression/cgalpngtest/child-tests-expected.png differ diff --git a/tests/regression/opencsgtest/child-tests-expected.png b/tests/regression/opencsgtest/child-tests-expected.png new file mode 100644 index 0000000..e8ea39b Binary files /dev/null and b/tests/regression/opencsgtest/child-tests-expected.png differ -- cgit v0.10.1 From 6659ad47b0b07b66b62ca79f3929d361733cc67a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 08:52:21 +0200 Subject: Updated boolean handling of if/else diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 7b9a000..97af740 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -8,6 +8,7 @@ o New import() statement reads the correct file format based on the filename ext (.stl, .dxf and .off is supported) o The color() statement now supports an alpha parameter, e.g. color(c=[1,0,0], alpha=0.4) o The color() statement now supports specifying colors as strings, e.g. color("Red") +o if() and else() can now take any value type as parameter. false, 0, empty string and empty vector or illegal value type will evaluate as false, everything else as true. Bugfixes: o square() crashed if any of the dimensions were zero diff --git a/src/control.cc b/src/control.cc index c39b74a..492b909 100644 --- a/src/control.cc +++ b/src/control.cc @@ -149,7 +149,7 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation if (type == IF) { const IfElseModuleInstantiation *ifelse = dynamic_cast(inst); - if (ifelse->argvalues.size() > 0 && ifelse->argvalues[0].type == Value::BOOL && ifelse->argvalues[0].b) { + if (ifelse->argvalues.size() > 0 && ifelse->argvalues[0].toBool()) { std::vector evaluatednodes = ifelse->evaluateChildren(); node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } diff --git a/src/value.cc b/src/value.cc index 34566bd..53fd6dc 100644 --- a/src/value.cc +++ b/src/value.cc @@ -361,6 +361,30 @@ std::string Value::toString() const return stream.str(); } +bool Value::toBool() const +{ + switch (this->type) { + case STRING: + return this->text.size() > 0; + break; + case VECTOR: + return this->vec.size() > 0; + break; + case RANGE: + return true; + break; + case NUMBER: + return this->num != 0; + break; + case BOOL: + return this->b; + break; + default: + return false; + break; + } +} + /*! Append a value to this vector. This must be of type VECTOR. diff --git a/src/value.h b/src/value.h index 2003460..fb6500c 100644 --- a/src/value.h +++ b/src/value.h @@ -61,6 +61,8 @@ public: std::string toString() const; + bool toBool() const; + void append(Value *val); private: -- cgit v0.10.1 From a18dd3961d96ac7f0bc38ab554170d29a99451e5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 08:52:31 +0200 Subject: Added ifelse-tests diff --git a/testdata/scad/features/ifelse-tests.scad b/testdata/scad/features/ifelse-tests.scad new file mode 100644 index 0000000..d8c777b --- /dev/null +++ b/testdata/scad/features/ifelse-tests.scad @@ -0,0 +1,44 @@ +if (true) cube(2, true); +else cylinder(r=1,h=2); + +translate([3,0,0]) + if (false) cylinder(r=1,h=2); + else cube(2, true); + +translate([0,3,0]) + if (false) cylinder(r=1,h=2); + else if (true) cube(2, true); + else sphere(); + +translate([3,3,0]) + if (false) cylinder(r=1,h=2); + else if (false) sphere(); + else cube(2, true); + +translate([6,0,0]) + if (0) cylinder(r=1,h=2); + else cube(2, true); + +translate([6,3,0]) + if (1) cube(2, true); + else cylinder(r=1,h=2); + +translate([9,0,0]) + if ("") cylinder(r=1,h=2); + else cube(2, true); + +translate([9,3,0]) + if ("hello") cube(2, true); + else cylinder(r=1,h=2); + +translate([12,0,0]) + if ([]) cylinder(r=1,h=2); + else cube(2, true); + +translate([12,3,0]) + if ([1,2,3]) cube(2, true); + else cylinder(r=1,h=2); + +translate([15,0,0]) + if (ILLEGAL) cylinder(r=1,h=2); + else cube(2, true); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1934b86..0453fdd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -235,7 +235,8 @@ LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/projection-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/assign-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/features/include-tests.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/features/child-tests.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/child-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/features/ifelse-tests.scad) #LIST(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../examples/example001.scad) add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES}) diff --git a/tests/regression/cgalpngtest/ifelse-tests-expected.png b/tests/regression/cgalpngtest/ifelse-tests-expected.png new file mode 100644 index 0000000..fcda7bc Binary files /dev/null and b/tests/regression/cgalpngtest/ifelse-tests-expected.png differ diff --git a/tests/regression/opencsgtest/ifelse-tests-expected.png b/tests/regression/opencsgtest/ifelse-tests-expected.png new file mode 100644 index 0000000..6dae4df Binary files /dev/null and b/tests/regression/opencsgtest/ifelse-tests-expected.png differ -- cgit v0.10.1 From a23edb4adc6a29e59565ce6009c980659a79423a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 09:24:10 +0200 Subject: Catch CGAL assert on certain minkowski operations diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index 6dcbdea..ea08ca1 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -1,10 +1,13 @@ #include "CGAL_Nef_polyhedron.h" #include "cgal.h" #include "cgalutils.h" +#include "printutils.h" #include "polyset.h" #include "dxfdata.h" #include "dxftess.h" #include +#include +#include CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other) { @@ -31,8 +34,15 @@ extern CGAL_Nef_polyhedron2 minkowski2(const CGAL_Nef_polyhedron2 &a, const CGAL CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &other) { - if (this->dim == 2) (*this->p2) = minkowski2(*this->p2, *other.p2); - else if (this->dim == 3) (*this->p3) = CGAL::minkowski_sum_3(*this->p3, *other.p3); + CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); + try { + if (this->dim == 2) (*this->p2) = minkowski2(*this->p2, *other.p2); + else if (this->dim == 3) (*this->p3) = CGAL::minkowski_sum_3(*this->p3, *other.p3); + } + catch (CGAL::Assertion_exception e) { + PRINTF("CGAL error in minkowski %s", e.what()); + CGAL::set_error_behaviour(old_behaviour); + } return *this; } diff --git a/testdata/scad/bugs/minkowski-assert.scad b/testdata/scad/bugs/minkowski-assert.scad new file mode 100644 index 0000000..4ae81da --- /dev/null +++ b/testdata/scad/bugs/minkowski-assert.scad @@ -0,0 +1,8 @@ +minkowski() { + cube(20, center=true); + rotate([20, 30, 40]) + difference() { + cube(5, center=true); + cube([1, 1, 10], center=true); + } +} -- cgit v0.10.1 From fc6a27432eed4061b670b48383115e99e53b7feb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 09:24:23 +0200 Subject: sync diff --git a/doc/TODO.txt b/doc/TODO.txt index 5fe22bb..1fdcd99 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -40,10 +40,6 @@ Using STL-imported models is tricky and triggers multiple issues: CRASH BUGS ---------- o Broken polyhedron() entities are not correctly detected and cause CGAL segfaults -o union() { - linear_extrude(height=10, twist=90) circle(5); - translate([7,-5,0]) linear_extrude(height=10, twist=180) polygon(points = [[0,0], [10,0], [5,10]]); - } o non-convex minkowski example from chrysn fails with an exception USER INTERFACE @@ -118,6 +114,7 @@ o Misc - Save: Ask for confirmation if file has been externally changed - Rename OpenCSG and CGAL to smth. not specific to the underlying libraries (e.g Preview, Render) + - Recent files not updated on SaveAs o Cmd-line - Add verbose option (PRINT command from mainwin.cc and progress output) @@ -144,7 +141,6 @@ o Function-Module-Interface - Pass a function to a module instanciation (e.g. for dynamic extrusion paths) o Language Frontend - Allow local variables and functions everywhere (not only on module level) - - allow any expression to be evaluated as boolean (!0 = true, 0 = false) - Rethink for vs. intersection_for vs. group. Should for loops generate child lists instead, and make these passable to other modules or accessible by child()? -- cgit v0.10.1 From b59be3fbc228c59a04582b71e4fa2ca2680fe52d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 09:52:02 +0200 Subject: Update recent file also on save/saveas diff --git a/src/MainWindow.h b/src/MainWindow.h index 0745935..0ba3bd9 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -92,6 +92,7 @@ private slots: void actionOpen(); void actionOpenRecent(); void actionOpenExample(); + void updateRecentFiles(); void clearRecentFiles(); void updateRecentFileActions(); void actionSave(); diff --git a/src/mainwin.cc b/src/mainwin.cc index c4925d5..8dc1fea 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -340,6 +340,7 @@ MainWindow::MainWindow(const QString &filename) } else { setFileName(""); } + updateRecentFileActions(); connect(editor->document(), SIGNAL(contentsChanged()), this, SLOT(animateUpdateDocChanged())); #ifdef _QCODE_EDIT_ @@ -491,6 +492,7 @@ MainWindow::openFile(const QString &new_filename) setFileName(new_filename); load(); + updateRecentFiles(); } void @@ -510,13 +512,6 @@ MainWindow::setFileName(const QString &filename) QString infoFileName = fileinfo.absoluteFilePath(); if (!infoFileName.isEmpty()) { this->fileName = infoFileName; - QSettings settings; // already set up properly via main.cpp - QStringList files = settings.value("recentFileList").toStringList(); - files.removeAll(this->fileName); - files.prepend(this->fileName); - while (files.size() > maxRecentFiles) - files.removeLast(); - settings.setValue("recentFileList", files); } else { this->fileName = fileinfo.fileName(); } @@ -525,6 +520,21 @@ MainWindow::setFileName(const QString &filename) QDir::setCurrent(fileinfo.dir().absolutePath()); } +} + +void MainWindow::updateRecentFiles() +{ + // Check that the canonical file path exists - only update recent files + // if it does. Should prevent empty list items on initial open etc. + QFileInfo fileinfo(this->fileName); + QString infoFileName = fileinfo.absoluteFilePath(); + QSettings settings; // already set up properly via main.cpp + QStringList files = settings.value("recentFileList").toStringList(); + files.removeAll(infoFileName); + files.prepend(infoFileName); + while (files.size() > maxRecentFiles) files.removeLast(); + settings.setValue("recentFileList", files); + foreach(QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { @@ -533,6 +543,7 @@ MainWindow::setFileName(const QString &filename) } } + void MainWindow::updatedFps() { bool fps_ok; @@ -988,6 +999,7 @@ void MainWindow::actionSave() this->editor->setContentModified(false); } clearCurrentOutput(); + updateRecentFiles(); } } -- cgit v0.10.1 From 256f38d3c28f3d19374521dc598909b4925d433a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 09:52:09 +0200 Subject: sync diff --git a/doc/TODO.txt b/doc/TODO.txt index 1fdcd99..ef86c26 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -40,7 +40,6 @@ Using STL-imported models is tricky and triggers multiple issues: CRASH BUGS ---------- o Broken polyhedron() entities are not correctly detected and cause CGAL segfaults -o non-convex minkowski example from chrysn fails with an exception USER INTERFACE -------------- @@ -114,7 +113,6 @@ o Misc - Save: Ask for confirmation if file has been externally changed - Rename OpenCSG and CGAL to smth. not specific to the underlying libraries (e.g Preview, Render) - - Recent files not updated on SaveAs o Cmd-line - Add verbose option (PRINT command from mainwin.cc and progress output) @@ -136,6 +134,7 @@ o Built-in modules o Advanced Transformations - Add statement for refinement via surface subdivision - Add statement for intersections in cartesian product of childs + - non-convex minkowski example from chrysn fails with an exception (testdata/scad/bugs/minkowski-assert.scad) o Function-Module-Interface - Pass a module instanciation to a function (e.g. for a volume() function) - Pass a function to a module instanciation (e.g. for dynamic extrusion paths) -- cgit v0.10.1 From 328897c1f28e0d438aa678891f8d5a45b114f267 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 8 Sep 2011 10:20:58 +0200 Subject: sync diff --git a/doc/TODO.txt b/doc/TODO.txt index ef86c26..e48ea70 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -130,7 +130,7 @@ o 2D Subsystem o Built-in modules - extrude*: Allow the base 2D primitive to have a Z value - rotate_extrude(): Allow for specification of start/stop/sweep angle? - - Convex hull of multiple 2D or 2D objects + - Convex hull of 3D objects o Advanced Transformations - Add statement for refinement via surface subdivision - Add statement for intersections in cartesian product of childs @@ -167,7 +167,6 @@ o Misc o Grammar - dim->name -> dim->label - A random(seed) function - - import_*() -> *_import() (consistent prefix vs. postfix) - linear_extrude()/rotate_extrude(): Cumbersome names? -> (extrude, revolve, lathe, sweep ?) o Hollow donut problem When extruding a 2D CSG tree (e.g. a polygon with a hole), the hole -- cgit v0.10.1 From cbba974d3ac1edeb716a1384a2262ed5447fa9e6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 9 Sep 2011 05:53:05 +0200 Subject: Initial attempt of cleaning up polyset handling. PolySet no longer keeps a refcount, basic cache mechanism is in place, instantiating polysets are controlled through PolySetEvaluator diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 34911b1..6bd7092 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -216,7 +216,6 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) dxf_tesselate(&ps, *dd, 0, true, false, 0); N = evaluateCGALMesh(ps); - ps.refcount = 0; delete dd; } else if (N.dim == 3) { @@ -240,18 +239,15 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) if (state.isPostfix()) { if (!isCached(node)) { // Apply polyset operation - PolySet *ps = node.evaluate_polyset(AbstractPolyNode::RENDER_CGAL, &this->psevaluator); + PolySet *ps = this->psevaluator.getPolySet(node); CGAL_Nef_polyhedron N; if (ps) { try { N = evaluateCGALMesh(*ps); // print_messages_pop(); node.progress_report(); - - ps->unlink(); } - catch (...) { // Don't leak the PolySet on ProgressCancelException - ps->unlink(); + catch (...) { throw; } } @@ -316,7 +312,7 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node // print_messages_push(); - PolySet *ps = node.evaluate_polyset(AbstractPolyNode::RENDER_CGAL); + PolySet *ps = this->psevaluator->getPolySet(node); if (ps) { try { CGAL_Nef_polyhedron N = ps->evaluateCSGMesh(); diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index 2453c25..a8e9844 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -49,6 +49,9 @@ private: QHash &cache; const Tree &tree; +public: + // FIXME: Do we need to make this visible? Used for cache management + // Note: psevaluator constructor needs this->tree to be initialized first PolySetCGALEvaluator psevaluator; }; diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc index f8e914b..4d165ce 100644 --- a/src/CGALRenderer.cc +++ b/src/CGALRenderer.cc @@ -68,7 +68,7 @@ CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root) CGALRenderer::~CGALRenderer() { - if (this->polyset) this->polyset->unlink(); + delete this->polyset; delete this->polyhedron; } diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index dafa6a6..40e46b9 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -108,10 +108,12 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node) { if (state.isPostfix()) { CSGTerm *t1 = NULL; - PolySet *ps = node.evaluate_polyset(AbstractPolyNode::RENDER_OPENCSG, this->psevaluator); - if (ps) { - t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, - ps, node.modinst, node); + if (this->psevaluator) { + PolySet *ps = this->psevaluator->getPolySet(node); + if (ps) { + t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, + ps, node.modinst, node); + } } this->stored_term[node.index()] = t1; addToParent(state, node); @@ -182,10 +184,9 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node) { if (state.isPostfix()) { CSGTerm *t1 = NULL; - // FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this. PolySet *ps = NULL; if (this->psevaluator) { - ps = this->psevaluator->evaluatePolySet(node, AbstractPolyNode::RENDER_OPENCSG); + ps = this->psevaluator->getPolySet(node); } if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, @@ -204,7 +205,7 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node) // FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this. PolySet *ps = NULL; if (this->psevaluator) { - ps = this->psevaluator->evaluatePolySet(node, AbstractPolyNode::RENDER_OPENCSG); + ps = this->psevaluator->getPolySet(node); } if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index a648587..9f9ab6e 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -1,5 +1,6 @@ #include "PolySetCGALEvaluator.h" #include "cgal.h" +#include "cgalutils.h" #include "polyset.h" #include "CGALEvaluator.h" #include "projectionnode.h" @@ -15,11 +16,13 @@ #include "openscad.h" // get_fragments_from_r() #include -PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, AbstractPolyNode::render_mode_e) +PolySetCGALEvaluator::PolySetCGALEvaluator(CGALEvaluator &cgalevaluator) + : PolySetEvaluator(cgalevaluator.getTree()), cgalevaluator(cgalevaluator) { - const string &cacheid = this->cgalevaluator.getTree().getString(node); - if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps->link(); +} +PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) +{ // Before projecting, union all children CGAL_Nef_polyhedron sum; BOOST_FOREACH (AbstractNode * v, node.getChildren()) { @@ -38,47 +41,46 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr if (node.cut_mode) { - PolySet *cube = new PolySet(); + PolySet cube; double infval = 1e8, eps = 0.1; double x1 = -infval, x2 = +infval, y1 = -infval, y2 = +infval, z1 = 0, z2 = eps; - cube->append_poly(); // top - cube->append_vertex(x1, y1, z2); - cube->append_vertex(x2, y1, z2); - cube->append_vertex(x2, y2, z2); - cube->append_vertex(x1, y2, z2); - - cube->append_poly(); // bottom - cube->append_vertex(x1, y2, z1); - cube->append_vertex(x2, y2, z1); - cube->append_vertex(x2, y1, z1); - cube->append_vertex(x1, y1, z1); - - cube->append_poly(); // side1 - cube->append_vertex(x1, y1, z1); - cube->append_vertex(x2, y1, z1); - cube->append_vertex(x2, y1, z2); - cube->append_vertex(x1, y1, z2); - - cube->append_poly(); // side2 - cube->append_vertex(x2, y1, z1); - cube->append_vertex(x2, y2, z1); - cube->append_vertex(x2, y2, z2); - cube->append_vertex(x2, y1, z2); - - cube->append_poly(); // side3 - cube->append_vertex(x2, y2, z1); - cube->append_vertex(x1, y2, z1); - cube->append_vertex(x1, y2, z2); - cube->append_vertex(x2, y2, z2); - - cube->append_poly(); // side4 - cube->append_vertex(x1, y2, z1); - cube->append_vertex(x1, y1, z1); - cube->append_vertex(x1, y1, z2); - cube->append_vertex(x1, y2, z2); - CGAL_Nef_polyhedron Ncube = this->cgalevaluator.evaluateCGALMesh(*cube); - cube->unlink(); + cube.append_poly(); // top + cube.append_vertex(x1, y1, z2); + cube.append_vertex(x2, y1, z2); + cube.append_vertex(x2, y2, z2); + cube.append_vertex(x1, y2, z2); + + cube.append_poly(); // bottom + cube.append_vertex(x1, y2, z1); + cube.append_vertex(x2, y2, z1); + cube.append_vertex(x2, y1, z1); + cube.append_vertex(x1, y1, z1); + + cube.append_poly(); // side1 + cube.append_vertex(x1, y1, z1); + cube.append_vertex(x2, y1, z1); + cube.append_vertex(x2, y1, z2); + cube.append_vertex(x1, y1, z2); + + cube.append_poly(); // side2 + cube.append_vertex(x2, y1, z1); + cube.append_vertex(x2, y2, z1); + cube.append_vertex(x2, y2, z2); + cube.append_vertex(x2, y1, z2); + + cube.append_poly(); // side3 + cube.append_vertex(x2, y2, z1); + cube.append_vertex(x1, y2, z1); + cube.append_vertex(x1, y2, z2); + cube.append_vertex(x2, y2, z2); + + cube.append_poly(); // side4 + cube.append_vertex(x1, y2, z1); + cube.append_vertex(x1, y1, z1); + cube.append_vertex(x1, y1, z2); + cube.append_vertex(x1, y2, z2); + CGAL_Nef_polyhedron Ncube = this->cgalevaluator.evaluateCGALMesh(cube); // N.p3 *= CGAL_Nef_polyhedron3(CGAL_Plane(0, 0, 1, 0), CGAL_Nef_polyhedron3::INCLUDED); sum *= Ncube; @@ -109,7 +111,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr } next_ps3_polygon_cut_mode:; } - ps3->unlink(); + delete ps3; } else { @@ -166,16 +168,14 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node, Abstr (*np.p2) += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); } } + delete ps3; DxfData *dxf = np.convertToDxfData(); dxf_tesselate(ps, *dxf, 0, true, false, 0); dxf_border_to_ps(ps, *dxf); - ps3->unlink(); delete dxf; } cant_project_non_simple_polyhedron: - - this->cache.insert(cacheid, new cache_entry(ps->link())); return ps; } @@ -251,12 +251,8 @@ static void add_slice(PolySet *ps, const DxfData &dxf, DxfData::Path &path, doub } } -PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, - AbstractPolyNode::render_mode_e) +PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node) { - const string &cacheid = this->cgalevaluator.getTree().getString(node); - if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps->link(); - DxfData *dxf; if (node.filename.empty()) @@ -283,7 +279,6 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfLinearExtrudeNode &node, } PolySet *ps = extrudeDxfData(node, *dxf); - this->cache.insert(cacheid, new cache_entry(ps->link())); delete dxf; return ps; } @@ -354,12 +349,8 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const DxfLinearExtrudeNode &node, return ps; } -PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, - AbstractPolyNode::render_mode_e) +PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node) { - const string &cacheid = this->cgalevaluator.getTree().getString(node); - if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps->link(); - DxfData *dxf; if (node.filename.empty()) @@ -386,20 +377,20 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node, } PolySet *ps = rotateDxfData(node, *dxf); - this->cache.insert(cacheid, new cache_entry(ps->link())); delete dxf; return ps; } -PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e) +PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node) { CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node); PolySet *ps = NULL; if (!N.empty()) ps = N.convertToPolyset(); + return ps; } -PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node, AbstractPolyNode::render_mode_e) +PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node) { CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node); PolySet *ps = NULL; @@ -479,6 +470,6 @@ PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, D } delete[] points; } - + return ps; } diff --git a/src/PolySetCGALEvaluator.h b/src/PolySetCGALEvaluator.h index f5b8665..2aa5b13 100644 --- a/src/PolySetCGALEvaluator.h +++ b/src/PolySetCGALEvaluator.h @@ -10,14 +10,13 @@ class PolySetCGALEvaluator : public PolySetEvaluator { public: - PolySetCGALEvaluator(class CGALEvaluator &CGALEvaluator) : - PolySetEvaluator(), cgalevaluator(CGALEvaluator) { } + PolySetCGALEvaluator(class CGALEvaluator &cgalevaluator); virtual ~PolySetCGALEvaluator() { } - virtual PolySet *evaluatePolySet(const ProjectionNode &node, AbstractPolyNode::render_mode_e); - virtual PolySet *evaluatePolySet(const DxfLinearExtrudeNode &node, AbstractPolyNode::render_mode_e); - virtual PolySet *evaluatePolySet(const DxfRotateExtrudeNode &node, AbstractPolyNode::render_mode_e); - virtual PolySet *evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e); - virtual PolySet *evaluatePolySet(const RenderNode &node, AbstractPolyNode::render_mode_e); + virtual PolySet *evaluatePolySet(const ProjectionNode &node); + virtual PolySet *evaluatePolySet(const DxfLinearExtrudeNode &node); + virtual PolySet *evaluatePolySet(const DxfRotateExtrudeNode &node); + virtual PolySet *evaluatePolySet(const CgaladvNode &node); + virtual PolySet *evaluatePolySet(const RenderNode &node); protected: PolySet *extrudeDxfData(const DxfLinearExtrudeNode &node, class DxfData &dxf); diff --git a/src/PolySetEvaluator.cc b/src/PolySetEvaluator.cc index 56acb1d..2808686 100644 --- a/src/PolySetEvaluator.cc +++ b/src/PolySetEvaluator.cc @@ -2,14 +2,31 @@ #include "printutils.h" #include "polyset.h" -PolySetEvaluator *PolySetEvaluator::global_evaluator = NULL; +/*! + The task of PolySetEvaluator is to create, keep track of and cache PolySet instances. -PolySetEvaluator::cache_entry::cache_entry(PolySet *ps) : - ps(ps), msg(print_messages_stack.last()) + All instances of PolySet which are not strictly temporary should be requested through this + class. +*/ + +PolySet *PolySetEvaluator::getPolySet(const AbstractNode &node) +{ + const string &cacheid = this->tree.getString(node); + if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps; + + PolySet *ps = node.evaluate_polyset(this); + this->cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0); + return ps; +} + +PolySetEvaluator::cache_entry::cache_entry(PolySet *ps) + : ps(ps) { + if (print_messages_stack.size() > 0) this->msg = print_messages_stack.last(); } -PolySetEvaluator::cache_entry::~cache_entry() +void PolySetEvaluator::printCache() { - ps->unlink(); + PRINTF("PolySets in cache: %d", this->cache.size()); + PRINTF("Polygons in cache: %d", this->cache.totalCost()); } diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h index 70ec7ed..1a97cb5 100644 --- a/src/PolySetEvaluator.h +++ b/src/PolySetEvaluator.h @@ -3,39 +3,42 @@ #include "myqhash.h" #include "node.h" +#include "Tree.h" #include class PolySetEvaluator { public: - enum EvaluateMode { EVALUATE_CGAL, EVALUATE_OPENCSG }; - PolySetEvaluator() : cache(100) {} - + PolySetEvaluator(const Tree &tree) : cache(100000), tree(tree) {} virtual ~PolySetEvaluator() {} - virtual PolySet *evaluatePolySet(const class ProjectionNode &, AbstractPolyNode::render_mode_e) = 0; - virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; - virtual PolySet *evaluatePolySet(const class DxfRotateExtrudeNode &, AbstractPolyNode::render_mode_e) = 0; - virtual PolySet *evaluatePolySet(const class CgaladvNode &, AbstractPolyNode::render_mode_e) = 0; - virtual PolySet *evaluatePolySet(const class RenderNode &, AbstractPolyNode::render_mode_e) = 0; + const Tree &getTree() const { return this->tree; } + + virtual PolySet *getPolySet(const class AbstractNode &); + + virtual PolySet *evaluatePolySet(const class ProjectionNode &) { return NULL; } + virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &) { return NULL; } + virtual PolySet *evaluatePolySet(const class DxfRotateExtrudeNode &) { return NULL; } + virtual PolySet *evaluatePolySet(const class CgaladvNode &) { return NULL; } + virtual PolySet *evaluatePolySet(const class RenderNode &) { return NULL; } void clearCache() { this->cache.clear(); } - + void printCache(); protected: struct cache_entry { class PolySet *ps; QString msg; cache_entry(PolySet *ps); - ~cache_entry(); + ~cache_entry() { } }; QCache cache; private: - static PolySetEvaluator *global_evaluator; + const Tree &tree; }; #endif diff --git a/src/cgaladv.cc b/src/cgaladv.cc index 8ffd626..5014133 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -29,6 +29,7 @@ #include "context.h" #include "builtin.h" #include "printutils.h" +#include "PolySetEvaluator.h" #include #include #include @@ -92,6 +93,11 @@ AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiat return node; } +PolySet *CgaladvNode::evaluate_polyset(PolySetEvaluator *ps) const +{ + return ps->evaluatePolySet(*this); +} + void register_builtin_cgaladv() { builtin_modules["minkowski"] = new CgaladvModule(MINKOWSKI); diff --git a/src/cgaladvnode.h b/src/cgaladvnode.h index a3f8bea..8e769bf 100644 --- a/src/cgaladvnode.h +++ b/src/cgaladvnode.h @@ -24,6 +24,7 @@ public: } virtual std::string toString() const; virtual std::string name() const; + PolySet *evaluate_polyset(class PolySetEvaluator *ps) const; Value path; std::string subdiv_type; diff --git a/src/csgterm.cc b/src/csgterm.cc index f24a41a..91497b4 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -167,8 +167,6 @@ CSGTerm *CSGTerm::link() void CSGTerm::unlink() { if (--refcounter <= 0) { - if (polyset) - polyset->unlink(); if (left) left->unlink(); if (right) diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index fd37ffa..ca98b66 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -124,19 +124,16 @@ void register_builtin_dxf_linear_extrude() builtin_modules["linear_extrude"] = new DxfLinearExtrudeModule(); } -PolySet *DxfLinearExtrudeNode::evaluate_polyset(render_mode_e mode, - PolySetEvaluator *evaluator) const +PolySet *DxfLinearExtrudeNode::evaluate_polyset(PolySetEvaluator *evaluator) const { if (!evaluator) { PRINTF("WARNING: No suitable PolySetEvaluator found for %s module!", this->name().c_str()); - PolySet *ps = new PolySet(); - ps->is2d = true; - return ps; + return NULL; } print_messages_push(); - PolySet *ps = evaluator->evaluatePolySet(*this, mode); + PolySet *ps = evaluator->evaluatePolySet(*this); print_messages_pop(); diff --git a/src/dxflinextrudenode.h b/src/dxflinextrudenode.h index 3c3beca..360fd28 100644 --- a/src/dxflinextrudenode.h +++ b/src/dxflinextrudenode.h @@ -24,7 +24,7 @@ public: double origin_x, origin_y, scale; bool center, has_twist; std::string filename, layername; - virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; + virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const; }; #endif diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index 5889cee..cd585aa 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -100,19 +100,16 @@ void register_builtin_dxf_rotate_extrude() builtin_modules["rotate_extrude"] = new DxfRotateExtrudeModule(); } -PolySet *DxfRotateExtrudeNode::evaluate_polyset(render_mode_e mode, - PolySetEvaluator *evaluator) const +PolySet *DxfRotateExtrudeNode::evaluate_polyset(PolySetEvaluator *evaluator) const { if (!evaluator) { PRINTF("WARNING: No suitable PolySetEvaluator found for %s module!", this->name().c_str()); - PolySet *ps = new PolySet(); - ps->is2d = true; - return ps; + return NULL; } print_messages_push(); - PolySet *ps = evaluator->evaluatePolySet(*this, mode); + PolySet *ps = evaluator->evaluatePolySet(*this); print_messages_pop(); diff --git a/src/dxfrotextrudenode.h b/src/dxfrotextrudenode.h index 797b53a..e0ade82 100644 --- a/src/dxfrotextrudenode.h +++ b/src/dxfrotextrudenode.h @@ -22,7 +22,7 @@ public: double fn, fs, fa; double origin_x, origin_y, scale; std::string filename, layername; - virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; + virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const; }; #endif diff --git a/src/import.cc b/src/import.cc index 0fdc156..f64a8f6 100644 --- a/src/import.cc +++ b/src/import.cc @@ -111,7 +111,7 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati return node; } -PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const +PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *evaluator) const { PolySet *p = NULL; diff --git a/src/importnode.h b/src/importnode.h index 49e9f16..c08ecc9 100644 --- a/src/importnode.h +++ b/src/importnode.h @@ -27,7 +27,7 @@ public: int convexity; double fn, fs, fa; double origin_x, origin_y, scale; - virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; + virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const; }; #endif diff --git a/src/mainwin.cc b/src/mainwin.cc index 8dc1fea..2fd876c 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -790,6 +790,7 @@ void MainWindow::compileCSG(bool procevents) if (procevents) QApplication::processEvents(); } + psevaluator.printCache(); } catch (ProgressCancelException e) { PRINT("CSG generation cancelled."); @@ -1225,6 +1226,7 @@ void MainWindow::actionRenderCGAL() QHash cache; CGALEvaluator evaluator(cache, this->tree); this->root_N = new CGAL_Nef_polyhedron(evaluator.evaluateCGALMesh(*this->root_node)); + evaluator.psevaluator.printCache(); } catch (ProgressCancelException e) { PRINT("Rendering cancelled."); diff --git a/src/node.h b/src/node.h index a3e1cad..577ddd5 100644 --- a/src/node.h +++ b/src/node.h @@ -36,6 +36,8 @@ public: overloaded to provide specialization for e.g. CSG nodes, primitive nodes etc. Used for human-readable output. */ virtual std::string name() const; + /*! Should return a PolySet of the given geometry. Returns NULL if smth. goes wrong */ + virtual class PolySet *evaluate_polyset(class PolySetEvaluator *evaluator) const { return NULL; } // FIXME: Make return value a reference const std::vector &getChildren() const { @@ -79,10 +81,6 @@ public: RENDER_CGAL, RENDER_OPENCSG }; - /*! Should return a PolySet of the given geometry. It's normal to return an - empty PolySet if smth. is wrong, but don't return NULL unless we change the calling - strategy for this method. */ - virtual class PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *evaluator) const = 0; }; std::ostream &operator<<(std::ostream &stream, const AbstractNode &node); diff --git a/src/polyset.cc b/src/polyset.cc index db37b49..23b9876 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -36,28 +36,12 @@ #include #include -PolySet::PolySet() : grid(GRID_FINE) +PolySet::PolySet() : grid(GRID_FINE), is2d(false), convexity(1) { - is2d = false; - convexity = 1; - refcount = 1; } PolySet::~PolySet() { - assert(refcount == 0); -} - -PolySet* PolySet::link() -{ - refcount++; - return this; -} - -void PolySet::unlink() -{ - if (--refcount == 0) - delete this; } void PolySet::append_poly() diff --git a/src/polyset.h b/src/polyset.h index e80d182..c59d86a 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -51,10 +51,6 @@ public: void render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo = NULL) const; void render_edges(colormode_e colormode, csgmode_e csgmode) const; - - int refcount; - PolySet *link(); - void unlink(); }; #endif diff --git a/src/primitives.cc b/src/primitives.cc index 50a197d..08b9c62 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -102,7 +102,7 @@ public: primitive_type_e type; int convexity; Value points, paths, triangles; - virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; + virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const; }; AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const @@ -273,7 +273,7 @@ static void generate_circle(point2d *circle, double r, int fragments) } } -PolySet *PrimitiveNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const +PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const { PolySet *p = new PolySet(); @@ -518,7 +518,7 @@ sphere_next_r2: double x,y; if (!this->points.vec[i]->getv2(x, y)) { PRINTF("ERROR: Unable to convert point at index %d to a vec2 of numbers", i); - p->unlink(); + delete p; return NULL; } dd.points.push_back(Vector2d(x, y)); diff --git a/src/projection.cc b/src/projection.cc index 5a7ea6e..2c9d821 100644 --- a/src/projection.cc +++ b/src/projection.cc @@ -79,18 +79,16 @@ AbstractNode *ProjectionModule::evaluate(const Context *ctx, const ModuleInstant return node; } -PolySet *ProjectionNode::evaluate_polyset(render_mode_e mode, PolySetEvaluator *evaluator) const +PolySet *ProjectionNode::evaluate_polyset(PolySetEvaluator *evaluator) const { if (!evaluator) { PRINTF("WARNING: No suitable PolySetEvaluator found for %s module!", this->name().c_str()); - PolySet *ps = new PolySet(); - ps->is2d = true; - return ps; + return NULL; } print_messages_push(); - PolySet *ps = evaluator->evaluatePolySet(*this, mode); + PolySet *ps = evaluator->evaluatePolySet(*this); print_messages_pop(); diff --git a/src/projectionnode.h b/src/projectionnode.h index 4c29b7b..41cca7c 100644 --- a/src/projectionnode.h +++ b/src/projectionnode.h @@ -19,7 +19,7 @@ public: int convexity; bool cut_mode; - virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *evaluator) const; + virtual PolySet *evaluate_polyset(class PolySetEvaluator *evaluator) const; }; #endif diff --git a/src/render.cc b/src/render.cc index 48a8535..f08423a 100644 --- a/src/render.cc +++ b/src/render.cc @@ -26,15 +26,12 @@ #include "rendernode.h" #include "module.h" -#include "polyset.h" #include "context.h" -#include "dxfdata.h" -#include "dxftess.h" -#include "csgterm.h" #include "builtin.h" #include "printutils.h" #include "progress.h" #include "visitor.h" +#include "PolySetEvaluator.h" #include #include @@ -68,6 +65,11 @@ AbstractNode *RenderModule::evaluate(const Context *ctx, const ModuleInstantiati return node; } +class PolySet *RenderNode::evaluate_polyset(PolySetEvaluator *ps) const +{ + return ps->evaluatePolySet(*this); +} + void register_builtin_render() { builtin_modules["render"] = new RenderModule(); diff --git a/src/rendernode.h b/src/rendernode.h index 9138c29..9e49baf 100644 --- a/src/rendernode.h +++ b/src/rendernode.h @@ -14,6 +14,7 @@ public: } virtual std::string toString() const; virtual std::string name() const { return "render"; } + PolySet *evaluate_polyset(class PolySetEvaluator *ps) const; int convexity; }; diff --git a/src/surface.cc b/src/surface.cc index 22598bf..35449ed 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -62,7 +62,7 @@ public: std::string filename; bool center; int convexity; - virtual PolySet *evaluate_polyset(render_mode_e mode, class PolySetEvaluator *) const; + virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const; }; AbstractNode *SurfaceModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const @@ -98,17 +98,17 @@ void register_builtin_surface() builtin_modules["surface"] = new SurfaceModule(); } -PolySet *SurfaceNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const +PolySet *SurfaceNode::evaluate_polyset(class PolySetEvaluator *) const { - PolySet *p = new PolySet(); handle_dep(filename); QFile f(QString::fromStdString(filename)); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { PRINTF("WARNING: Can't open DAT file `%s'.", filename.c_str()); - return p; + return NULL; } + PolySet *p = new PolySet(); int lines = 0, columns = 0; boost::unordered_map,double> data; double min_val = 0; diff --git a/tests/csgtermtest.cc b/tests/csgtermtest.cc index 26b809a..7c37b0a 100644 --- a/tests/csgtermtest.cc +++ b/tests/csgtermtest.cc @@ -24,6 +24,7 @@ */ #include "myqhash.h" +#include "PolySetEvaluator.h" #include "CSGTermEvaluator.h" #include "CSGTextCache.h" #include "openscad.h" @@ -145,7 +146,8 @@ int main(int argc, char **argv) vector highlights; vector background; - CSGTermEvaluator evaluator(tree); + PolySetEvaluator psevaluator(tree); + CSGTermEvaluator evaluator(tree, &psevaluator); CSGTerm *root_term = evaluator.evaluateCSGTerm(*root_node, highlights, background); // cout << "Stored terms: " << evaluator.stored_term.size() << "\n"; diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index 72f7488..28c0daa 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -144,8 +144,7 @@ int main(int argc, char *argv[]) CsgInfo csgInfo; QHash cache; CGALEvaluator cgalevaluator(cache, tree); - PolySetCGALEvaluator psevaluator(cgalevaluator); - CSGTermEvaluator evaluator(tree, &psevaluator); + CSGTermEvaluator evaluator(tree, &cgalevaluator.psevaluator); CSGTerm *root_raw_term = evaluator.evaluateCSGTerm(*root_node, csgInfo.highlight_terms, csgInfo.background_terms); diff --git a/tests/regression/csgtermtest/allmodules-expected.txt b/tests/regression/csgtermtest/allmodules-expected.txt index d7a04fc..f544c01 100644 --- a/tests/regression/csgtermtest/allmodules-expected.txt +++ b/tests/regression/csgtermtest/allmodules-expected.txt @@ -1 +1 @@ -(((((((((((((linear_extrude14 + linear_extrude15) + rotate_extrude16) + rotate_extrude17) + import21) + cube23) + sphere24) + cylinder25) + polyhedron26) + square27) + circle28) + polygon29) + projection30) + surface32) +((((((cube23 + sphere24) + cylinder25) + polyhedron26) + square27) + circle28) + polygon29) diff --git a/tests/regression/csgtermtest/dxf_linear_extrude-expected.txt b/tests/regression/csgtermtest/dxf_linear_extrude-expected.txt index bebcc7a..a40cf60 100644 --- a/tests/regression/csgtermtest/dxf_linear_extrude-expected.txt +++ b/tests/regression/csgtermtest/dxf_linear_extrude-expected.txt @@ -1 +1 @@ -linear_extrude2 +No top-level CSG object diff --git a/tests/regression/csgtermtest/dxf_rotate_extrude-expected.txt b/tests/regression/csgtermtest/dxf_rotate_extrude-expected.txt index 318aa70..a40cf60 100644 --- a/tests/regression/csgtermtest/dxf_rotate_extrude-expected.txt +++ b/tests/regression/csgtermtest/dxf_rotate_extrude-expected.txt @@ -1 +1 @@ -rotate_extrude2 +No top-level CSG object diff --git a/tests/regression/csgtermtest/linear_extrude-expected.txt b/tests/regression/csgtermtest/linear_extrude-expected.txt index bebcc7a..a40cf60 100644 --- a/tests/regression/csgtermtest/linear_extrude-expected.txt +++ b/tests/regression/csgtermtest/linear_extrude-expected.txt @@ -1 +1 @@ -linear_extrude2 +No top-level CSG object diff --git a/tests/regression/csgtermtest/projection-expected.txt b/tests/regression/csgtermtest/projection-expected.txt index 2a4c47e..a40cf60 100644 --- a/tests/regression/csgtermtest/projection-expected.txt +++ b/tests/regression/csgtermtest/projection-expected.txt @@ -1 +1 @@ -projection2 +No top-level CSG object diff --git a/tests/regression/csgtermtest/rotate_extrude-expected.txt b/tests/regression/csgtermtest/rotate_extrude-expected.txt index 318aa70..a40cf60 100644 --- a/tests/regression/csgtermtest/rotate_extrude-expected.txt +++ b/tests/regression/csgtermtest/rotate_extrude-expected.txt @@ -1 +1 @@ -rotate_extrude2 +No top-level CSG object diff --git a/tests/regression/csgtermtest/surface-expected.txt b/tests/regression/csgtermtest/surface-expected.txt index d0e3459..a40cf60 100644 --- a/tests/regression/csgtermtest/surface-expected.txt +++ b/tests/regression/csgtermtest/surface-expected.txt @@ -1 +1 @@ -surface2 +No top-level CSG object -- cgit v0.10.1 From 09cc0496f7ce61e2bcbce80e067e0fac8054599a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 9 Sep 2011 06:10:33 +0200 Subject: Make PolySet cache global diff --git a/src/PolySetEvaluator.cc b/src/PolySetEvaluator.cc index 2808686..6426d6e 100644 --- a/src/PolySetEvaluator.cc +++ b/src/PolySetEvaluator.cc @@ -9,13 +9,15 @@ class. */ +QCache PolySetEvaluator::cache(100000); + PolySet *PolySetEvaluator::getPolySet(const AbstractNode &node) { const string &cacheid = this->tree.getString(node); - if (this->cache.contains(cacheid)) return this->cache[cacheid]->ps; + if (cache.contains(cacheid)) return cache[cacheid]->ps; PolySet *ps = node.evaluate_polyset(this); - this->cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0); + cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0); return ps; } @@ -27,6 +29,6 @@ PolySetEvaluator::cache_entry::cache_entry(PolySet *ps) void PolySetEvaluator::printCache() { - PRINTF("PolySets in cache: %d", this->cache.size()); - PRINTF("Polygons in cache: %d", this->cache.totalCost()); + PRINTF("PolySets in cache: %d", cache.size()); + PRINTF("Polygons in cache: %d", cache.totalCost()); } diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h index 1a97cb5..b7c490d 100644 --- a/src/PolySetEvaluator.h +++ b/src/PolySetEvaluator.h @@ -9,7 +9,7 @@ class PolySetEvaluator { public: - PolySetEvaluator(const Tree &tree) : cache(100000), tree(tree) {} + PolySetEvaluator(const Tree &tree) : tree(tree) {} virtual ~PolySetEvaluator() {} const Tree &getTree() const { return this->tree; } @@ -23,7 +23,7 @@ public: virtual PolySet *evaluatePolySet(const class RenderNode &) { return NULL; } void clearCache() { - this->cache.clear(); + cache.clear(); } void printCache(); protected: @@ -35,7 +35,7 @@ protected: ~cache_entry() { } }; - QCache cache; + static QCache cache; private: const Tree &tree; -- cgit v0.10.1 From b087e68e5430c3dde6adfe452becbaba0f680196 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 01:53:25 +0200 Subject: Don't leave files open on parse errors diff --git a/src/lexer.l b/src/lexer.l index 4c0ddea..3cd4a19 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -33,6 +33,7 @@ #include #include #include +#include //isatty for visual c++ #ifdef _MSC_VER @@ -71,6 +72,7 @@ extern const char *parser_source_path; void includefile(); QDir sourcepath(); QStack path_stack; +QStack openfiles; QString filename; QString filepath; @@ -122,6 +124,7 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { if (!yyin) { PRINTF("WARNING: Can't open input file `%s'.", filename); } else { + openfiles.append(yyin); yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); BEGIN(INITIAL); } @@ -129,10 +132,12 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { } <> { - if(!path_stack.isEmpty()) + if(!path_stack.empty()) path_stack.pop(); - if (yyin && yyin != stdin) - fclose(yyin); + if (yyin && yyin != stdin) { + assert(!openfiles.empty()); + fclose(openfiles.pop()); + } yypop_buffer_state(); if (!YY_CURRENT_BUFFER) yyterminate(); @@ -183,7 +188,7 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { QDir sourcepath() { - if(!path_stack.isEmpty()) + if(!path_stack.empty()) return path_stack.top(); return QDir(parser_source_path); @@ -214,8 +219,19 @@ void includefile() path_stack.pop(); return; } + openfiles.append(yyin); filename.clear(); yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); } +/*! + In case of an error, this will make sure we clean up our custom data structures + and close all files. +*/ +void lexerdestroy() +{ + foreach (FILE *f, openfiles) fclose(f); + openfiles.clear(); + path_stack.clear(); +} diff --git a/src/parser.y b/src/parser.y index 2d78d1f..33fbc3f 100644 --- a/src/parser.y +++ b/src/parser.y @@ -575,6 +575,7 @@ void yyerror (char const *s) module = NULL; } +extern void lexerdestroy(); extern FILE *lexerin; extern const char *parser_input_buffer; const char *parser_input_buffer; @@ -592,7 +593,7 @@ AbstractModule *parse(const char *text, const char *path, int debug) parserdebug = debug; parserparse(); - + lexerdestroy(); lexerlex_destroy(); if (!module) -- cgit v0.10.1 From c0641d6916775309d64944ca121cc736f0c8d7a1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 07:33:18 +0200 Subject: Reenabled PolySet caching. Pass shared_ptrs to polysets around to better manage memory diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 6bd7092..51fe41a 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -91,8 +91,7 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg chnode->progress_report(); } } - const std::string &cacheid = this->tree.getString(node); - this->cache.insert(cacheid, N); + this->cache.insert(this->tree.getString(node), N); } extern CGAL_Nef_polyhedron2 *convexhull2(std::list a); @@ -123,8 +122,7 @@ void CGALEvaluator::applyHull(const CgaladvNode &node) if (all2d) { CGAL_Nef_polyhedron N(convexhull2(polys)); - const std::string &cacheid = this->tree.getString(node); - this->cache.insert(cacheid, N); + this->cache.insert(this->tree.getString(node), N); } } } @@ -225,8 +223,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) node.matrix[2], node.matrix[6], node.matrix[10], node.matrix[14], node.matrix[15]); N.p3->transform(t); } - const std::string &cacheid = this->tree.getString(node); - this->cache.insert(cacheid, N); + this->cache.insert(this->tree.getString(node), N); } addToParent(state, node); } @@ -239,7 +236,7 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) if (state.isPostfix()) { if (!isCached(node)) { // Apply polyset operation - PolySet *ps = this->psevaluator.getPolySet(node); + shared_ptr ps = this->psevaluator.getPolySet(node, false); CGAL_Nef_polyhedron N; if (ps) { try { @@ -251,8 +248,7 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) throw; } } - const std::string &cacheid = this->tree.getString(node); - this->cache.insert(cacheid, N); + this->cache.insert(this->tree.getString(node), N); } addToParent(state, node); } @@ -312,7 +308,7 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node // print_messages_push(); - PolySet *ps = this->psevaluator->getPolySet(node); + shared_ptr ps = this->psevaluator->getPolySet(node, false); if (ps) { try { CGAL_Nef_polyhedron N = ps->evaluateCSGMesh(); @@ -320,11 +316,9 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node // print_messages_pop(); node.progress_report(); - ps->unlink(); return N; } catch (...) { // Don't leak the PolySet on ProgressCancelException - ps->unlink(); throw; } } diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 40e46b9..ebea89c 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -86,11 +86,11 @@ Response CSGTermEvaluator::visit(State &state, const AbstractIntersectionNode &n } static CSGTerm *evaluate_csg_term_from_ps(const State &state, - vector &highlights, - vector &background, - PolySet *ps, - const ModuleInstantiation *modinst, - const AbstractNode &node) + vector &highlights, + vector &background, + const shared_ptr &ps, + const ModuleInstantiation *modinst, + const AbstractNode &node) { std::stringstream stream; stream << node.name() << node.index(); @@ -109,7 +109,7 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node) if (state.isPostfix()) { CSGTerm *t1 = NULL; if (this->psevaluator) { - PolySet *ps = this->psevaluator->getPolySet(node); + shared_ptr ps = this->psevaluator->getPolySet(node, true); if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, ps, node.modinst, node); @@ -184,9 +184,9 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node) { if (state.isPostfix()) { CSGTerm *t1 = NULL; - PolySet *ps = NULL; + shared_ptr ps; if (this->psevaluator) { - ps = this->psevaluator->getPolySet(node); + ps = this->psevaluator->getPolySet(node, true); } if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, @@ -203,9 +203,9 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node) if (state.isPostfix()) { CSGTerm *t1 = NULL; // FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this. - PolySet *ps = NULL; + shared_ptr ps; if (this->psevaluator) { - ps = this->psevaluator->getPolySet(node); + ps = this->psevaluator->getPolySet(node, true); } if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index a16d920..4a86c5c 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -28,6 +28,7 @@ #include "OpenCSGRenderer.h" #include "polyset.h" #include "csgterm.h" +#include "stl-utils.h" #ifdef ENABLE_OPENCSG # include #endif @@ -37,13 +38,13 @@ class OpenCSGPrim : public OpenCSG::Primitive public: OpenCSGPrim(OpenCSG::Operation operation, unsigned int convexity) : OpenCSG::Primitive(operation, convexity) { } - PolySet *p; + shared_ptr ps; double *m; int csgmode; virtual void render() { glPushMatrix(); glMultMatrixd(m); - p->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); + ps->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m); glPopMatrix(); } }; @@ -120,11 +121,12 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, OpenCSGPrim *prim = new OpenCSGPrim(chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? OpenCSG::Subtraction : OpenCSG::Intersection, chain->polysets[i]->convexity); - prim->p = chain->polysets[i]; + prim->ps = chain->polysets[i]; prim->m = chain->matrices[i]; prim->csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; if (highlight) prim->csgmode += 20; else if (background) prim->csgmode += 10; primitives.push_back(prim); } + std::for_each(primitives.begin(), primitives.end(), del_fun()); } diff --git a/src/PolySetEvaluator.cc b/src/PolySetEvaluator.cc index 6426d6e..a2bdca5 100644 --- a/src/PolySetEvaluator.cc +++ b/src/PolySetEvaluator.cc @@ -11,18 +11,26 @@ QCache PolySetEvaluator::cache(100000); -PolySet *PolySetEvaluator::getPolySet(const AbstractNode &node) +/*! + Factory method returning a PolySet from the given node. If the + node is already cached, the cached PolySet will be returned + otherwise a new PolySet will be created from the node. If cache is + true, the newly created PolySet will be cached. + */ +shared_ptr PolySetEvaluator::getPolySet(const AbstractNode &node, bool cache) { - const string &cacheid = this->tree.getString(node); - if (cache.contains(cacheid)) return cache[cacheid]->ps; + std::string cacheid = this->tree.getString(node); + if (this->cache.contains(cacheid)) { + PRINTF("Cache hit: %s", cacheid.substr(0, 40).c_str()); + return this->cache[cacheid]->ps; + } - PolySet *ps = node.evaluate_polyset(this); - cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0); + shared_ptr ps(node.evaluate_polyset(this)); + if (cache) this->cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0); return ps; } -PolySetEvaluator::cache_entry::cache_entry(PolySet *ps) - : ps(ps) +PolySetEvaluator::cache_entry::cache_entry(const shared_ptr &ps) : ps(ps) { if (print_messages_stack.size() > 0) this->msg = print_messages_stack.last(); } diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h index b7c490d..6319e55 100644 --- a/src/PolySetEvaluator.h +++ b/src/PolySetEvaluator.h @@ -5,6 +5,7 @@ #include "node.h" #include "Tree.h" #include +#include "memory.h" class PolySetEvaluator { @@ -14,7 +15,7 @@ public: const Tree &getTree() const { return this->tree; } - virtual PolySet *getPolySet(const class AbstractNode &); + virtual shared_ptr getPolySet(const class AbstractNode &, bool cache); virtual PolySet *evaluatePolySet(const class ProjectionNode &) { return NULL; } virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &) { return NULL; } @@ -22,16 +23,16 @@ public: virtual PolySet *evaluatePolySet(const class CgaladvNode &) { return NULL; } virtual PolySet *evaluatePolySet(const class RenderNode &) { return NULL; } - void clearCache() { + static void clearCache() { cache.clear(); } void printCache(); protected: struct cache_entry { - class PolySet *ps; + shared_ptr ps; QString msg; - cache_entry(PolySet *ps); + cache_entry(const shared_ptr &ps); ~cache_entry() { } }; diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index c3ba2a6..956fc11 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -63,7 +63,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, glDepthFunc(GL_LEQUAL); QHash,int> polySetVisitMark; for (size_t i = 0; i < chain->polysets.size(); i++) { - if (polySetVisitMark[QPair(chain->polysets[i], chain->matrices[i])]++ > 0) + if (polySetVisitMark[QPair(chain->polysets[i].get(), chain->matrices[i])]++ > 0) continue; double *m = chain->matrices[i]; double *c = chain->colors[i]; diff --git a/src/Tree.cc b/src/Tree.cc index a451f24..7615a3d 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -2,12 +2,18 @@ #include "nodedumper.h" #include +#include + +static bool filter(char c) +{ + return c == ' ' || c == '\n' || c == '\t' || c == '\r'; +} /*! - Returns the cached string representation of the subtree rootet by \a node. + Returns the cached string representation of the subtree rooted by \a node. If node is not cached, the cache will be rebuilt. */ -const std::string &Tree::getString(const AbstractNode &node) const +const std::string Tree::getString(const AbstractNode &node) const { assert(this->root_node); if (!this->nodecache.contains(node)) { @@ -17,7 +23,10 @@ const std::string &Tree::getString(const AbstractNode &node) const assert(this->nodecache.contains(*this->root_node) && "NodeDumper failed to create a cache"); } - return this->nodecache[node]; + std::string str = this->nodecache[node]; + str.erase(std::remove_if(str.begin(), str.end(), filter), str.end()); + + return str; } /*! diff --git a/src/Tree.h b/src/Tree.h index 2c3f0b8..5fda0c3 100644 --- a/src/Tree.h +++ b/src/Tree.h @@ -20,8 +20,7 @@ public: void setRoot(const AbstractNode *root); const AbstractNode *root() const { return this->root_node; } - // FIXME: Really return a reference? - const string &getString(const AbstractNode &node) const; + const string getString(const AbstractNode &node) const; private: const AbstractNode *root_node; diff --git a/src/csgterm.cc b/src/csgterm.cc index 91497b4..8306aaf 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -47,24 +47,17 @@ */ -CSGTerm::CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], const std::string &label) +CSGTerm::CSGTerm(const shared_ptr &polyset, const double matrix[16], const double color[4], const std::string &label) + : type(TYPE_PRIMITIVE), polyset(polyset), label(label), left(NULL), right(NULL) { - this->type = TYPE_PRIMITIVE; - this->polyset = polyset; - this->label = label; - this->left = NULL; - this->right = NULL; for (int i = 0; i < 16; i++) this->m[i] = matrix[i]; for (int i = 0; i < 4; i++) this->color[i] = color[i]; refcounter = 1; } CSGTerm::CSGTerm(type_e type, CSGTerm *left, CSGTerm *right) + : type(type), left(left), right(right) { - this->type = type; - this->polyset = NULL; - this->left = left; - this->right = right; refcounter = 1; } @@ -195,7 +188,7 @@ CSGChain::CSGChain() { } -void CSGChain::add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, std::string label) +void CSGChain::add(const shared_ptr &polyset, double *m, double *color, CSGTerm::type_e type, std::string label) { polysets.push_back(polyset); matrices.push_back(m); diff --git a/src/csgterm.h b/src/csgterm.h index 2a89ef1..c12b7ae 100644 --- a/src/csgterm.h +++ b/src/csgterm.h @@ -4,6 +4,7 @@ #include #include #include "polyset.h" +#include "memory.h" class CSGTerm { @@ -16,7 +17,7 @@ public: }; type_e type; - PolySet *polyset; + shared_ptr polyset; std::string label; CSGTerm *left; CSGTerm *right; @@ -24,7 +25,7 @@ public: double color[4]; int refcounter; - CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], const std::string &label); + CSGTerm(const shared_ptr &polyset, const double matrix[16], const double color[4], const std::string &label); CSGTerm(type_e type, CSGTerm *left, CSGTerm *right); CSGTerm *normalize(); @@ -38,7 +39,7 @@ public: class CSGChain { public: - std::vector polysets; + std::vector > polysets; std::vector matrices; std::vector colors; std::vector types; @@ -46,7 +47,7 @@ public: CSGChain(); - void add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, std::string label); + void add(const shared_ptr &polyset, double *m, double *color, CSGTerm::type_e type, std::string label); void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); std::string dump(); diff --git a/src/mainwin.cc b/src/mainwin.cc index 2fd876c..e4d9684 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1497,7 +1497,7 @@ void MainWindow::actionExportImage() void MainWindow::actionFlushCaches() { // FIXME: Polycache -> PolySetEvaluator -// FIXME: PolySetEvaluator->clearCache(); + PolySetEvaluator::clearCache(); #ifdef ENABLE_CGAL // FIXME: Flush caches through whatever channels we have // CGALEvaluator::evaluator()->getCache().clear(); diff --git a/src/node.h b/src/node.h index 577ddd5..9f25627 100644 --- a/src/node.h +++ b/src/node.h @@ -37,7 +37,7 @@ public: Used for human-readable output. */ virtual std::string name() const; /*! Should return a PolySet of the given geometry. Returns NULL if smth. goes wrong */ - virtual class PolySet *evaluate_polyset(class PolySetEvaluator *evaluator) const { return NULL; } + virtual class PolySet *evaluate_polyset(class PolySetEvaluator *) const { return NULL; } // FIXME: Make return value a reference const std::vector &getChildren() const { -- cgit v0.10.1 From dc7eeb30d06a928a30ee47a765be3e5a61288d35 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 07:33:35 +0200 Subject: Testing ccache diff --git a/setenv_mjau.sh b/setenv_mjau.sh index b8012f6..f6a16d2 100644 --- a/setenv_mjau.sh +++ b/setenv_mjau.sh @@ -5,3 +5,7 @@ export DYLD_LIBRARY_PATH=$MACOSX_DEPLOY_DIR/lib #export CGALDIR=$PWD/../install/CGAL-3.6 #export QCODEEDITDIR=$PWD/../qcodeedit-2.2.3/install #export DYLD_LIBRARY_PATH=$OPENCSGDIR/lib:$QCODEEDITDIR/lib + +# ccache: +export PATH=/opt/local/libexec/ccache:$PATH +export CCACHE_BASEDIR=$PWD/.. -- cgit v0.10.1 From 18e97e0bd3f6bda4fdcd17de2a85173ba59b6b00 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 09:10:31 +0200 Subject: Fixed bug introduced by the new PolySet cache; string filtering done in the wrong place, refactored cache into separate class diff --git a/openscad.pro b/openscad.pro index 4541eaa..baa9899 100644 --- a/openscad.pro +++ b/openscad.pro @@ -159,6 +159,7 @@ HEADERS += src/renderer.h \ src/traverser.h \ src/nodecache.h \ src/nodedumper.h \ + src/PolySetCache.h \ src/PolySetEvaluator.h \ src/CSGTermEvaluator.h \ src/myqhash.h \ @@ -208,6 +209,7 @@ SOURCES += src/openscad.cc \ src/qhash.cc \ src/Tree.cc \ src/mathc99.cc \ + src/PolySetCache.cc \ src/PolySetEvaluator.cc cgal { diff --git a/src/PolySetCache.cc b/src/PolySetCache.cc new file mode 100644 index 0000000..89c511e --- /dev/null +++ b/src/PolySetCache.cc @@ -0,0 +1,21 @@ +#include "PolySetCache.h" +#include "printutils.h" +#include "PolySet.h" + +PolySetCache *PolySetCache::inst = NULL; + +void PolySetCache::insert(const std::string &id, const shared_ptr &ps) +{ + this->cache.insert(id, new cache_entry(ps), ps ? ps->polygons.size() : 0); +} + +void PolySetCache::print() +{ + PRINTF("PolySets in cache: %d", this->cache.size()); + PRINTF("Polygons in cache: %d", this->cache.totalCost()); +} + +PolySetCache::cache_entry::cache_entry(const shared_ptr &ps) : ps(ps) +{ + if (print_messages_stack.size() > 0) this->msg = print_messages_stack.last(); +} diff --git a/src/PolySetCache.h b/src/PolySetCache.h new file mode 100644 index 0000000..da51c5e --- /dev/null +++ b/src/PolySetCache.h @@ -0,0 +1,34 @@ +#ifndef POLYSETCACHE_H_ +#define POLYSETCACHE_H_ + +#include "myqhash.h" +#include +#include "memory.h" + +class PolySetCache +{ +public: + PolySetCache(size_t polygonlimit = 100000) : cache(polygonlimit) {} + + static PolySetCache *instance() { if (!inst) inst = new PolySetCache; return inst; } + + bool contains(const std::string &id) const { return this->cache.contains(id); } + shared_ptr get(const std::string &id) const { return this->cache[id]->ps; } + void insert(const std::string &id, const shared_ptr &ps); + void clear() { cache.clear(); } + void print(); + +private: + static PolySetCache *inst; + + struct cache_entry { + shared_ptr ps; + QString msg; + cache_entry(const shared_ptr &ps); + ~cache_entry() { } + }; + + QCache cache; +}; + +#endif diff --git a/src/PolySetEvaluator.cc b/src/PolySetEvaluator.cc index a2bdca5..e46ae59 100644 --- a/src/PolySetEvaluator.cc +++ b/src/PolySetEvaluator.cc @@ -1,3 +1,4 @@ +#include "PolySetCache.h" #include "PolySetEvaluator.h" #include "printutils.h" #include "polyset.h" @@ -9,7 +10,10 @@ class. */ -QCache PolySetEvaluator::cache(100000); +static bool filter(char c) +{ + return c == ' ' || c == '\n' || c == '\t' || c == '\r'; +} /*! Factory method returning a PolySet from the given node. If the @@ -20,23 +24,15 @@ QCache PolySetEvaluator::cache(10000 shared_ptr PolySetEvaluator::getPolySet(const AbstractNode &node, bool cache) { std::string cacheid = this->tree.getString(node); - if (this->cache.contains(cacheid)) { - PRINTF("Cache hit: %s", cacheid.substr(0, 40).c_str()); - return this->cache[cacheid]->ps; + cacheid.erase(std::remove_if(cacheid.begin(), cacheid.end(), filter), cacheid.end()); + + if (PolySetCache::instance()->contains(cacheid)) { +// For cache debugging +// PRINTF("Cache hit: %s", cacheid.substr(0, 40).c_str()); + return PolySetCache::instance()->get(cacheid); } shared_ptr ps(node.evaluate_polyset(this)); - if (cache) this->cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0); + if (cache) PolySetCache::instance()->insert(cacheid, ps); return ps; } - -PolySetEvaluator::cache_entry::cache_entry(const shared_ptr &ps) : ps(ps) -{ - if (print_messages_stack.size() > 0) this->msg = print_messages_stack.last(); -} - -void PolySetEvaluator::printCache() -{ - PRINTF("PolySets in cache: %d", cache.size()); - PRINTF("Polygons in cache: %d", cache.totalCost()); -} diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h index 6319e55..833b079 100644 --- a/src/PolySetEvaluator.h +++ b/src/PolySetEvaluator.h @@ -1,10 +1,8 @@ #ifndef POLYSETEVALUATOR_H_ #define POLYSETEVALUATOR_H_ -#include "myqhash.h" #include "node.h" #include "Tree.h" -#include #include "memory.h" class PolySetEvaluator @@ -23,21 +21,6 @@ public: virtual PolySet *evaluatePolySet(const class CgaladvNode &) { return NULL; } virtual PolySet *evaluatePolySet(const class RenderNode &) { return NULL; } - static void clearCache() { - cache.clear(); - } - void printCache(); -protected: - - struct cache_entry { - shared_ptr ps; - QString msg; - cache_entry(const shared_ptr &ps); - ~cache_entry() { } - }; - - static QCache cache; - private: const Tree &tree; }; diff --git a/src/Tree.cc b/src/Tree.cc index 7615a3d..e791e12 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -4,16 +4,11 @@ #include #include -static bool filter(char c) -{ - return c == ' ' || c == '\n' || c == '\t' || c == '\r'; -} - /*! Returns the cached string representation of the subtree rooted by \a node. If node is not cached, the cache will be rebuilt. */ -const std::string Tree::getString(const AbstractNode &node) const +const std::string &Tree::getString(const AbstractNode &node) const { assert(this->root_node); if (!this->nodecache.contains(node)) { @@ -23,10 +18,7 @@ const std::string Tree::getString(const AbstractNode &node) const assert(this->nodecache.contains(*this->root_node) && "NodeDumper failed to create a cache"); } - std::string str = this->nodecache[node]; - str.erase(std::remove_if(str.begin(), str.end(), filter), str.end()); - - return str; + return this->nodecache[node]; } /*! diff --git a/src/Tree.h b/src/Tree.h index 5fda0c3..5df5bba 100644 --- a/src/Tree.h +++ b/src/Tree.h @@ -20,7 +20,7 @@ public: void setRoot(const AbstractNode *root); const AbstractNode *root() const { return this->root_node; } - const string getString(const AbstractNode &node) const; + const string &getString(const AbstractNode &node) const; private: const AbstractNode *root_node; diff --git a/src/mainwin.cc b/src/mainwin.cc index e4d9684..130e237 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -24,6 +24,7 @@ * */ +#include "PolySetCache.h" #include "MainWindow.h" #include "openscad.h" // examplesdir #include "Preferences.h" @@ -790,7 +791,7 @@ void MainWindow::compileCSG(bool procevents) if (procevents) QApplication::processEvents(); } - psevaluator.printCache(); + PolySetCache::instance()->print(); } catch (ProgressCancelException e) { PRINT("CSG generation cancelled."); @@ -1226,7 +1227,7 @@ void MainWindow::actionRenderCGAL() QHash cache; CGALEvaluator evaluator(cache, this->tree); this->root_N = new CGAL_Nef_polyhedron(evaluator.evaluateCGALMesh(*this->root_node)); - evaluator.psevaluator.printCache(); + PolySetCache::instance()->print(); } catch (ProgressCancelException e) { PRINT("Rendering cancelled."); @@ -1497,7 +1498,7 @@ void MainWindow::actionExportImage() void MainWindow::actionFlushCaches() { // FIXME: Polycache -> PolySetEvaluator - PolySetEvaluator::clearCache(); + PolySetCache::instance()->clear(); #ifdef ENABLE_CGAL // FIXME: Flush caches through whatever channels we have // CGALEvaluator::evaluator()->getCache().clear(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0453fdd..08ae030 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -110,6 +110,7 @@ set(COMMON_SOURCES ../src/nodedumper.cc ../src/traverser.cc ../src/PolySetEvaluator.cc + ../src/PolySetCache.cc ../src/Tree.cc ${FLEX_OpenSCADlexer_OUTPUTS} ${BISON_OpenSCADparser_OUTPUTS}) diff --git a/tests/dumptest.cc b/tests/dumptest.cc index 9af7154..65424b3 100644 --- a/tests/dumptest.cc +++ b/tests/dumptest.cc @@ -144,7 +144,7 @@ int main(int argc, char **argv) string dumpstdstr = tree.getString(*root_node); string dumpstdstr_cached = tree.getString(*root_node); - if (dumpstdstr != dumpstdstr_cached) rc = 1; + assert(dumpstdstr == dumpstdstr_cached); std::cout << dumpstdstr << "\n"; -- cgit v0.10.1 From 95949cf961d84f65ad9bfb9f2dec7361059ca515 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 10:51:55 +0200 Subject: Implemented CGAL caching diff --git a/openscad.pro b/openscad.pro index baa9899..1abca19 100644 --- a/openscad.pro +++ b/openscad.pro @@ -217,6 +217,7 @@ HEADERS += src/cgal.h \ src/cgalfwd.h \ src/cgalutils.h \ src/CGALEvaluator.h \ + src/CGALCache.h \ src/PolySetCGALEvaluator.h \ src/CGALRenderer.h \ src/CGAL_Nef_polyhedron.h @@ -224,6 +225,7 @@ HEADERS += src/cgal.h \ SOURCES += src/cgalutils.cc \ src/CGALEvaluator.cc \ src/PolySetCGALEvaluator.cc \ + src/CGALCache.cc \ src/CGALRenderer.cc \ src/CGAL_Nef_polyhedron.cc \ src/CGAL_Nef_polyhedron_DxfData.cc \ diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 51fe41a..d950cb8 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -1,3 +1,4 @@ +#include "CGALCache.h" #include "CGALEvaluator.h" #include "visitor.h" #include "state.h" @@ -11,6 +12,7 @@ #include "dxfdata.h" #include "dxftess.h" +#include "CGALCache.h" #include "cgal.h" #include "cgalutils.h" #include @@ -31,12 +33,12 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractNode &node) evaluate.execute(); assert(isCached(node)); } - return this->cache[this->tree.getString(node)]; + return CGALCache::instance()->get(this->tree.getIdString(node)); } bool CGALEvaluator::isCached(const AbstractNode &node) const { - return this->cache.contains(this->tree.getString(node)); + return CGALCache::instance()->contains(this->tree.getIdString(node)); } /*! @@ -68,10 +70,8 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr } /*! - FIXME: Let caller insert into the cache since caller might modify the result - (e.g. transform) */ -void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::CsgOp op) +CGAL_Nef_polyhedron CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::CsgOp op) { CGAL_Nef_polyhedron N; if (this->visitedchildren[node.index()].size() > 0) { @@ -84,20 +84,21 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg if (chnode->modinst->tag_background) continue; assert(isCached(*chnode)); if (N.empty()) { - N = this->cache[chcacheid].copy(); + N = CGALCache::instance()->get(chcacheid).copy(); } else { - process(N, this->cache[chcacheid], op); + process(N, CGALCache::instance()->get(chcacheid), op); } chnode->progress_report(); } } - this->cache.insert(this->tree.getString(node), N); + return N; } extern CGAL_Nef_polyhedron2 *convexhull2(std::list a); -void CGALEvaluator::applyHull(const CgaladvNode &node) +CGAL_Nef_polyhedron CGALEvaluator::applyHull(const CgaladvNode &node) { + CGAL_Nef_polyhedron N; if (this->visitedchildren[node.index()].size() > 0) { std::list polys; bool all2d = true; @@ -109,9 +110,9 @@ void CGALEvaluator::applyHull(const CgaladvNode &node) // FIXME: Don't use deep access to modinst members if (chnode->modinst->tag_background) continue; assert(isCached(*chnode)); - const CGAL_Nef_polyhedron &ch = this->cache[chcacheid]; + const CGAL_Nef_polyhedron &ch = CGALCache::instance()->get(chcacheid); if (ch.dim == 2) { - polys.push_back(ch.p2); + polys.push_back(ch.p2.get()); } else if (ch.dim == 3) { PRINT("WARNING: hull() is not implemented yet for 3D objects!"); @@ -121,10 +122,10 @@ void CGALEvaluator::applyHull(const CgaladvNode &node) } if (all2d) { - CGAL_Nef_polyhedron N(convexhull2(polys)); - this->cache.insert(this->tree.getString(node), N); + N = CGAL_Nef_polyhedron(convexhull2(polys)); } } + return N; } /* @@ -138,7 +139,10 @@ Response CGALEvaluator::visit(State &state, const AbstractNode &node) { if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { - if (!isCached(node)) applyToChildren(node, CGE_UNION); + if (!isCached(node)) { + CGAL_Nef_polyhedron N = applyToChildren(node, CGE_UNION); + CGALCache::instance()->insert(this->tree.getIdString(node), N); + } addToParent(state, node); } return ContinueTraversal; @@ -148,7 +152,10 @@ Response CGALEvaluator::visit(State &state, const AbstractIntersectionNode &node { if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { - if (!isCached(node)) applyToChildren(node, CGE_INTERSECTION); + if (!isCached(node)) { + CGAL_Nef_polyhedron N = applyToChildren(node, CGE_INTERSECTION); + CGALCache::instance()->insert(this->tree.getIdString(node), N); + } addToParent(state, node); } return ContinueTraversal; @@ -173,7 +180,8 @@ Response CGALEvaluator::visit(State &state, const CsgNode &node) default: assert(false); } - applyToChildren(node, op); + CGAL_Nef_polyhedron N = applyToChildren(node, op); + CGALCache::instance()->insert(this->tree.getIdString(node), N); } addToParent(state, node); } @@ -186,10 +194,9 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) if (state.isPostfix()) { if (!isCached(node)) { // First union all children - applyToChildren(node, CGE_UNION); + CGAL_Nef_polyhedron N = applyToChildren(node, CGE_UNION); // Then apply transform - CGAL_Nef_polyhedron N = this->cache[this->tree.getString(node)]; // If there is no geometry under the transform, N will be empty and of dim 0, // just just silently ignore such nodes if (N.dim == 2) { @@ -223,7 +230,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) node.matrix[2], node.matrix[6], node.matrix[10], node.matrix[14], node.matrix[15]); N.p3->transform(t); } - this->cache.insert(this->tree.getString(node), N); + CGALCache::instance()->insert(this->tree.getIdString(node), N); } addToParent(state, node); } @@ -239,16 +246,11 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node) shared_ptr ps = this->psevaluator.getPolySet(node, false); CGAL_Nef_polyhedron N; if (ps) { - try { - N = evaluateCGALMesh(*ps); + N = evaluateCGALMesh(*ps); // print_messages_pop(); - node.progress_report(); - } - catch (...) { - throw; - } + node.progress_report(); } - this->cache.insert(this->tree.getString(node), N); + CGALCache::instance()->insert(this->tree.getIdString(node), N); } addToParent(state, node); } @@ -260,11 +262,12 @@ Response CGALEvaluator::visit(State &state, const CgaladvNode &node) if (state.isPrefix() && isCached(node)) return PruneTraversal; if (state.isPostfix()) { if (!isCached(node)) { + CGAL_Nef_polyhedron N; CGALEvaluator::CsgOp op; switch (node.type) { case MINKOWSKI: op = CGE_MINKOWSKI; - applyToChildren(node, op); + N = applyToChildren(node, op); break; case GLIDE: PRINT("WARNING: glide() is not implemented yet!"); @@ -275,9 +278,10 @@ Response CGALEvaluator::visit(State &state, const CgaladvNode &node) return PruneTraversal; break; case HULL: - applyHull(node); + N = applyHull(node); break; } + CGALCache::instance()->insert(this->tree.getIdString(node), N); } addToParent(state, node); } @@ -293,37 +297,9 @@ void CGALEvaluator::addToParent(const State &state, const AbstractNode &node) assert(state.isPostfix()); this->visitedchildren.erase(node.index()); if (state.parent()) { - this->visitedchildren[state.parent()->index()].push_back(std::make_pair(&node, this->tree.getString(node))); - } -} - -#if 0 -/*! - Static function to evaluate CGAL meshes. - NB! This is just a support function used for development and debugging -*/ -CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node) -{ - // FIXME: Lookup Nef polyhedron in cache. - - // print_messages_push(); - - shared_ptr ps = this->psevaluator->getPolySet(node, false); - if (ps) { - try { - CGAL_Nef_polyhedron N = ps->evaluateCSGMesh(); - // FIXME: Insert into cache - // print_messages_pop(); - node.progress_report(); - - return N; - } - catch (...) { // Don't leak the PolySet on ProgressCancelException - throw; - } + this->visitedchildren[state.parent()->index()].push_back(std::make_pair(&node, this->tree.getIdString(node))); } } -#endif CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) { diff --git a/src/CGALEvaluator.h b/src/CGALEvaluator.h index a8e9844..c1b5ae8 100644 --- a/src/CGALEvaluator.h +++ b/src/CGALEvaluator.h @@ -20,8 +20,7 @@ class CGALEvaluator : public Visitor { public: enum CsgOp {CGE_UNION, CGE_INTERSECTION, CGE_DIFFERENCE, CGE_MINKOWSKI}; - // FIXME: If a cache is not given, we need to fix this ourselves - CGALEvaluator(QHash &cache, const Tree &tree) : cache(cache), tree(tree), psevaluator(*this) {} + CGALEvaluator(const Tree &tree) : tree(tree), psevaluator(*this) {} virtual ~CGALEvaluator() {} virtual Response visit(State &state, const AbstractNode &node); @@ -40,14 +39,13 @@ private: void addToParent(const State &state, const AbstractNode &node); bool isCached(const AbstractNode &node) const; void process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, CGALEvaluator::CsgOp op); - void applyToChildren(const AbstractNode &node, CGALEvaluator::CsgOp op); - void applyHull(const CgaladvNode &node); + CGAL_Nef_polyhedron applyToChildren(const AbstractNode &node, CGALEvaluator::CsgOp op); + CGAL_Nef_polyhedron applyHull(const CgaladvNode &node); string currindent; typedef list > ChildList; map visitedchildren; - QHash &cache; const Tree &tree; public: // FIXME: Do we need to make this visible? Used for cache management diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index ea08ca1..975c9a4 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -85,7 +85,7 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() CGAL_Nef_polyhedron CGAL_Nef_polyhedron::copy() const { CGAL_Nef_polyhedron copy = *this; - if (copy.p2) copy.p2 = new CGAL_Nef_polyhedron2(*copy.p2); - else if (copy.p3) copy.p3 = new CGAL_Nef_polyhedron3(*copy.p3); + if (copy.p2) copy.p2.reset(new CGAL_Nef_polyhedron2(*copy.p2)); + else if (copy.p3) copy.p3.reset(new CGAL_Nef_polyhedron3(*copy.p3)); return copy; } diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h index 616ba23..a2eedaf 100644 --- a/src/CGAL_Nef_polyhedron.h +++ b/src/CGAL_Nef_polyhedron.h @@ -4,13 +4,14 @@ #ifdef ENABLE_CGAL #include "cgalfwd.h" +#include "memory.h" class CGAL_Nef_polyhedron { public: - CGAL_Nef_polyhedron() : dim(0), p2(0), p3(0) {} - CGAL_Nef_polyhedron(CGAL_Nef_polyhedron2 *p) : dim(2), p2(p), p3(0) {} - CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) : dim(3), p2(0), p3(p) {} + CGAL_Nef_polyhedron() : dim(0) {} + CGAL_Nef_polyhedron(CGAL_Nef_polyhedron2 *p) : dim(2), p2(p) {} + CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) : dim(3), p3(p) {} ~CGAL_Nef_polyhedron() {} bool empty() const { return (dim == 0 || !p2 && !p3); } @@ -24,9 +25,8 @@ public: class DxfData *convertToDxfData() const; int dim; - // FIXME: Define ownership of the CGAL objects, e.g. use reference-counted smart pointers - CGAL_Nef_polyhedron2 *p2; - CGAL_Nef_polyhedron3 *p3; + shared_ptr p2; + shared_ptr p3; }; #endif /* ENABLE_CGAL */ diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 9f9ab6e..b019ad5 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -162,7 +162,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) // FIXME: Should the CGAL_Nef_polyhedron2 be cached? if (np.empty()) { np.dim = 2; - np.p2 = new CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); + np.p2.reset(new CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED)); } else { (*np.p2) += CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED); diff --git a/src/PolySetEvaluator.cc b/src/PolySetEvaluator.cc index e46ae59..1f09127 100644 --- a/src/PolySetEvaluator.cc +++ b/src/PolySetEvaluator.cc @@ -10,11 +10,6 @@ class. */ -static bool filter(char c) -{ - return c == ' ' || c == '\n' || c == '\t' || c == '\r'; -} - /*! Factory method returning a PolySet from the given node. If the node is already cached, the cached PolySet will be returned @@ -23,8 +18,7 @@ static bool filter(char c) */ shared_ptr PolySetEvaluator::getPolySet(const AbstractNode &node, bool cache) { - std::string cacheid = this->tree.getString(node); - cacheid.erase(std::remove_if(cacheid.begin(), cacheid.end(), filter), cacheid.end()); + std::string cacheid = this->tree.getIdString(node); if (PolySetCache::instance()->contains(cacheid)) { // For cache debugging diff --git a/src/Tree.cc b/src/Tree.cc index e791e12..68cb2bf 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -21,6 +21,30 @@ const std::string &Tree::getString(const AbstractNode &node) const return this->nodecache[node]; } +static bool filter(char c) +{ + return c == ' ' || c == '\n' || c == '\t' || c == '\r'; +} + +/*! + Returns the cached ID string representation of the subtree rooted by \a node. + If node is not cached, the cache will be rebuilt. + + The difference between this method and getString() is that the ID string + is stripped for whitespace. Especially indentation whitespace is important to + strip to enable cache hits for equivalent nodes from different scopes. +*/ +const std::string &Tree::getIdString(const AbstractNode &node) const +{ + assert(this->root_node); + if (!this->nodeidcache.contains(node)) { + std::string str = getString(node); + str.erase(std::remove_if(str.begin(), str.end(), filter), str.end()); + return this->nodeidcache.insert(node, str); + } + return this->nodeidcache[node]; +} + /*! Sets a new root. Will clear the existing cache. */ diff --git a/src/Tree.h b/src/Tree.h index 5df5bba..aaa61d7 100644 --- a/src/Tree.h +++ b/src/Tree.h @@ -21,10 +21,12 @@ public: const AbstractNode *root() const { return this->root_node; } const string &getString(const AbstractNode &node) const; + const string &getIdString(const AbstractNode &node) const; private: const AbstractNode *root_node; mutable NodeCache nodecache; + mutable NodeCache nodeidcache; }; #endif diff --git a/src/mainwin.cc b/src/mainwin.cc index 130e237..f9b60a6 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -86,6 +86,7 @@ using namespace boost::lambda; #ifdef ENABLE_CGAL +#include "CGALCache.h" #include "CGALEvaluator.h" #include "PolySetCGALEvaluator.h" #include "CGALRenderer.h" @@ -780,9 +781,7 @@ void MainWindow::compileCSG(bool procevents) progress_report_prep(root_node, report_func, pd); try { - // FIXME: put cache somewhere else as it's pretty useless now - QHash cache; - CGALEvaluator cgalevaluator(cache, this->tree); + CGALEvaluator cgalevaluator(this->tree); PolySetCGALEvaluator psevaluator(cgalevaluator); CSGTermEvaluator csgrenderer(this->tree, &psevaluator); root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms); @@ -792,6 +791,7 @@ void MainWindow::compileCSG(bool procevents) QApplication::processEvents(); } PolySetCache::instance()->print(); + CGALCache::instance()->print(); } catch (ProgressCancelException e) { PRINT("CSG generation cancelled."); @@ -1223,11 +1223,10 @@ void MainWindow::actionRenderCGAL() progress_report_prep(this->root_node, report_func, pd); try { - // FIXME: put cache somewhere else as it's pretty useless now - QHash cache; - CGALEvaluator evaluator(cache, this->tree); + CGALEvaluator evaluator(this->tree); this->root_N = new CGAL_Nef_polyhedron(evaluator.evaluateCGALMesh(*this->root_node)); PolySetCache::instance()->print(); + CGALCache::instance()->print(); } catch (ProgressCancelException e) { PRINT("Rendering cancelled."); diff --git a/src/nodecache.h b/src/nodecache.h index cc3355e..61afe3e 100644 --- a/src/nodecache.h +++ b/src/nodecache.h @@ -25,9 +25,10 @@ public: else return this->nullvalue; } - void insert(const class AbstractNode &node, const std::string & value) { + /*! Returns a reference to the cached string copy */ + const std::string &insert(const class AbstractNode &node, const std::string & value) { if (this->cache.size() <= node.index()) this->cache.resize(node.index() + 1); - this->cache[node.index()] = value; + return this->cache[node.index()] = value; } void remove(const class AbstractNode &node) { diff --git a/src/openscad.cc b/src/openscad.cc index c3ee389..fd74de4 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -249,9 +249,7 @@ int main(int argc, char **argv) NodeDumper dumper(nodecache); Tree tree; #ifdef ENABLE_CGAL - // FIXME: enforce some maximum cache size (old version had 100K vertices as limit) - QHash cache; - CGALEvaluator cgalevaluator(cache, tree); + CGALEvaluator cgalevaluator(tree); PolySetCGALEvaluator psevaluator(cgalevaluator); #endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 08ae030..509180e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -144,7 +144,7 @@ include_directories(${CGAL_INCLUDE_DIRS}) # cgaltest # add_executable(cgaltest cgaltest.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CSGTermEvaluator.cc - ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc + ../src/CGALEvaluator.cc ../src/CGALCache.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) set_target_properties(cgaltest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") @@ -155,7 +155,7 @@ target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_ # add_executable(cgalpngtest cgalpngtest.cc OffscreenView.cc OffscreenContext.mm ../src/CGALRenderer.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc - ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc + ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc ../src/CGALCache.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) @@ -168,7 +168,7 @@ target_link_libraries(cgalpngtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${ add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc - ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc + ../src/CGALEvaluator.cc ../src/CGALCache.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) set_target_properties(opencsgtest PROPERTIES COMPILE_FLAGS "-DENABLE_OPENCSG -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc index 8e3859b..4c5c914 100644 --- a/tests/cgalpngtest.cc +++ b/tests/cgalpngtest.cc @@ -59,14 +59,11 @@ QString librarydir; using std::string; -// FIXME: enforce some maximum cache size (old version had 100K vertices as limit) -QHash cache; - void cgalTree(Tree &tree) { assert(tree.root()); - CGALEvaluator evaluator(cache, tree); + CGALEvaluator evaluator(tree); Traverser evaluate(evaluator, *tree.root(), Traverser::PRE_AND_POSTFIX); evaluate.execute(); } @@ -174,8 +171,7 @@ int main(int argc, char **argv) Tree tree(root_node); CsgInfo csgInfo; - QHash cache; - CGALEvaluator cgalevaluator(cache, tree); + CGALEvaluator cgalevaluator(tree); PolySetCGALEvaluator psevaluator(cgalevaluator); CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node); diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc index 029fcfc..8dfb63c 100644 --- a/tests/cgaltest.cc +++ b/tests/cgaltest.cc @@ -54,14 +54,11 @@ QString librarydir; using std::string; -// FIXME: enforce some maximum cache size (old version had 100K vertices as limit) -QHash cache; - void cgalTree(Tree &tree) { assert(tree.root()); - CGALEvaluator evaluator(cache, tree); + CGALEvaluator evaluator(tree); Traverser evaluate(evaluator, *tree.root(), Traverser::PRE_AND_POSTFIX); evaluate.execute(); } @@ -163,8 +160,7 @@ int main(int argc, char **argv) Tree tree(root_node); - QHash cache; - CGALEvaluator cgalevaluator(cache, tree); + CGALEvaluator cgalevaluator(tree); PolySetCGALEvaluator psevaluator(cgalevaluator); CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node); diff --git a/tests/opencsgtest.cc b/tests/opencsgtest.cc index 28c0daa..59501a0 100644 --- a/tests/opencsgtest.cc +++ b/tests/opencsgtest.cc @@ -142,8 +142,7 @@ int main(int argc, char *argv[]) Tree tree(root_node); CsgInfo csgInfo; - QHash cache; - CGALEvaluator cgalevaluator(cache, tree); + CGALEvaluator cgalevaluator(tree); CSGTermEvaluator evaluator(tree, &cgalevaluator.psevaluator); CSGTerm *root_raw_term = evaluator.evaluateCSGTerm(*root_node, csgInfo.highlight_terms, -- cgit v0.10.1 From d25e197ac7d72214bbdc2753ef84104932c625dd Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 11:07:18 +0200 Subject: Forgot to commit CGALCache class diff --git a/src/CGALCache.cc b/src/CGALCache.cc new file mode 100644 index 0000000..6bdad41 --- /dev/null +++ b/src/CGALCache.cc @@ -0,0 +1,17 @@ +#include "CGALCache.h" +#include "printutils.h" +#include "CGAL_Nef_polyhedron.h" + +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()); + PRINTF("CGAL Cache insert: %s (%d verts)", id.substr(0, 40).c_str(), N.weight()); +} + +void CGALCache::print() +{ + PRINTF("CGAL Polyhedrons in cache: %d", this->cache.size()); + PRINTF("Vertices in cache: %d", this->cache.totalCost()); +} diff --git a/src/CGALCache.h b/src/CGALCache.h new file mode 100644 index 0000000..7d3a2d9 --- /dev/null +++ b/src/CGALCache.h @@ -0,0 +1,28 @@ +#ifndef CGALCACHE_H_ +#define CGALCACHE_H_ + +#include "myqhash.h" +#include + +/*! +*/ +class CGALCache +{ +public: + CGALCache(size_t limit = 100000) : cache(limit) {} + + static CGALCache *instance() { if (!inst) inst = new CGALCache; return inst; } + + bool contains(const std::string &id) const { return this->cache.contains(id); } + const class CGAL_Nef_polyhedron &get(const std::string &id) const { return *this->cache[id]; } + void insert(const std::string &id, const CGAL_Nef_polyhedron &N); + void clear() { cache.clear(); } + void print(); + +private: + static CGALCache *inst; + + QCache cache; +}; + +#endif -- cgit v0.10.1 From 77dbd805371d3953c4f832259a509b0a8c51a3a4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 11:10:22 +0200 Subject: helper to include TR1 stuff diff --git a/src/memory.h b/src/memory.h new file mode 100644 index 0000000..cd8878a --- /dev/null +++ b/src/memory.h @@ -0,0 +1,7 @@ +#ifndef MEMORY_H_ +#define MEMORY_H_ + +#include +using boost::shared_ptr; + +#endif -- cgit v0.10.1 From 1f52da35ef1db3df87865283d201f811a11c5378 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 11:10:48 +0200 Subject: helper to include TR1 stuff diff --git a/openscad.pro b/openscad.pro index 1abca19..6e79b29 100644 --- a/openscad.pro +++ b/openscad.pro @@ -165,6 +165,7 @@ HEADERS += src/renderer.h \ src/myqhash.h \ src/Tree.h \ src/mathc99.h \ + src/memory.h \ src/stl-utils.h SOURCES += src/openscad.cc \ -- cgit v0.10.1 From cf2bd1fe4f39c2017b220440ce966077423f17f5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 11:48:00 +0200 Subject: Linux build fixes diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h index a2eedaf..79d36b7 100644 --- a/src/CGAL_Nef_polyhedron.h +++ b/src/CGAL_Nef_polyhedron.h @@ -14,7 +14,7 @@ public: CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) : dim(3), p3(p) {} ~CGAL_Nef_polyhedron() {} - bool empty() const { return (dim == 0 || !p2 && !p3); } + bool empty() const { return (dim == 0 || (!p2 && !p3)); } CGAL_Nef_polyhedron &operator+=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &operator*=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &operator-=(const CGAL_Nef_polyhedron &other); diff --git a/src/PolySetCache.cc b/src/PolySetCache.cc index 89c511e..0a93642 100644 --- a/src/PolySetCache.cc +++ b/src/PolySetCache.cc @@ -1,6 +1,6 @@ #include "PolySetCache.h" #include "printutils.h" -#include "PolySet.h" +#include "polyset.h" PolySetCache *PolySetCache::inst = NULL; -- cgit v0.10.1 From 1b0ca0d6470c9aaa97caefdaa6e7eb400abd04d3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 12:26:23 +0200 Subject: bugfix: Clear both caches before rebuilding diff --git a/src/Tree.cc b/src/Tree.cc index 68cb2bf..7c4866b 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -12,6 +12,8 @@ const std::string &Tree::getString(const AbstractNode &node) const { assert(this->root_node); if (!this->nodecache.contains(node)) { + this->nodecache.clear(); + this->nodeidcache.clear(); NodeDumper dumper(this->nodecache, false); Traverser trav(dumper, *this->root_node, Traverser::PRE_AND_POSTFIX); trav.execute(); -- cgit v0.10.1 From 53c9613fec1fc66853a161c1a73ab807b7cd7f6a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 12:39:49 +0200 Subject: note about lighting diff --git a/doc/TODO.txt b/doc/TODO.txt index e48ea70..97af30a 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -78,6 +78,7 @@ o 3D View thicknesses, distances, slot thicknesses etc. - When specifying a transparency with the color() statement, the object is not sorted and will be rendered wrongly + - Add option to change lights, e.g. add an optional camera light o Editor wishlist - More infrastructure for external editor (allow communication from the outside) - Preferences GUI for the features below -- cgit v0.10.1 From 81ec00c09b5923effe6ad0d7fbf9404610f16d0f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 13:14:15 +0200 Subject: Change the diagonal view so that the object's front faces the light diff --git a/src/glview.cc b/src/glview.cc index 896ff0a..d69e43d 100644 --- a/src/glview.cc +++ b/src/glview.cc @@ -63,7 +63,7 @@ void GLView::init() this->viewer_distance = 500; this->object_rot_x = 35; this->object_rot_y = 0; - this->object_rot_z = 25; + this->object_rot_z = -25; this->object_trans_x = 0; this->object_trans_y = 0; this->object_trans_z = 0; diff --git a/src/mainwin.cc b/src/mainwin.cc index f9b60a6..0cf39e7 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1674,7 +1674,7 @@ void MainWindow::viewAngleDiagonal() { this->glview->object_rot_x = 35; this->glview->object_rot_y = 0; - this->glview->object_rot_z = 25; + this->glview->object_rot_z = -25; this->glview->updateGL(); } -- cgit v0.10.1 From 06a101df174602fd1f6dd5e1ac7486004e0b80f8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 11 Sep 2011 20:56:45 +0200 Subject: Change link on web page when publishing snapshots diff --git a/scripts/publish-macosx.sh b/scripts/publish-macosx.sh index 6415b52..088e64e 100755 --- a/scripts/publish-macosx.sh +++ b/scripts/publish-macosx.sh @@ -20,3 +20,6 @@ cp OpenSCAD-$VERSION.dmg ~/Dropbox/Public ln -sf OpenSCAD-$VERSION.dmg ~/Dropbox/Public/OpenSCAD-latest.dmg echo "Upload in progress..." + +# Update snapshot filename on wab page +`dirname $0`/update-web.sh OpenSCAD-$VERSION.dmg diff --git a/scripts/update-web.sh b/scripts/update-web.sh new file mode 100755 index 0000000..264da08 --- /dev/null +++ b/scripts/update-web.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +dmgfile=$1 +if [ -z "$dmgfile" ]; then + echo "Usage: $0 " + exit 1 +fi +indexfile=../openscad.github.com/index.html +if [ -f $indexfile ]; then + sed -i .backup -e "s/^\(.*mac-snapshot.*\)\(openscad-.*\.dmg\)\(.*\)\(openscad-.*dmg\)\(.*$\)/\\1$dmgfile\\3$dmgfile\\5/" $indexfile +else + echo "Web page not found at $indexfile" +fi +echo "Web page updated. Remember to commit and push openscad.githib.com" -- cgit v0.10.1 From b68c63e3bd37f50c954083d02cb86df07ce808f4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 12 Sep 2011 03:07:02 +0200 Subject: Added horn torus example known to cause a CGAL assertion diff --git a/testdata/scad/bugs/horn-torus.scad b/testdata/scad/bugs/horn-torus.scad new file mode 100644 index 0000000..f93a364 --- /dev/null +++ b/testdata/scad/bugs/horn-torus.scad @@ -0,0 +1,5 @@ +// This model causes a CGAL assertion in CGAL_Nef_polyhedron3(CGAL_Polyhedron) constructor. +// One cause of this error could be that the grid handling in PolySet degenerated the original +// mesh into a non-manifold one. + +rotate_extrude($fn = 24) translate ([ 1, 0, 0 ]) circle (r = 1); -- cgit v0.10.1 From ccb6af2816344a2747a9cf03eb9e393a8750dce6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 12 Sep 2011 03:46:13 +0200 Subject: Don't output deprecated parameters if they're not specified diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index ca98b66..8bb246f 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -144,13 +144,17 @@ std::string DxfLinearExtrudeNode::toString() const { std::stringstream stream; - stream << this->name() << "(" - "file = \"" << this->filename << "\", " - "cache = \"" << QFileInfo(QString::fromStdString(this->filename)) << "\", " - "layer = \"" << this->layername << "\", " + stream << this->name() << "("; + if (!this->filename.empty()) { // Ignore deprecated parameters if empty + stream << + "file = \"" << this->filename << "\", " + "cache = \"" << QFileInfo(QString::fromStdString(this->filename)) << "\", " + "layer = \"" << this->layername << "\", " + "origin = [ " << this->origin_x << " " << this->origin_y << " ], " + "scale = " << this->scale << ", "; + } + stream << "height = " << std::dec << this->height << ", " - "origin = [ " << this->origin_x << " " << this->origin_y << " ], " - "scale = " << this->scale << ", " "center = " << (this->center?"true":"false") << ", " "convexity = " << this->convexity; diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index cd585aa..646b643 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -120,12 +120,16 @@ std::string DxfRotateExtrudeNode::toString() const { std::stringstream stream; - stream << this->name() << "(" - "file = \"" << this->filename << "\", " - "cache = \"" << QFileInfo(QString::fromStdString(this->filename)) << "\", " - "layer = \"" << this->layername << "\", " - "origin = [ " << std::dec << this->origin_x << " " << this->origin_y << " ], " - "scale = " << this->scale << ", " + stream << this->name() << "("; + if (!this->filename.empty()) { // Ignore deprecated parameters if empty + stream << + "file = \"" << this->filename << "\", " + "cache = \"" << QFileInfo(QString::fromStdString(this->filename)) << "\", " + "layer = \"" << this->layername << "\", " + "origin = [ " << std::dec << this->origin_x << " " << this->origin_y << " ], " + "scale = " << this->scale << ", "; + } + stream << "convexity = " << this->convexity << ", " "$fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs << ")"; diff --git a/src/mainwin.cc b/src/mainwin.cc index 0cf39e7..56502f2 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1496,12 +1496,9 @@ void MainWindow::actionExportImage() void MainWindow::actionFlushCaches() { -// FIXME: Polycache -> PolySetEvaluator PolySetCache::instance()->clear(); #ifdef ENABLE_CGAL -// FIXME: Flush caches through whatever channels we have - // CGALEvaluator::evaluator()->getCache().clear(); - // this->dumper->clearCache(); + CGALCache::instance()->clear(); #endif dxf_dim_cache.clear(); dxf_cross_cache.clear(); diff --git a/tests/regression/dumptest/allmodules-expected.txt b/tests/regression/dumptest/allmodules-expected.txt index e708c43..2f920df 100644 --- a/tests/regression/dumptest/allmodules-expected.txt +++ b/tests/regression/dumptest/allmodules-expected.txt @@ -11,10 +11,10 @@ group() { union(); difference(); intersection(); - linear_extrude(file = "", cache = "0.0", layer = "", height = 100, origin = [ 0 0 ], scale = 1, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); - linear_extrude(file = "", cache = "0.0", layer = "", height = 100, origin = [ 0 0 ], scale = 1, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); - rotate_extrude(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); - rotate_extrude(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + linear_extrude(height = 100, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + linear_extrude(height = 100, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + rotate_extrude(convexity = 1, $fn = 0, $fa = 12, $fs = 1); + rotate_extrude(convexity = 1, $fn = 0, $fa = 12, $fs = 1); import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); import(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); diff --git a/tests/regression/dumptest/dxf_linear_extrude-expected.txt b/tests/regression/dumptest/dxf_linear_extrude-expected.txt index fd6535d..9284114 100644 --- a/tests/regression/dumptest/dxf_linear_extrude-expected.txt +++ b/tests/regression/dumptest/dxf_linear_extrude-expected.txt @@ -1,3 +1,3 @@ group() { - linear_extrude(file = "", cache = "0.0", layer = "", height = 100, origin = [ 0 0 ], scale = 1, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + linear_extrude(height = 100, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); } diff --git a/tests/regression/dumptest/dxf_rotate_extrude-expected.txt b/tests/regression/dumptest/dxf_rotate_extrude-expected.txt index 2d65d35..e2f5832 100644 --- a/tests/regression/dumptest/dxf_rotate_extrude-expected.txt +++ b/tests/regression/dumptest/dxf_rotate_extrude-expected.txt @@ -1,3 +1,3 @@ group() { - rotate_extrude(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + rotate_extrude(convexity = 1, $fn = 0, $fa = 12, $fs = 1); } diff --git a/tests/regression/dumptest/linear_extrude-expected.txt b/tests/regression/dumptest/linear_extrude-expected.txt index fd6535d..9284114 100644 --- a/tests/regression/dumptest/linear_extrude-expected.txt +++ b/tests/regression/dumptest/linear_extrude-expected.txt @@ -1,3 +1,3 @@ group() { - linear_extrude(file = "", cache = "0.0", layer = "", height = 100, origin = [ 0 0 ], scale = 1, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + linear_extrude(height = 100, center = false, convexity = 1, $fn = 0, $fa = 12, $fs = 1); } diff --git a/tests/regression/dumptest/rotate_extrude-expected.txt b/tests/regression/dumptest/rotate_extrude-expected.txt index 2d65d35..e2f5832 100644 --- a/tests/regression/dumptest/rotate_extrude-expected.txt +++ b/tests/regression/dumptest/rotate_extrude-expected.txt @@ -1,3 +1,3 @@ group() { - rotate_extrude(file = "", cache = "0.0", layer = "", origin = [ 0 0 ], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 1); + rotate_extrude(convexity = 1, $fn = 0, $fa = 12, $fs = 1); } -- cgit v0.10.1 From 5ac9162f1c67fd21737ead11d7ebc638bf4eef5f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 12 Sep 2011 11:59:50 +0200 Subject: Some typos diff --git a/scripts/update-web.sh b/scripts/update-web.sh index 264da08..4180d01 100755 --- a/scripts/update-web.sh +++ b/scripts/update-web.sh @@ -7,8 +7,8 @@ if [ -z "$dmgfile" ]; then fi indexfile=../openscad.github.com/index.html if [ -f $indexfile ]; then - sed -i .backup -e "s/^\(.*mac-snapshot.*\)\(openscad-.*\.dmg\)\(.*\)\(openscad-.*dmg\)\(.*$\)/\\1$dmgfile\\3$dmgfile\\5/" $indexfile + sed -i .backup -e "s/^\(.*mac-snapshot.*\)\(OpenSCAD-.*\.dmg\)\(.*\)\(OpenSCAD-.*dmg\)\(.*$\)/\\1$dmgfile\\3$dmgfile\\5/" $indexfile + echo "Web page updated. Remember to commit and push openscad.github.com" else echo "Web page not found at $indexfile" fi -echo "Web page updated. Remember to commit and push openscad.githib.com" -- cgit v0.10.1