diff --git a/color-schemes/editor/dark-background.json b/color-schemes/editor/dark-background.json index 2c199fcc..3db0fb02 100644 --- a/color-schemes/editor/dark-background.json +++ b/color-schemes/editor/dark-background.json @@ -23,7 +23,7 @@ "selection-foreground" : "#ffffff", "selection-background" : "#4a90d9", "margin-background" : "#272822", - "margin-foreground" : "#e0e0e0", + "margin-foreground" : "Gray", "matched-brace-background" : "#505050", "matched-brace-foreground" : "#ffffff", "unmatched-brace-background" : "#dc322f", @@ -33,4 +33,4 @@ "error-indicator-outline" : "#ff000000", "edge" : "#ffffff" } -} \ No newline at end of file +} diff --git a/color-schemes/editor/light-background.json b/color-schemes/editor/light-background.json index 2c0ffb30..b7e02aee 100644 --- a/color-schemes/editor/light-background.json +++ b/color-schemes/editor/light-background.json @@ -23,7 +23,7 @@ "selection-foreground" : "#ffffff", "selection-background" : "#4a90d9", "margin-background" : "#f8f8f8", - "margin-foreground" : "#000000", + "margin-foreground" : "Gray", "matched-brace-background" : "#c7f6cb", "matched-brace-foreground" : "Blue", "unmatched-brace-background" : "#ffcdcc", @@ -33,4 +33,4 @@ "error-indicator-outline" : "#ff000000", "edge" : "#ffffff" } -} \ No newline at end of file +} diff --git a/color-schemes/editor/monokai.json b/color-schemes/editor/monokai.json index 8ddac03c..bfd8dc1a 100644 --- a/color-schemes/editor/monokai.json +++ b/color-schemes/editor/monokai.json @@ -23,7 +23,7 @@ "selection-foreground" : "#272822", "selection-background" : "#f8f8f2", "margin-background" : "#3e3d32", - "margin-foreground" : "#f8f8f2", + "margin-foreground" : "DarkGray", "matched-brace-background" : "#606060", "matched-brace-foreground" : "#ffff00", "unmatched-brace-background" : "#b06060", @@ -33,4 +33,4 @@ "error-indicator-outline" : "#ff000000", "edge" : "#ffffff" } -} \ No newline at end of file +} diff --git a/openscad.pro b/openscad.pro index a2eefe65..3f7f9793 100644 --- a/openscad.pro +++ b/openscad.pro @@ -498,7 +498,6 @@ SOURCES += src/cgalutils.cc \ src/CGALCache.cc \ src/CGALRenderer.cc \ src/CGAL_Nef_polyhedron.cc \ - src/CGAL_Nef_polyhedron_DxfData.cc \ src/cgalworker.cc \ src/Polygon2d-CGAL.cc } diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index d49521e0..a470e191 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -3,6 +3,7 @@ #include "cgalutils.h" #include "printutils.h" #include "polyset.h" +#include "svg.h" CGAL_Nef_polyhedron::CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p) { @@ -135,3 +136,26 @@ void CGAL_Nef_polyhedron::resize(Vector3d newsize, this->transform(Transform3d(t)); } + +std::string CGAL_Nef_polyhedron::dump() const +{ + return OpenSCAD::dump_svg( *this->p3 ); +} + + +void CGAL_Nef_polyhedron::transform( const Transform3d &matrix ) +{ + if (!this->isEmpty()) { + if (matrix.matrix().determinant() == 0) { + PRINT("WARNING: Scaling a 3D object with 0 - removing object"); + this->reset(); + } + else { + CGAL_Aff_transformation t( + matrix(0,0), matrix(0,1), matrix(0,2), matrix(0,3), + matrix(1,0), matrix(1,1), matrix(1,2), matrix(1,3), + matrix(2,0), matrix(2,1), matrix(2,2), matrix(2,3), matrix(3,3)); + this->p3->transform(t); + } + } +} diff --git a/src/CGAL_Nef_polyhedron_DxfData.cc b/src/CGAL_Nef_polyhedron_DxfData.cc deleted file mode 100644 index cbb5ce77..00000000 --- a/src/CGAL_Nef_polyhedron_DxfData.cc +++ /dev/null @@ -1,62 +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 "Polygon2d.h" -#include "grid.h" -#include "CGAL_Nef_polyhedron.h" -#include "cgal.h" -#include "cgalutils.h" -#include -#include "polyset.h" -#include "Tree.h" - -#ifdef ENABLE_CGAL - -std::string CGAL_Nef_polyhedron::dump() const -{ - return OpenSCAD::dump_svg( *this->p3 ); -} - - -void CGAL_Nef_polyhedron::transform( const Transform3d &matrix ) -{ - if (!this->isEmpty()) { - if (matrix.matrix().determinant() == 0) { - PRINT("WARNING: Scaling a 3D object with 0 - removing object"); - this->reset(); - } - else { - CGAL_Aff_transformation t( - matrix(0,0), matrix(0,1), matrix(0,2), matrix(0,3), - matrix(1,0), matrix(1,1), matrix(1,2), matrix(1,3), - matrix(2,0), matrix(2,1), matrix(2,2), matrix(2,3), matrix(3,3)); - this->p3->transform(t); - } - } -} - -#endif // ENABLE_CGAL diff --git a/src/cgalutils.cc b/src/cgalutils.cc index ed93c1d8..15d880fa 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -117,6 +117,54 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolygon2d(const Polygon2d &po return createNefPolyhedronFromPolySet(*ps); } +/* + +ZRemover + +This class converts one or more Nef3 polyhedra into a Nef2 polyhedron by +stripping off the 'z' coordinates from the vertices. The resulting Nef2 +poly is accumulated in the 'output_nefpoly2d' member variable. + +The 'z' coordinates will either be all 0s, for an xy-plane intersected Nef3, +or, they will be a mixture of -eps and +eps, for a thin-box intersected Nef3. + +Notes on CGAL's Nef Polyhedron2: + +1. The 'mark' on a 2d Nef face is important when doing unions/intersections. + If the 'mark' of a face is wrong the resulting nef2 poly will be unexpected. +2. The 'mark' can be dependent on the points fed to the Nef2 constructor. + This is why we iterate through the 3d faces using the halfedge cycle + source()->target() instead of the ordinary source()->source(). The + the latter can generate sequences of points that will fail the + the CGAL::is_simple_2() test, resulting in improperly marked nef2 polys. +3. 3d facets have 'two sides'. we throw out the 'down' side to prevent dups. + +The class uses the 'visitor' pattern from the CGAL manual. See also +http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3/Chapter_main.html +http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3_ref/Class_Nef_polyhedron3.html +OGL_helper.h +*/ + +class ZRemover { +public: + CGAL_Nef_polyhedron2::Boundary boundary; + boost::shared_ptr tmpnef2d; + boost::shared_ptr output_nefpoly2d; + CGAL::Direction_3 up; + ZRemover() + { + output_nefpoly2d.reset( new CGAL_Nef_polyhedron2() ); + boundary = CGAL_Nef_polyhedron2::INCLUDED; + up = CGAL::Direction_3(0,0,1); + } + void visit( CGAL_Nef_polyhedron3::Vertex_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::Halfedge_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::SHalfedge_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::SHalfloop_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::SFace_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet ); +}; + namespace CGALUtils { bool applyHull(const Geometry::ChildList &children, PolySet &result) diff --git a/src/cgalutils.h b/src/cgalutils.h index 4939c9fb..9e09bcb6 100644 --- a/src/cgalutils.h +++ b/src/cgalutils.h @@ -40,54 +40,3 @@ namespace CGALUtils { std::vector &triangles, CGAL::Plane_3 &plane); }; - -#include "svg.h" -#include "printutils.h" - -/* - -ZRemover - -This class converts one or more Nef3 polyhedra into a Nef2 polyhedron by -stripping off the 'z' coordinates from the vertices. The resulting Nef2 -poly is accumulated in the 'output_nefpoly2d' member variable. - -The 'z' coordinates will either be all 0s, for an xy-plane intersected Nef3, -or, they will be a mixture of -eps and +eps, for a thin-box intersected Nef3. - -Notes on CGAL's Nef Polyhedron2: - -1. The 'mark' on a 2d Nef face is important when doing unions/intersections. - If the 'mark' of a face is wrong the resulting nef2 poly will be unexpected. -2. The 'mark' can be dependent on the points fed to the Nef2 constructor. - This is why we iterate through the 3d faces using the halfedge cycle - source()->target() instead of the ordinary source()->source(). The - the latter can generate sequences of points that will fail the - the CGAL::is_simple_2() test, resulting in improperly marked nef2 polys. -3. 3d facets have 'two sides'. we throw out the 'down' side to prevent dups. - -The class uses the 'visitor' pattern from the CGAL manual. See also -http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3/Chapter_main.html -http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3_ref/Class_Nef_polyhedron3.html -OGL_helper.h -*/ - -class ZRemover { -public: - CGAL_Nef_polyhedron2::Boundary boundary; - boost::shared_ptr tmpnef2d; - boost::shared_ptr output_nefpoly2d; - CGAL::Direction_3 up; - ZRemover() - { - output_nefpoly2d.reset( new CGAL_Nef_polyhedron2() ); - boundary = CGAL_Nef_polyhedron2::INCLUDED; - up = CGAL::Direction_3(0,0,1); - } - void visit( CGAL_Nef_polyhedron3::Vertex_const_handle ) {} - void visit( CGAL_Nef_polyhedron3::Halfedge_const_handle ) {} - void visit( CGAL_Nef_polyhedron3::SHalfedge_const_handle ) {} - void visit( CGAL_Nef_polyhedron3::SHalfloop_const_handle ) {} - void visit( CGAL_Nef_polyhedron3::SFace_const_handle ) {} - void visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet ); -}; diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 3286c99f..ed110952 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -344,17 +344,15 @@ void ScintillaEditor::noColor() qsci->setIndicatorOutlineColor(QColor(0, 0, 0, 255), indicatorNumber); // only alpha part is used qsci->setCaretLineBackgroundColor(Qt::white); qsci->setWhitespaceForegroundColor(Qt::black); - qsci->setMarginsBackgroundColor(Qt::white); - qsci->setMarginsForegroundColor(Qt::black); - qsci->setSelectionForegroundColor(Qt::white); - qsci->setSelectionBackgroundColor(Qt::black); - qsci->setMatchedBraceBackgroundColor(Qt::white); + qsci->setSelectionForegroundColor(Qt::black); + qsci->setSelectionBackgroundColor(QColor("LightSkyBlue")); + qsci->setMatchedBraceBackgroundColor(QColor("LightBlue")); qsci->setMatchedBraceForegroundColor(Qt::black); - qsci->setUnmatchedBraceBackgroundColor(Qt::white); + qsci->setUnmatchedBraceBackgroundColor(QColor("pink")); qsci->setUnmatchedBraceForegroundColor(Qt::black); - qsci->setMarginsBackgroundColor(Qt::lightGray); - qsci->setMarginsForegroundColor(Qt::black); - qsci->setFoldMarginColors(Qt::lightGray, Qt::lightGray); + qsci->setMarginsBackgroundColor(QColor("whiteSmoke")); + qsci->setMarginsForegroundColor(QColor("gray")); + qsci->setFoldMarginColors(QColor("whiteSmoke"), QColor("whiteSmoke")); qsci->setEdgeColor(Qt::black); } @@ -471,10 +469,10 @@ void ScintillaEditor::zoomOut() void ScintillaEditor::initFont(const QString& fontName, uint size) { - QFont font(fontName, size); - font.setFixedPitch(true); - lexer->setFont(font); - qsci->setMarginsFont(font); + this->currentFont = QFont(fontName, size); + this->currentFont.setFixedPitch(true); + lexer->setFont(this->currentFont); + qsci->setMarginsFont(this->currentFont); onTextChanged(); // Update margin width } @@ -486,8 +484,8 @@ void ScintillaEditor::initMargin() void ScintillaEditor::onTextChanged() { - QFontMetrics fontmetrics = qsci->fontMetrics(); - qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6); + QFontMetrics fontmetrics(this->currentFont); + qsci->setMarginWidth(1, QString(trunc(log10(qsci->lines())+2), '0')); } bool ScintillaEditor::find(const QString &expr, bool findNext, bool findBackwards) diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h index 6d83da6e..c00e7542 100644 --- a/src/scintillaeditor.h +++ b/src/scintillaeditor.h @@ -94,4 +94,5 @@ private: static const int indicatorNumber = 8; // first 8 are used by lexers static const int markerNumber = 2; ScadLexer *lexer; + QFont currentFont; }; diff --git a/src/transform.cc b/src/transform.cc index c86f0301..2f7a2a89 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -168,12 +168,16 @@ AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInsta { ValuePtr v = c.lookup_variable("m"); if (v->type() == Value::VECTOR) { + Matrix4d rawmatrix = Matrix4d::Identity(); for (int i = 0; i < 16; i++) { size_t x = i / 4, y = i % 4; if (y < v->toVector().size() && v->toVector()[y].type() == Value::VECTOR && x < v->toVector()[y].toVector().size()) - v->toVector()[y].toVector()[x].getDouble(node->matrix(y, x)); + v->toVector()[y].toVector()[x].getDouble(rawmatrix(y, x)); } + double w = rawmatrix(3,3); + if (w != 1.0) node->matrix = rawmatrix / w; + else node->matrix = rawmatrix; } } diff --git a/testdata/scad/3D/features/transform-tests.scad b/testdata/scad/3D/features/transform-tests.scad index 0c922c78..95a1c589 100644 --- a/testdata/scad/3D/features/transform-tests.scad +++ b/testdata/scad/3D/features/transform-tests.scad @@ -15,3 +15,8 @@ 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(); +translate([-25,-40,0]) + multmatrix([[1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,2]]) mycyl(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2448473f..2c4aa776 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -694,7 +694,6 @@ set(CGAL_SOURCES ../src/cgalutils-tess.cc ../src/cgalutils-polyhedron.cc ../src/CGALCache.cc - ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/Polygon2d-CGAL.cc ../src/svg.cc ../src/GeometryEvaluator.cc) diff --git a/tests/regression/cgalpngtest/transform-tests-expected.png b/tests/regression/cgalpngtest/transform-tests-expected.png index ee8b6e5b..145eebae 100644 Binary files a/tests/regression/cgalpngtest/transform-tests-expected.png and b/tests/regression/cgalpngtest/transform-tests-expected.png differ diff --git a/tests/regression/dumptest/transform-tests-expected.csg b/tests/regression/dumptest/transform-tests-expected.csg index 8b3d86a4..399fe735 100644 --- a/tests/regression/dumptest/transform-tests-expected.csg +++ b/tests/regression/dumptest/transform-tests-expected.csg @@ -42,4 +42,11 @@ group() { cylinder($fn = 0, $fa = 12, $fs = 2, h = 20, r1 = 10, r2 = 0, center = false); } } + multmatrix([[1, 0, 0, -25], [0, 1, 0, -40], [0, 0, 1, 0], [0, 0, 0, 1]]) { + multmatrix([[0.5, 0, 0, 0], [0, 0.5, 0, 0], [0, 0, 0.5, 0], [0, 0, 0, 1]]) { + group() { + cylinder($fn = 0, $fa = 12, $fs = 2, h = 20, r1 = 10, r2 = 0, center = false); + } + } + } } diff --git a/tests/regression/opencsgtest/transform-tests-expected.png b/tests/regression/opencsgtest/transform-tests-expected.png index 52f43304..55d7a44d 100644 Binary files a/tests/regression/opencsgtest/transform-tests-expected.png and b/tests/regression/opencsgtest/transform-tests-expected.png differ diff --git a/tests/regression/throwntogethertest/transform-tests-expected.png b/tests/regression/throwntogethertest/transform-tests-expected.png index 52f43304..55d7a44d 100644 Binary files a/tests/regression/throwntogethertest/transform-tests-expected.png and b/tests/regression/throwntogethertest/transform-tests-expected.png differ