From c559be20e140c125637afd335c572a83d5bd2b94 Mon Sep 17 00:00:00 2001 From: don bright Date: Sat, 18 Oct 2014 19:13:57 +0200 Subject: [PATCH 001/263] Create basic gettext infrastructure and French language stub. --- doc/translation.txt | 85 ++ openscad.pro | 8 +- po/LINGUAS | 2 + po/POTFILES.in | 77 ++ po/fr.po | 1556 +++++++++++++++++++++++++++++++++ po/openscad.pot | 1553 ++++++++++++++++++++++++++++++++ scripts/translation-update.sh | 58 ++ src/AboutDialog.h | 1 + src/MainWindow.h | 1 + src/OpenCSGWarningDialog.h | 1 + src/Preferences.h | 1 + src/ProgressWidget.h | 1 + src/printutils.h | 4 + src/qtgettext.h | 18 + 14 files changed, 3365 insertions(+), 1 deletion(-) create mode 100644 doc/translation.txt create mode 100644 po/LINGUAS create mode 100644 po/POTFILES.in create mode 100644 po/fr.po create mode 100644 po/openscad.pot create mode 100755 scripts/translation-update.sh create mode 100644 src/qtgettext.h diff --git a/doc/translation.txt b/doc/translation.txt new file mode 100644 index 00000000..cced8f60 --- /dev/null +++ b/doc/translation.txt @@ -0,0 +1,85 @@ +OpenSCAD human language translation +=================================== + +We use the GNU gettext system, both for c++ code as well as QT's .ui files. +The latter is accomplished by the '-tr' feature of QT's uic to insert +a gettext wrapper into the ui_xxxxx.h files. + +For somewhat similar designs, see the source code of projects like celestia, +stellarium, licq, merkaartor, etc (although they typically use cmake). + +Currently the build system does not auto-update anything. The .mo files must +be generated by running the gettext tools: xgettext, msgmerge, and msgfmt. +There is a script included, translation-update.sh, that automates this process. + +File layout: +============ + + ./po/*.po - .po files, one per language + ./po/openscad.pot - .pot template, generated by xgettext + ./po/POTFILES.in - list of source code files with translatable strings + ./po/LINGUAS - list of language codes for which .po files exist + ./src/qtgettext.h - wrapper code between QT and GNU gettext + ./scripts/translation-update.sh - simple unix helper script + ./po/xx/LC_MESSAGES/openscad.mo - 'binaries' of .po files, built by script + +To translate the strings: +========================= + +Use a text editor or special program (poedit or lokalize) to edit the .po file. +( See http://en.opensuse.org/SDB:Localization_work_with_po_files ) +Then submit your new .po file as an OpenSCAD github issue or pull request: + +https://github.com/openscad/openscad/issues/ + +In the future there might be a site to allow translations in a browser: + +https://translations.launchpad.net/openscad + +If all else fails, email the OpenSCAD mailing list with your new .po +file attached. + +To make source code changes: +============================ + +In .cc files, #include "printutils.h" and change each "text" into +_("text"). In .ui files, #include "qtgettext.h" first in the .h file +(see MainWindow.h). Then clean and rebuild to recreate the ui_xxxx.h +files. + + $ make clean && qmake && make + +Now make sure your .cc and ui_xxxx.h files are listed in po/POTFILES.in. +Then run the script to scan them, and regenerate .pot & .po files. + + $ ./scripts/translate.sh updateall + +This will create new .po files with any new untranslated strings you +added to the source code. These .po files can be distributed to +translators for translation. After the translated .po file is obtained, +overwrite the old .po and run the same script to update the .mo files. + + $ ./scripts/translate.sh updateall + +To add a new language: +====================== + +First add the language code to file ./po/LINGUAS. Then run msginit, replacing +$LANGCODE with the language code you want. + + $ msginit -l $LANGCODE -o ./po/$LANGCODE.po -i ./po/openscad.pot + +You will now have a new ./po/xx.po file to edit and translate + +Testing: +======== + +On unix, set the locale related environment variables. For example in +French, run this: + + $ LANGUAGE=fr ./openscad + +Linux system trace tools can help find errors. To show open()s on .mo files: + + $ LANGUAGE=fr strace -f ./openscad 2>&1 | grep LC_MESSAGES + diff --git a/openscad.pro b/openscad.pro index 067576f1..e9f6adc2 100644 --- a/openscad.pro +++ b/openscad.pro @@ -120,6 +120,8 @@ unix:!macx { QMAKE_LIBS_OPENGL *= -lX11 } +#QTPLUGIN += qtaccessiblewidgets + netbsd* { QMAKE_LFLAGS += -L/usr/X11R7/lib QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib @@ -159,6 +161,8 @@ netbsd* { QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions + # gettext + QMAKE_CXXFLAGS_WARN_ON += -Wno-format-security # might want to actually turn this on once in a while QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-compare } @@ -208,7 +212,9 @@ win* { RESOURCES = openscad.qrc -FORMS += src/MainWindow.ui \ +QMAKE_UIC += -tr _ + +FORMS += src/MainWindow.ui \ src/Preferences.ui \ src/OpenCSGWarningDialog.ui \ src/AboutDialog.ui \ diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 00000000..f2b5b5a0 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,2 @@ +# available languages +fr diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 00000000..624cf316 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,77 @@ +# see doc/translation.txt + +# ui_xxxx.h files created by qt's uic when make is run. +# if you add new .ui files, add their .h counterpart here +objects/ui_AboutDialog.h +objects/ui_OpenCSGWarningDialog.h +objects/ui_ProgressWidget.h +objects/ui_MainWindow.h +objects/ui_Preferences.h + +# C++ +src/AppleEvents.cc +src/builtin.cc +src/cgaladv.cc +src/cgaladv_minkowski2.cc +src/CGALCache.cc +src/CGALEvaluator.cc +src/CGAL_Nef_polyhedron.cc +src/CGAL_Nef_polyhedron_DxfData.cc +src/CGALRenderer.cc +src/cgalutils.cc +src/cgalworker.cc +src/color.cc +src/context.cc +src/control.cc +src/csgops.cc +src/csgterm.cc +src/CSGTermEvaluator.cc +src/csgtermnormalizer.cc +src/dxfdata.cc +src/dxfdim.cc +src/dxftess.cc +src/dxftess-cgal.cc +src/dxftess-glu.cc +src/editor.cc +src/export.cc +src/expr.cc +src/func.cc +src/glview.cc +src/handle_dep.cc +src/highlighter.cc +src/import.cc +src/linalg.cc +src/linearextrude.cc +src/mainwin.cc +src/mathc99.cc +src/ModuleCache.cc +src/module.cc +src/node.cc +src/nodedumper.cc +src/OpenCSGRenderer.cc +src/OpenCSGWarningDialog.cc +src/openscad.cc +src/parsersettings.cc +src/PolySetCache.cc +src/polyset.cc +src/PolySetCGALEvaluator.cc +src/PolySetEvaluator.cc +src/Preferences.cc +src/primitives.cc +src/printutils.cc +src/progress.cc +src/ProgressWidget.cc +src/projection.cc +src/render.cc +src/renderer.cc +src/rendersettings.cc +src/rotateextrude.cc +src/stl-utils.cc +src/surface.cc +src/svg.cc +src/ThrownTogetherRenderer.cc +src/transform.cc +src/traverser.cc +src/Tree.cc +src/value.cc +src/version_check.cc diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 00000000..6663821d --- /dev/null +++ b/po/fr.po @@ -0,0 +1,1556 @@ +# French translations for OpenSCAD package. +# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER +# This file is distributed under the same license as the OpenSCAD package. +# don , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2013.02.07\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-01-06 05:06+0100\n" +"PO-Revision-Date: 2013-02-08 15:06-0600\n" +"Last-Translator: don bright \n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:86 +#, fuzzy +msgid "OpenGL Warning" +msgstr "Information OpenGL" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 +msgid "Close" +msgstr "Fermer" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: objects/ui_MainWindow.h:470 +msgid "MainWindow" +msgstr "" + +#: objects/ui_MainWindow.h:471 +msgid "&New" +msgstr "&Nouveau" + +#: objects/ui_MainWindow.h:472 +msgid "Ctrl+N" +msgstr "" + +#: objects/ui_MainWindow.h:473 +msgid "&Open..." +msgstr "&Ouvrir..." + +#: objects/ui_MainWindow.h:474 +msgid "Ctrl+O" +msgstr "" + +#: objects/ui_MainWindow.h:475 +msgid "&Save" +msgstr "Enregi&strer" + +#: objects/ui_MainWindow.h:476 +msgid "Ctrl+S" +msgstr "" + +#: objects/ui_MainWindow.h:477 +msgid "Save &As..." +msgstr "Enregistrer &sous..." + +#: objects/ui_MainWindow.h:478 +msgid "Ctrl+Shift+S" +msgstr "" + +#: objects/ui_MainWindow.h:479 +msgid "&Reload" +msgstr "&Recharger" + +#: objects/ui_MainWindow.h:480 +msgid "Ctrl+R" +msgstr "" + +#: objects/ui_MainWindow.h:481 +msgid "&Quit" +msgstr "&Quitter" + +#: objects/ui_MainWindow.h:482 +msgid "Ctrl+Q" +msgstr "" + +#: objects/ui_MainWindow.h:483 +msgid "&Undo" +msgstr "Ann&uler" + +#: objects/ui_MainWindow.h:484 +msgid "Ctrl+Z" +msgstr "" + +#: objects/ui_MainWindow.h:485 +msgid "&Redo" +msgstr "&Refaire" + +#: objects/ui_MainWindow.h:486 +msgid "Ctrl+Shift+Z" +msgstr "" + +#: objects/ui_MainWindow.h:487 +msgid "Cu&t" +msgstr "Co&uper" + +#: objects/ui_MainWindow.h:488 +msgid "Ctrl+X" +msgstr "" + +#: objects/ui_MainWindow.h:489 +msgid "&Copy" +msgstr "&Copier" + +#: objects/ui_MainWindow.h:490 +msgid "Ctrl+C" +msgstr "" + +#: objects/ui_MainWindow.h:491 +msgid "&Paste" +msgstr "&Coller" + +#: objects/ui_MainWindow.h:492 +msgid "Ctrl+V" +msgstr "" + +#: objects/ui_MainWindow.h:493 +msgid "&Indent" +msgstr "&Indenter" + +#: objects/ui_MainWindow.h:494 +msgid "Ctrl+I" +msgstr "" + +#: objects/ui_MainWindow.h:495 +msgid "U&nindent" +msgstr "Dési&ndenter" + +#: objects/ui_MainWindow.h:496 +msgid "Ctrl+Shift+I" +msgstr "" + +#: objects/ui_MainWindow.h:497 +msgid "C&omment" +msgstr "" + +#: objects/ui_MainWindow.h:498 +msgid "Ctrl+D" +msgstr "" + +#: objects/ui_MainWindow.h:499 +msgid "Unco&mment" +msgstr "" + +#: objects/ui_MainWindow.h:500 +msgid "Ctrl+Shift+D" +msgstr "" + +#: objects/ui_MainWindow.h:501 +msgid "Paste viewport translation" +msgstr "" + +#: objects/ui_MainWindow.h:502 +msgid "Ctrl+T" +msgstr "" + +#: objects/ui_MainWindow.h:503 +msgid "Paste viewport rotation" +msgstr "" + +#: objects/ui_MainWindow.h:504 +msgid "Zoom In" +msgstr "Zoom Avant" + +#: objects/ui_MainWindow.h:505 +msgid "Ctrl++" +msgstr "" + +#: objects/ui_MainWindow.h:506 +msgid "Zoom Out" +msgstr "Zoom Arrière" + +#: objects/ui_MainWindow.h:507 +msgid "Ctrl+-" +msgstr "" + +#: objects/ui_MainWindow.h:508 +msgid "Hide editor" +msgstr "" + +#: objects/ui_MainWindow.h:509 +msgid "&Reload and Compile" +msgstr "" + +#: objects/ui_MainWindow.h:510 +msgid "F4" +msgstr "" + +#: objects/ui_MainWindow.h:511 +msgid "&Compile" +msgstr "" + +#: objects/ui_MainWindow.h:512 +msgid "F5" +msgstr "" + +#: objects/ui_MainWindow.h:513 +msgid "Compile and &Render (CGAL)" +msgstr "" + +#: objects/ui_MainWindow.h:514 +msgid "F6" +msgstr "" + +#: objects/ui_MainWindow.h:515 +msgid "Display &AST..." +msgstr "" + +#: objects/ui_MainWindow.h:516 +msgid "Display CSG &Tree..." +msgstr "" + +#: objects/ui_MainWindow.h:517 +msgid "Display CSG &Products..." +msgstr "" + +#: objects/ui_MainWindow.h:518 +msgid "Export as &STL..." +msgstr "" + +#: objects/ui_MainWindow.h:519 +msgid "Export as &OFF..." +msgstr "" + +#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 +msgid "OpenCSG" +msgstr "" + +#: objects/ui_MainWindow.h:521 +msgid "F9" +msgstr "" + +#: objects/ui_MainWindow.h:522 +msgid "CGAL Surfaces" +msgstr "" + +#: objects/ui_MainWindow.h:523 +msgid "F10" +msgstr "" + +#: objects/ui_MainWindow.h:524 +msgid "CGAL Grid Only" +msgstr "" + +#: objects/ui_MainWindow.h:525 +msgid "F11" +msgstr "" + +#: objects/ui_MainWindow.h:526 +msgid "Thrown Together" +msgstr "" + +#: objects/ui_MainWindow.h:527 +msgid "F12" +msgstr "" + +#: objects/ui_MainWindow.h:528 +msgid "Show Edges" +msgstr "" + +#: objects/ui_MainWindow.h:529 +msgid "Ctrl+1" +msgstr "" + +#: objects/ui_MainWindow.h:530 +msgid "Show Axes" +msgstr "Afficher les axes" + +#: objects/ui_MainWindow.h:531 +msgid "Ctrl+2" +msgstr "" + +#: objects/ui_MainWindow.h:532 +msgid "Show Crosshairs" +msgstr "" + +#: objects/ui_MainWindow.h:533 +msgid "Ctrl+3" +msgstr "" + +#: objects/ui_MainWindow.h:534 +msgid "Animate" +msgstr "" + +#: objects/ui_MainWindow.h:535 +msgid "Top" +msgstr "Dessus" + +#: objects/ui_MainWindow.h:536 +msgid "Ctrl+4" +msgstr "" + +#: objects/ui_MainWindow.h:537 +msgid "Bottom" +msgstr "Dessous" + +#: objects/ui_MainWindow.h:538 +msgid "Ctrl+5" +msgstr "" + +#: objects/ui_MainWindow.h:539 +msgid "Left" +msgstr "Gauche" + +#: objects/ui_MainWindow.h:540 +msgid "Ctrl+6" +msgstr "" + +#: objects/ui_MainWindow.h:541 +msgid "Right" +msgstr "Droite" + +#: objects/ui_MainWindow.h:542 +msgid "Ctrl+7" +msgstr "" + +#: objects/ui_MainWindow.h:543 +msgid "Front" +msgstr "Face" + +#: objects/ui_MainWindow.h:544 +msgid "Ctrl+8" +msgstr "" + +#: objects/ui_MainWindow.h:545 +msgid "Back" +msgstr "Arrière" + +#: objects/ui_MainWindow.h:546 +msgid "Ctrl+9" +msgstr "" + +#: objects/ui_MainWindow.h:547 +msgid "Diagonal" +msgstr "" + +#: objects/ui_MainWindow.h:548 +msgid "Ctrl+0" +msgstr "" + +#: objects/ui_MainWindow.h:549 +msgid "Center" +msgstr "" + +#: objects/ui_MainWindow.h:550 +msgid "Ctrl+P" +msgstr "" + +#: objects/ui_MainWindow.h:551 +msgid "Perspective" +msgstr "" + +#: objects/ui_MainWindow.h:552 +msgid "Orthogonal" +msgstr "" + +#: objects/ui_MainWindow.h:553 +msgid "Hide console" +msgstr "" + +#: objects/ui_MainWindow.h:554 +msgid "About" +msgstr "À propos" + +#: objects/ui_MainWindow.h:555 +msgid "Documentation" +msgstr "" + +#: objects/ui_MainWindow.h:556 +msgid "Clear Recent" +msgstr "" + +#: objects/ui_MainWindow.h:557 +msgid "Export as DXF..." +msgstr "" + +#: objects/ui_MainWindow.h:559 +msgid "Ctrl+W" +msgstr "" + +#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +msgid "Preferences" +msgstr "Préférences" + +#: objects/ui_MainWindow.h:561 +msgid "Flush Caches" +msgstr "" + +#: objects/ui_MainWindow.h:562 +msgid "OpenSCAD Homepage" +msgstr "" + +#: objects/ui_MainWindow.h:563 +msgid "Automatic Reload and Compile" +msgstr "" + +#: objects/ui_MainWindow.h:564 +msgid "Export as Image..." +msgstr "" + +#: objects/ui_MainWindow.h:565 +msgid "Export as CSG..." +msgstr "" + +#: objects/ui_MainWindow.h:566 +msgid "Library info" +msgstr "" + +#: objects/ui_MainWindow.h:567 +msgid "Check for Update.." +msgstr "" + +#: objects/ui_MainWindow.h:568 +msgid "Show Library Folder..." +msgstr "" + +#: objects/ui_MainWindow.h:569 +msgid "Reset View" +msgstr "" + +#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 +msgid "Editor" +msgstr "" + +#: objects/ui_MainWindow.h:574 +msgid "Editor for SCAD code" +msgstr "" + +#: objects/ui_MainWindow.h:577 +msgid "Console" +msgstr "" + +#: objects/ui_MainWindow.h:580 +msgid "Console messages" +msgstr "" + +#: objects/ui_MainWindow.h:582 +msgid "Time:" +msgstr "" + +#: objects/ui_MainWindow.h:583 +msgid "FPS:" +msgstr "" + +#: objects/ui_MainWindow.h:584 +msgid "Steps:" +msgstr "" + +#: objects/ui_MainWindow.h:585 +msgid "Dump Pictures" +msgstr "" + +#: objects/ui_MainWindow.h:586 +msgid "&File" +msgstr "&Fichier" + +#: objects/ui_MainWindow.h:587 +msgid "Open Recent" +msgstr "" + +#: objects/ui_MainWindow.h:588 +msgid "Examples" +msgstr "&Exemples" + +#: objects/ui_MainWindow.h:589 +msgid "&Edit" +msgstr "&Édition" + +#: objects/ui_MainWindow.h:590 +msgid "&Design" +msgstr "" + +#: objects/ui_MainWindow.h:591 +msgid "&View" +msgstr "&Vue" + +#: objects/ui_MainWindow.h:592 +msgid "&Help" +msgstr "&Aide" + +#: objects/ui_Preferences.h:515 +#, fuzzy +msgid "3D View" +msgstr "&Vue" + +#: objects/ui_Preferences.h:516 +msgid "Advanced" +msgstr "" + +#: objects/ui_Preferences.h:518 +msgid "Update" +msgstr "" + +#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +msgid "Features" +msgstr "" + +#: objects/ui_Preferences.h:521 +msgid "Enable/Disable experimental features" +msgstr "" + +#: objects/ui_Preferences.h:523 +msgid "Color scheme:" +msgstr "" + +#: objects/ui_Preferences.h:528 +msgid "Cornfield" +msgstr "" + +#: objects/ui_Preferences.h:530 +msgid "Metallic" +msgstr "" + +#: objects/ui_Preferences.h:532 +msgid "Sunset" +msgstr "" + +#: objects/ui_Preferences.h:535 +msgid "Font" +msgstr "" + +#: objects/ui_Preferences.h:536 +msgid "Color syntax highlighting" +msgstr "" + +#: objects/ui_Preferences.h:539 +msgid "For Light Background" +msgstr "" + +#: objects/ui_Preferences.h:540 +msgid "For Dark Background" +msgstr "" + +#: objects/ui_Preferences.h:541 +msgid "Off" +msgstr "" + +#: objects/ui_Preferences.h:543 +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:544 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:545 +msgid "Check Now" +msgstr "" + +#: objects/ui_Preferences.h:546 +msgid "Last checked: " +msgstr "" + +#: objects/ui_Preferences.h:549 +msgid "Show capability warning" +msgstr "" + +#: objects/ui_Preferences.h:550 +msgid "Enable for OpenGL 1.x" +msgstr "" + +#: objects/ui_Preferences.h:551 +msgid "Turn off rendering at " +msgstr "" + +#: objects/ui_Preferences.h:552 +msgid "elements" +msgstr "" + +#: objects/ui_Preferences.h:553 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:554 +msgid "CGAL Cache size" +msgstr "" + +#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 +msgid "bytes" +msgstr "" + +#: objects/ui_Preferences.h:556 +msgid "PolySet Cache size" +msgstr "" + +#: objects/ui_Preferences.h:558 +msgid "toolBar" +msgstr "" + +#: src/cgaladv_minkowski2.cc:43 +msgid " vertices:" +msgstr "" + +#: src/cgaladv_minkowski2.cc:55 +msgid "{ Outer boundary = " +msgstr "" + +#: src/cgaladv_minkowski2.cc:58 +msgid "{ Unbounded polygon." +msgstr "" + +#: src/cgaladv_minkowski2.cc:63 +msgid " holes:" +msgstr "" + +#: src/cgaladv_minkowski2.cc:65 +msgid " Hole #" +msgstr "" + +#: src/cgaladv_minkowski2.cc:90 +msgid "" +"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" +msgstr "" + +#: src/cgaladv_minkowski2.cc:123 +msgid "WARNING: minkowski() could not get any points from object 1!" +msgstr "" + +#: src/cgaladv_minkowski2.cc:126 +msgid "WARNING: minkowski() could not get any points from object 2!" +msgstr "" + +#: src/CGALEvaluator.cc:89 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +msgstr "" + +#: src/CGALEvaluator.cc:141 +msgid "WARNING: hull() does not support mixing 2D and 3D objects." +msgstr "" + +#: src/CGALEvaluator.cc:159 +msgid "" +"Hull() currently requires a valid 2-manifold. Please modify your design. See " +"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" + +#: src/CGALEvaluator.cc:336 +msgid "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." +msgstr "" + +#: src/CGALEvaluator.cc:384 +msgid "WARNING: glide() is not implemented yet!" +msgstr "" + +#: src/CGALEvaluator.cc:388 +msgid "WARNING: subdiv() is not implemented yet!" +msgstr "" + +#: src/CGALEvaluator.cc:422 +msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" +msgstr "" + +#: src/CGALEvaluator.cc:708 +#, c-format +msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "" + +#: src/CGAL_Nef_polyhedron.cc:113 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +msgstr "" + +#: src/cgalutils.cc:138 +#, c-format +msgid "CGAL error in CGAL_Build_PolySet: %s" +msgstr "" + +#: src/cgalworker.cc:36 +msgid "Rendering cancelled." +msgstr "" + +#: src/color.cc:69 +#, c-format +msgid "" +"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " +"large." +msgstr "" + +#: src/color.cc:81 +#, c-format +msgid "WARNING: Color name \"%s\" unknown. Please see" +msgstr "" + +#: src/color.cc:82 +msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" +msgstr "" + +#: src/context.cc:97 +#, c-format +msgid "WARNING: Attempt to modify constant '%s'." +msgstr "" + +#: src/context.cc:121 +#, c-format +msgid "WARNING: Ignoring unknown variable '%s'." +msgstr "" + +#: src/context.cc:128 +#, c-format +msgid "WARNING: Ignoring unknown function '%s'." +msgstr "" + +#: src/context.cc:135 +#, c-format +msgid "WARNING: Ignoring unknown module '%s'." +msgstr "" + +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#, c-format +msgid "" +"WARNING: Normalized tree is growing past %d elements. Aborting " +"normalization.\n" +msgstr "" + +#: src/dxfdata.cc:83 +#, c-format +msgid "WARNING: Can't open DXF file '%s'." +msgstr "" + +#: src/dxfdata.cc:147 +#, c-format +msgid "WARNING: Illegal ID '%s' in `%s'" +msgstr "" + +#: src/dxfdata.cc:386 +#, c-format +msgid "WARNING: Illegal value %s in '%s'" +msgstr "" + +#: src/dxfdata.cc:392 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." +msgstr "" + +#: src/dxfdata.cc:395 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." +msgstr "" + +#: src/dxfdim.cc:131 +#, c-format +msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" +msgstr "" + +#: src/dxfdim.cc:136 +#, c-format +msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" +msgstr "" + +#: src/dxfdim.cc:211 +#, c-format +msgid "WARNING: Can't find cross in '%s', layer '%s'!" +msgstr "" + +#: src/dxftess-cgal.cc:170 +msgid "" +"WARNING: Duplicate vertices and/or intersecting lines found during DXF " +"Tessellation." +msgstr "" + +#: src/dxftess-cgal.cc:171 +msgid "" +"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." +msgstr "" + +#: src/dxftess-cgal.cc:176 +#, c-format +msgid "CGAL error in dxf_tesselate(): %s" +msgstr "" + +#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 +#, c-format +msgid "GLU tesselation error %s" +msgstr "" + +#: src/export.cc:120 src/export.cc:137 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" +msgstr "" + +#: src/func.cc:503 src/func.cc:536 +#, c-format +msgid " WARNING: search term not found: \"%s\"" +msgstr "" + +#: src/func.cc:533 +#, c-format +msgid " WARNING: search term not found: %s" +msgstr "" + +#: src/func.cc:545 +#, c-format +msgid " WARNING: search: none performed on input %s" +msgstr "" + +#: src/glview.cc:149 +#, c-format +msgid "GLEW Error: %s\n" +msgstr "" + +#: src/glview.cc:161 +#, c-format +msgid "" +"GLEW version %s\n" +"OpenGL version %s\n" +"%s (%s)\n" +"\n" +"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" +"Extensions:\n" +"%s\n" +msgstr "" + +#: src/glview.cc:304 +#, c-format +msgid "" +"OpenGL Program Linker Error:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:310 +#, c-format +msgid "" +"OpenGL Program Link OK:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:315 +#, c-format +msgid "" +"OpenGL Program Validation results:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:329 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/glview.cc:332 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/glview.cc:335 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/glview.cc:339 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/handle_dep.cc:36 +#, c-format +msgid "Can't open dependencies file `%s' for writing!\n" +msgstr "" + +#: src/import.cc:195 +#, c-format +msgid "WARNING: Can't open import file '%s'." +msgstr "" + +#: src/import.cc:247 +#, c-format +msgid "WARNING: Can't parse vertex line '%s'." +msgstr "" + +#: src/import.cc:292 +msgid "WARNING: OFF import requires CGAL." +msgstr "" + +#: src/import.cc:306 +#, c-format +msgid "ERROR: Unsupported file format while trying to import file '%s'" +msgstr "" + +#: src/linearextrude.cc:77 +msgid "" +"DEPRECATED: Support for reading files in linear_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" + +#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 +#, c-format +msgid "WARNING: No suitable PolySetEvaluator found for %s module!" +msgstr "" + +#: src/mainwin.cc:119 +msgid "" +"Copyright (C) 2009-2013 The OpenSCAD Developers\n" +"\n" +"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." +msgstr "" + +#: src/mainwin.cc:525 +msgid "OpenSCAD - New Document[*]" +msgstr "" + +#: src/mainwin.cc:529 +msgid "[*]" +msgstr "" + +#: src/mainwin.cc:603 +#, c-format +msgid "Failed to open file %s: %s" +msgstr "" + +#: src/mainwin.cc:610 +#, c-format +msgid "Loaded design '%s'." +msgstr "" + +#: src/mainwin.cc:741 +msgid "Compiling design (CSG Tree generation)..." +msgstr "" + +#: src/mainwin.cc:767 +msgid "ERROR: Compilation failed! (no top level object found)" +msgstr "" + +#: src/mainwin.cc:769 +msgid "ERROR: Compilation failed!" +msgstr "" + +#: src/mainwin.cc:782 +msgid "Compiling design (CSG Products generation)..." +msgstr "" + +#: src/mainwin.cc:804 +msgid "ERROR: CSG generation failed! (no top level object found)" +msgstr "" + +#: src/mainwin.cc:813 +msgid "CSG generation cancelled." +msgstr "" + +#: src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "" + +#: src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "" + +#: src/mainwin.cc:839 +#, c-format +msgid "Compiling highlights (%d CSG Trees)..." +msgstr "" + +#: src/mainwin.cc:851 +#, c-format +msgid "Compiling background (%d CSG Trees)..." +msgstr "" + +#: src/mainwin.cc:864 +#, c-format +msgid "WARNING: Normalized tree has %d elements!" +msgstr "" + +#: src/mainwin.cc:865 +msgid "WARNING: OpenCSG rendering has been disabled." +msgstr "" + +#: src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "" + +#: src/mainwin.cc:878 +msgid "CSG generation finished." +msgstr "" + +#: src/mainwin.cc:880 src/mainwin.cc:1346 +#, c-format +msgid "Total rendering time: %d hours, %d minutes, %d seconds" +msgstr "" + +#: src/mainwin.cc:907 +msgid "Open File" +msgstr "Ouvrir un fichier" + +#: src/mainwin.cc:908 +msgid "OpenSCAD Designs (*.scad *.csg)" +msgstr "" + +#: src/mainwin.cc:1002 +#, c-format +msgid "Failed to open file for writing: %s (%s)" +msgstr "" + +#: src/mainwin.cc:1010 +#, c-format +msgid "Saved design '%s'." +msgstr "" + +#: src/mainwin.cc:1020 +msgid "Save File" +msgstr "" + +#: src/mainwin.cc:1021 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1022 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1032 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1184 src/mainwin.cc:1857 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1185 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1235 src/mainwin.cc:1279 +msgid "Parsing design (AST generation)..." +msgstr "" + +#: src/mainwin.cc:1263 +#, c-format +msgid "frame%05d.png" +msgstr "" + +#: src/mainwin.cc:1300 +msgid "Rendering Polygon Mesh using CGAL..." +msgstr "" + +#: src/mainwin.cc:1321 +msgid " Top level object is a 2D object:" +msgstr "" + +#: src/mainwin.cc:1322 +#, c-format +msgid " Empty: %6s" +msgstr "" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "yes" +msgstr "" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "no" +msgstr "" + +#: src/mainwin.cc:1323 +#, c-format +msgid " Plane: %6s" +msgstr "" + +#: src/mainwin.cc:1324 src/mainwin.cc:1336 +#, c-format +msgid " Vertices: %6d" +msgstr "" + +#: src/mainwin.cc:1325 src/mainwin.cc:1337 +#, c-format +msgid " Halfedges: %6d" +msgstr "" + +#: src/mainwin.cc:1326 src/mainwin.cc:1338 +#, c-format +msgid " Edges: %6d" +msgstr "" + +#: src/mainwin.cc:1327 +#, c-format +msgid " Faces: %6d" +msgstr "" + +#: src/mainwin.cc:1328 +#, c-format +msgid " FaceCycles: %6d" +msgstr "" + +#: src/mainwin.cc:1329 +#, c-format +msgid " ConnComp: %6d" +msgstr "" + +#: src/mainwin.cc:1333 +msgid " Top level object is a 3D object:" +msgstr "" + +#: src/mainwin.cc:1334 +#, c-format +msgid " Simple: %6s" +msgstr "" + +#: src/mainwin.cc:1335 +#, c-format +msgid " Valid: %6s" +msgstr "" + +#: src/mainwin.cc:1339 +#, c-format +msgid " Halffacets: %6d" +msgstr "" + +#: src/mainwin.cc:1340 +#, c-format +msgid " Facets: %6d" +msgstr "" + +#: src/mainwin.cc:1341 +#, c-format +msgid " Volumes: %6d" +msgstr "" + +#: src/mainwin.cc:1359 +msgid "Rendering finished." +msgstr "" + +#: src/mainwin.cc:1362 +msgid "WARNING: No top level geometry to render" +msgstr "" + +#: src/mainwin.cc:1380 +msgid "AST Dump" +msgstr "" + +#: src/mainwin.cc:1385 +msgid "No AST to dump. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1398 +msgid "CSG Tree Dump" +msgstr "" + +#: src/mainwin.cc:1403 +msgid "No CSG to dump. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1416 +msgid "CSG Products Dump" +msgstr "" + +#: src/mainwin.cc:1418 +msgid "" +"\n" +"CSG before normalization:\n" +"%1\n" +"\n" +"\n" +"CSG after normalization:\n" +"%2\n" +"\n" +"\n" +"CSG rendering chain:\n" +"%3\n" +"\n" +"\n" +"Highlights CSG rendering chain:\n" +"%4\n" +"\n" +"\n" +"Background CSG rendering chain:\n" +"%5\n" +msgstr "" + +#: src/mainwin.cc:1441 src/mainwin.cc:1501 +msgid "Nothing to export! Try building first (press F6)." +msgstr "" + +#: src/mainwin.cc:1447 +msgid "Current top level object is not a 3D object." +msgstr "" + +#: src/mainwin.cc:1453 +msgid "" +"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." +"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" + +#: src/mainwin.cc:1460 +msgid "Export STL File" +msgstr "" + +#: src/mainwin.cc:1460 +msgid "Export OFF File" +msgstr "" + +#: src/mainwin.cc:1462 +msgid "STL Files (*.stl)" +msgstr "" + +#: src/mainwin.cc:1462 +msgid "OFF Files (*.off)" +msgstr "" + +#: src/mainwin.cc:1464 +#, c-format +msgid "No filename specified. %s export aborted." +msgstr "" + +#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 +#, c-format +msgid "Can't open file \"%s\" for export" +msgstr "" + +#: src/mainwin.cc:1478 +#, c-format +msgid "%s export finished." +msgstr "" + +#: src/mainwin.cc:1507 +msgid "Current top level object is not a 2D object." +msgstr "" + +#: src/mainwin.cc:1513 +msgid "Export DXF File" +msgstr "" + +#: src/mainwin.cc:1514 +msgid "Untitled.dxf" +msgstr "" + +#: src/mainwin.cc:1515 +msgid "DXF Files (*.dxf)" +msgstr "" + +#: src/mainwin.cc:1517 +msgid "No filename specified. DXF export aborted." +msgstr "" + +#: src/mainwin.cc:1529 +msgid "DXF export finished." +msgstr "" + +#: src/mainwin.cc:1541 +msgid "Nothing to export. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1546 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:1547 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:1548 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:1550 +msgid "No filename specified. CSG export aborted." +msgstr "" + +#: src/mainwin.cc:1562 +msgid "CSG export finished." +msgstr "" + +#: src/mainwin.cc:1573 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:1573 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:1575 +msgid "No filename specified. Image export aborted." +msgstr "" + +#: src/mainwin.cc:1842 +msgid "OpenGL Info" +msgstr "Information OpenGL" + +#: src/mainwin.cc:1842 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "" + +#: src/mainwin.cc:1858 +msgid "" +"The document has been modified.\n" +"Do you want to save your changes?" +msgstr "" + +#: src/ModuleCache.cc:70 +#, c-format +msgid "Recompiling cached library: %s (%s)" +msgstr "" + +#: src/ModuleCache.cc:73 +#, c-format +msgid "Compiling library '%s'." +msgstr "" + +#: src/ModuleCache.cc:81 +#, c-format +msgid "WARNING: Can't open library file '%s'\n" +msgstr "" + +#: src/ModuleCache.cc:99 +#, c-format +msgid " compiled module: %p" +msgstr "" + +#: src/module.cc:298 +#, c-format +msgid "WARNING: Failed to compile library '%s'." +msgstr "" + +#: src/openscad.cc:109 +msgid "" +"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" +"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" +"%2%[ --version ] [ --info ] \\\n" +"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" +"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" +"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" +"%2%[ --render | --preview[=throwntogether] ] \\\n" +"%2%[ --enable= ] \\\n" +"%2%filename\n" +msgstr "" + +#: src/openscad.cc:126 +#, c-format +msgid "OpenSCAD version %s\n" +msgstr "" + +#: src/openscad.cc:583 +msgid "Allowed options" +msgstr "" + +#: src/openscad.cc:601 +msgid "Hidden options" +msgstr "" + +#: src/openscad.cc:637 +msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" +msgstr "" + +#: src/openscad.cc:642 +msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" +msgstr "" + +#: src/openscad.cc:699 +msgid "Requested GUI mode but can't open display!\n" +msgstr "" + +#: src/PolySetCache.cc:24 +#, c-format +msgid "PolySets in cache: %d" +msgstr "" + +#: src/PolySetCache.cc:25 +#, c-format +msgid "PolySet cache size in bytes: %d" +msgstr "" + +#: src/polyset.cc:55 +msgid "PolySet:" +msgstr "" + +#: src/polyset.cc:56 +msgid "" +"\n" +" dimensions:" +msgstr "" + +#: src/polyset.cc:57 +msgid "" +"\n" +" convexity:" +msgstr "" + +#: src/polyset.cc:58 +msgid "" +"\n" +" num polygons: " +msgstr "" + +#: src/polyset.cc:59 +msgid "" +"\n" +" num borders: " +msgstr "" + +#: src/polyset.cc:60 +msgid "" +"\n" +" polygons data:" +msgstr "" + +#: src/polyset.cc:62 +msgid "" +"\n" +" polygon begin:" +msgstr "" + +#: src/polyset.cc:66 src/polyset.cc:75 +msgid "" +"\n" +" vertex:" +msgstr "" + +#: src/polyset.cc:69 +msgid "" +"\n" +" borders data:" +msgstr "" + +#: src/polyset.cc:71 +msgid "" +"\n" +" border polygon begin:" +msgstr "" + +#: src/polyset.cc:78 +msgid "" +"\n" +"PolySet end" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:46 +msgid "" +"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " +"design.." +msgstr "" + +#: src/PolySetCGALEvaluator.cc:63 +#, c-format +msgid "CGAL error in projection node during plane intersection: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:65 +msgid "Trying alternative intersection using very large thin box: " +msgstr "" + +#: src/PolySetCGALEvaluator.cc:80 +#, c-format +msgid "CGAL error in projection node during bigbox intersection: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:87 +msgid "WARNING: projection() failed." +msgstr "" + +#: src/PolySetCGALEvaluator.cc:109 +#, c-format +msgid "CGAL error in projection node while flattening: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:303 +msgid "ERROR: linear_extrude() is not defined for 3D child objects!" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:343 +#, c-format +msgid "" +"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:403 +msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:441 +msgid "WARNING: Body of render() isn't valid 2-manifold!" +msgstr "" + +#: src/primitives.cc:183 +#, c-format +msgid "WARNING: $fs too small - clamping to %f" +msgstr "" + +#: src/primitives.cc:187 +#, c-format +msgid "WARNING: $fa too small - clamping to %f" +msgstr "" + +#: src/primitives.cc:536 +#, c-format +msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" +msgstr "" + +#: src/rotateextrude.cc:72 +msgid "" +"DEPRECATED: Support for reading files in rotate_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" + +#: src/surface.cc:107 +#, c-format +msgid "WARNING: Can't open DAT file '%s'." +msgstr "" + +#: src/surface.cc:139 +#, c-format +msgid "WARNING: Illegal value in '%s': %s" +msgstr "" diff --git a/po/openscad.pot b/po/openscad.pot new file mode 100644 index 00000000..f3b716dd --- /dev/null +++ b/po/openscad.pot @@ -0,0 +1,1553 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2014.01.06\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-01-06 05:06+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 +msgid "Close" +msgstr "" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: objects/ui_MainWindow.h:470 +msgid "MainWindow" +msgstr "" + +#: objects/ui_MainWindow.h:471 +msgid "&New" +msgstr "" + +#: objects/ui_MainWindow.h:472 +msgid "Ctrl+N" +msgstr "" + +#: objects/ui_MainWindow.h:473 +msgid "&Open..." +msgstr "" + +#: objects/ui_MainWindow.h:474 +msgid "Ctrl+O" +msgstr "" + +#: objects/ui_MainWindow.h:475 +msgid "&Save" +msgstr "" + +#: objects/ui_MainWindow.h:476 +msgid "Ctrl+S" +msgstr "" + +#: objects/ui_MainWindow.h:477 +msgid "Save &As..." +msgstr "" + +#: objects/ui_MainWindow.h:478 +msgid "Ctrl+Shift+S" +msgstr "" + +#: objects/ui_MainWindow.h:479 +msgid "&Reload" +msgstr "" + +#: objects/ui_MainWindow.h:480 +msgid "Ctrl+R" +msgstr "" + +#: objects/ui_MainWindow.h:481 +msgid "&Quit" +msgstr "" + +#: objects/ui_MainWindow.h:482 +msgid "Ctrl+Q" +msgstr "" + +#: objects/ui_MainWindow.h:483 +msgid "&Undo" +msgstr "" + +#: objects/ui_MainWindow.h:484 +msgid "Ctrl+Z" +msgstr "" + +#: objects/ui_MainWindow.h:485 +msgid "&Redo" +msgstr "" + +#: objects/ui_MainWindow.h:486 +msgid "Ctrl+Shift+Z" +msgstr "" + +#: objects/ui_MainWindow.h:487 +msgid "Cu&t" +msgstr "" + +#: objects/ui_MainWindow.h:488 +msgid "Ctrl+X" +msgstr "" + +#: objects/ui_MainWindow.h:489 +msgid "&Copy" +msgstr "" + +#: objects/ui_MainWindow.h:490 +msgid "Ctrl+C" +msgstr "" + +#: objects/ui_MainWindow.h:491 +msgid "&Paste" +msgstr "" + +#: objects/ui_MainWindow.h:492 +msgid "Ctrl+V" +msgstr "" + +#: objects/ui_MainWindow.h:493 +msgid "&Indent" +msgstr "" + +#: objects/ui_MainWindow.h:494 +msgid "Ctrl+I" +msgstr "" + +#: objects/ui_MainWindow.h:495 +msgid "U&nindent" +msgstr "" + +#: objects/ui_MainWindow.h:496 +msgid "Ctrl+Shift+I" +msgstr "" + +#: objects/ui_MainWindow.h:497 +msgid "C&omment" +msgstr "" + +#: objects/ui_MainWindow.h:498 +msgid "Ctrl+D" +msgstr "" + +#: objects/ui_MainWindow.h:499 +msgid "Unco&mment" +msgstr "" + +#: objects/ui_MainWindow.h:500 +msgid "Ctrl+Shift+D" +msgstr "" + +#: objects/ui_MainWindow.h:501 +msgid "Paste viewport translation" +msgstr "" + +#: objects/ui_MainWindow.h:502 +msgid "Ctrl+T" +msgstr "" + +#: objects/ui_MainWindow.h:503 +msgid "Paste viewport rotation" +msgstr "" + +#: objects/ui_MainWindow.h:504 +msgid "Zoom In" +msgstr "" + +#: objects/ui_MainWindow.h:505 +msgid "Ctrl++" +msgstr "" + +#: objects/ui_MainWindow.h:506 +msgid "Zoom Out" +msgstr "" + +#: objects/ui_MainWindow.h:507 +msgid "Ctrl+-" +msgstr "" + +#: objects/ui_MainWindow.h:508 +msgid "Hide editor" +msgstr "" + +#: objects/ui_MainWindow.h:509 +msgid "&Reload and Compile" +msgstr "" + +#: objects/ui_MainWindow.h:510 +msgid "F4" +msgstr "" + +#: objects/ui_MainWindow.h:511 +msgid "&Compile" +msgstr "" + +#: objects/ui_MainWindow.h:512 +msgid "F5" +msgstr "" + +#: objects/ui_MainWindow.h:513 +msgid "Compile and &Render (CGAL)" +msgstr "" + +#: objects/ui_MainWindow.h:514 +msgid "F6" +msgstr "" + +#: objects/ui_MainWindow.h:515 +msgid "Display &AST..." +msgstr "" + +#: objects/ui_MainWindow.h:516 +msgid "Display CSG &Tree..." +msgstr "" + +#: objects/ui_MainWindow.h:517 +msgid "Display CSG &Products..." +msgstr "" + +#: objects/ui_MainWindow.h:518 +msgid "Export as &STL..." +msgstr "" + +#: objects/ui_MainWindow.h:519 +msgid "Export as &OFF..." +msgstr "" + +#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 +msgid "OpenCSG" +msgstr "" + +#: objects/ui_MainWindow.h:521 +msgid "F9" +msgstr "" + +#: objects/ui_MainWindow.h:522 +msgid "CGAL Surfaces" +msgstr "" + +#: objects/ui_MainWindow.h:523 +msgid "F10" +msgstr "" + +#: objects/ui_MainWindow.h:524 +msgid "CGAL Grid Only" +msgstr "" + +#: objects/ui_MainWindow.h:525 +msgid "F11" +msgstr "" + +#: objects/ui_MainWindow.h:526 +msgid "Thrown Together" +msgstr "" + +#: objects/ui_MainWindow.h:527 +msgid "F12" +msgstr "" + +#: objects/ui_MainWindow.h:528 +msgid "Show Edges" +msgstr "" + +#: objects/ui_MainWindow.h:529 +msgid "Ctrl+1" +msgstr "" + +#: objects/ui_MainWindow.h:530 +msgid "Show Axes" +msgstr "" + +#: objects/ui_MainWindow.h:531 +msgid "Ctrl+2" +msgstr "" + +#: objects/ui_MainWindow.h:532 +msgid "Show Crosshairs" +msgstr "" + +#: objects/ui_MainWindow.h:533 +msgid "Ctrl+3" +msgstr "" + +#: objects/ui_MainWindow.h:534 +msgid "Animate" +msgstr "" + +#: objects/ui_MainWindow.h:535 +msgid "Top" +msgstr "" + +#: objects/ui_MainWindow.h:536 +msgid "Ctrl+4" +msgstr "" + +#: objects/ui_MainWindow.h:537 +msgid "Bottom" +msgstr "" + +#: objects/ui_MainWindow.h:538 +msgid "Ctrl+5" +msgstr "" + +#: objects/ui_MainWindow.h:539 +msgid "Left" +msgstr "" + +#: objects/ui_MainWindow.h:540 +msgid "Ctrl+6" +msgstr "" + +#: objects/ui_MainWindow.h:541 +msgid "Right" +msgstr "" + +#: objects/ui_MainWindow.h:542 +msgid "Ctrl+7" +msgstr "" + +#: objects/ui_MainWindow.h:543 +msgid "Front" +msgstr "" + +#: objects/ui_MainWindow.h:544 +msgid "Ctrl+8" +msgstr "" + +#: objects/ui_MainWindow.h:545 +msgid "Back" +msgstr "" + +#: objects/ui_MainWindow.h:546 +msgid "Ctrl+9" +msgstr "" + +#: objects/ui_MainWindow.h:547 +msgid "Diagonal" +msgstr "" + +#: objects/ui_MainWindow.h:548 +msgid "Ctrl+0" +msgstr "" + +#: objects/ui_MainWindow.h:549 +msgid "Center" +msgstr "" + +#: objects/ui_MainWindow.h:550 +msgid "Ctrl+P" +msgstr "" + +#: objects/ui_MainWindow.h:551 +msgid "Perspective" +msgstr "" + +#: objects/ui_MainWindow.h:552 +msgid "Orthogonal" +msgstr "" + +#: objects/ui_MainWindow.h:553 +msgid "Hide console" +msgstr "" + +#: objects/ui_MainWindow.h:554 +msgid "About" +msgstr "" + +#: objects/ui_MainWindow.h:555 +msgid "Documentation" +msgstr "" + +#: objects/ui_MainWindow.h:556 +msgid "Clear Recent" +msgstr "" + +#: objects/ui_MainWindow.h:557 +msgid "Export as DXF..." +msgstr "" + +#: objects/ui_MainWindow.h:559 +msgid "Ctrl+W" +msgstr "" + +#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +msgid "Preferences" +msgstr "" + +#: objects/ui_MainWindow.h:561 +msgid "Flush Caches" +msgstr "" + +#: objects/ui_MainWindow.h:562 +msgid "OpenSCAD Homepage" +msgstr "" + +#: objects/ui_MainWindow.h:563 +msgid "Automatic Reload and Compile" +msgstr "" + +#: objects/ui_MainWindow.h:564 +msgid "Export as Image..." +msgstr "" + +#: objects/ui_MainWindow.h:565 +msgid "Export as CSG..." +msgstr "" + +#: objects/ui_MainWindow.h:566 +msgid "Library info" +msgstr "" + +#: objects/ui_MainWindow.h:567 +msgid "Check for Update.." +msgstr "" + +#: objects/ui_MainWindow.h:568 +msgid "Show Library Folder..." +msgstr "" + +#: objects/ui_MainWindow.h:569 +msgid "Reset View" +msgstr "" + +#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 +msgid "Editor" +msgstr "" + +#: objects/ui_MainWindow.h:574 +msgid "Editor for SCAD code" +msgstr "" + +#: objects/ui_MainWindow.h:577 +msgid "Console" +msgstr "" + +#: objects/ui_MainWindow.h:580 +msgid "Console messages" +msgstr "" + +#: objects/ui_MainWindow.h:582 +msgid "Time:" +msgstr "" + +#: objects/ui_MainWindow.h:583 +msgid "FPS:" +msgstr "" + +#: objects/ui_MainWindow.h:584 +msgid "Steps:" +msgstr "" + +#: objects/ui_MainWindow.h:585 +msgid "Dump Pictures" +msgstr "" + +#: objects/ui_MainWindow.h:586 +msgid "&File" +msgstr "" + +#: objects/ui_MainWindow.h:587 +msgid "Open Recent" +msgstr "" + +#: objects/ui_MainWindow.h:588 +msgid "Examples" +msgstr "" + +#: objects/ui_MainWindow.h:589 +msgid "&Edit" +msgstr "" + +#: objects/ui_MainWindow.h:590 +msgid "&Design" +msgstr "" + +#: objects/ui_MainWindow.h:591 +msgid "&View" +msgstr "" + +#: objects/ui_MainWindow.h:592 +msgid "&Help" +msgstr "" + +#: objects/ui_Preferences.h:515 +msgid "3D View" +msgstr "" + +#: objects/ui_Preferences.h:516 +msgid "Advanced" +msgstr "" + +#: objects/ui_Preferences.h:518 +msgid "Update" +msgstr "" + +#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +msgid "Features" +msgstr "" + +#: objects/ui_Preferences.h:521 +msgid "Enable/Disable experimental features" +msgstr "" + +#: objects/ui_Preferences.h:523 +msgid "Color scheme:" +msgstr "" + +#: objects/ui_Preferences.h:528 +msgid "Cornfield" +msgstr "" + +#: objects/ui_Preferences.h:530 +msgid "Metallic" +msgstr "" + +#: objects/ui_Preferences.h:532 +msgid "Sunset" +msgstr "" + +#: objects/ui_Preferences.h:535 +msgid "Font" +msgstr "" + +#: objects/ui_Preferences.h:536 +msgid "Color syntax highlighting" +msgstr "" + +#: objects/ui_Preferences.h:539 +msgid "For Light Background" +msgstr "" + +#: objects/ui_Preferences.h:540 +msgid "For Dark Background" +msgstr "" + +#: objects/ui_Preferences.h:541 +msgid "Off" +msgstr "" + +#: objects/ui_Preferences.h:543 +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:544 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:545 +msgid "Check Now" +msgstr "" + +#: objects/ui_Preferences.h:546 +msgid "Last checked: " +msgstr "" + +#: objects/ui_Preferences.h:549 +msgid "Show capability warning" +msgstr "" + +#: objects/ui_Preferences.h:550 +msgid "Enable for OpenGL 1.x" +msgstr "" + +#: objects/ui_Preferences.h:551 +msgid "Turn off rendering at " +msgstr "" + +#: objects/ui_Preferences.h:552 +msgid "elements" +msgstr "" + +#: objects/ui_Preferences.h:553 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:554 +msgid "CGAL Cache size" +msgstr "" + +#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 +msgid "bytes" +msgstr "" + +#: objects/ui_Preferences.h:556 +msgid "PolySet Cache size" +msgstr "" + +#: objects/ui_Preferences.h:558 +msgid "toolBar" +msgstr "" + +#: src/cgaladv_minkowski2.cc:43 +msgid " vertices:" +msgstr "" + +#: src/cgaladv_minkowski2.cc:55 +msgid "{ Outer boundary = " +msgstr "" + +#: src/cgaladv_minkowski2.cc:58 +msgid "{ Unbounded polygon." +msgstr "" + +#: src/cgaladv_minkowski2.cc:63 +msgid " holes:" +msgstr "" + +#: src/cgaladv_minkowski2.cc:65 +msgid " Hole #" +msgstr "" + +#: src/cgaladv_minkowski2.cc:90 +msgid "" +"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" +msgstr "" + +#: src/cgaladv_minkowski2.cc:123 +msgid "WARNING: minkowski() could not get any points from object 1!" +msgstr "" + +#: src/cgaladv_minkowski2.cc:126 +msgid "WARNING: minkowski() could not get any points from object 2!" +msgstr "" + +#: src/CGALEvaluator.cc:89 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +msgstr "" + +#: src/CGALEvaluator.cc:141 +msgid "WARNING: hull() does not support mixing 2D and 3D objects." +msgstr "" + +#: src/CGALEvaluator.cc:159 +msgid "" +"Hull() currently requires a valid 2-manifold. Please modify your design. See " +"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" + +#: src/CGALEvaluator.cc:336 +msgid "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." +msgstr "" + +#: src/CGALEvaluator.cc:384 +msgid "WARNING: glide() is not implemented yet!" +msgstr "" + +#: src/CGALEvaluator.cc:388 +msgid "WARNING: subdiv() is not implemented yet!" +msgstr "" + +#: src/CGALEvaluator.cc:422 +msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" +msgstr "" + +#: src/CGALEvaluator.cc:708 +#, c-format +msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "" + +#: src/CGAL_Nef_polyhedron.cc:113 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +msgstr "" + +#: src/cgalutils.cc:138 +#, c-format +msgid "CGAL error in CGAL_Build_PolySet: %s" +msgstr "" + +#: src/cgalworker.cc:36 +msgid "Rendering cancelled." +msgstr "" + +#: src/color.cc:69 +#, c-format +msgid "" +"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " +"large." +msgstr "" + +#: src/color.cc:81 +#, c-format +msgid "WARNING: Color name \"%s\" unknown. Please see" +msgstr "" + +#: src/color.cc:82 +msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" +msgstr "" + +#: src/context.cc:97 +#, c-format +msgid "WARNING: Attempt to modify constant '%s'." +msgstr "" + +#: src/context.cc:121 +#, c-format +msgid "WARNING: Ignoring unknown variable '%s'." +msgstr "" + +#: src/context.cc:128 +#, c-format +msgid "WARNING: Ignoring unknown function '%s'." +msgstr "" + +#: src/context.cc:135 +#, c-format +msgid "WARNING: Ignoring unknown module '%s'." +msgstr "" + +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#, c-format +msgid "" +"WARNING: Normalized tree is growing past %d elements. Aborting " +"normalization.\n" +msgstr "" + +#: src/dxfdata.cc:83 +#, c-format +msgid "WARNING: Can't open DXF file '%s'." +msgstr "" + +#: src/dxfdata.cc:147 +#, c-format +msgid "WARNING: Illegal ID '%s' in `%s'" +msgstr "" + +#: src/dxfdata.cc:386 +#, c-format +msgid "WARNING: Illegal value %s in '%s'" +msgstr "" + +#: src/dxfdata.cc:392 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." +msgstr "" + +#: src/dxfdata.cc:395 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." +msgstr "" + +#: src/dxfdim.cc:131 +#, c-format +msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" +msgstr "" + +#: src/dxfdim.cc:136 +#, c-format +msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" +msgstr "" + +#: src/dxfdim.cc:211 +#, c-format +msgid "WARNING: Can't find cross in '%s', layer '%s'!" +msgstr "" + +#: src/dxftess-cgal.cc:170 +msgid "" +"WARNING: Duplicate vertices and/or intersecting lines found during DXF " +"Tessellation." +msgstr "" + +#: src/dxftess-cgal.cc:171 +msgid "" +"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." +msgstr "" + +#: src/dxftess-cgal.cc:176 +#, c-format +msgid "CGAL error in dxf_tesselate(): %s" +msgstr "" + +#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 +#, c-format +msgid "GLU tesselation error %s" +msgstr "" + +#: src/export.cc:120 src/export.cc:137 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" +msgstr "" + +#: src/func.cc:503 src/func.cc:536 +#, c-format +msgid " WARNING: search term not found: \"%s\"" +msgstr "" + +#: src/func.cc:533 +#, c-format +msgid " WARNING: search term not found: %s" +msgstr "" + +#: src/func.cc:545 +#, c-format +msgid " WARNING: search: none performed on input %s" +msgstr "" + +#: src/glview.cc:149 +#, c-format +msgid "GLEW Error: %s\n" +msgstr "" + +#: src/glview.cc:161 +#, c-format +msgid "" +"GLEW version %s\n" +"OpenGL version %s\n" +"%s (%s)\n" +"\n" +"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" +"Extensions:\n" +"%s\n" +msgstr "" + +#: src/glview.cc:304 +#, c-format +msgid "" +"OpenGL Program Linker Error:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:310 +#, c-format +msgid "" +"OpenGL Program Link OK:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:315 +#, c-format +msgid "" +"OpenGL Program Validation results:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:329 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/glview.cc:332 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/glview.cc:335 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/glview.cc:339 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/handle_dep.cc:36 +#, c-format +msgid "Can't open dependencies file `%s' for writing!\n" +msgstr "" + +#: src/import.cc:195 +#, c-format +msgid "WARNING: Can't open import file '%s'." +msgstr "" + +#: src/import.cc:247 +#, c-format +msgid "WARNING: Can't parse vertex line '%s'." +msgstr "" + +#: src/import.cc:292 +msgid "WARNING: OFF import requires CGAL." +msgstr "" + +#: src/import.cc:306 +#, c-format +msgid "ERROR: Unsupported file format while trying to import file '%s'" +msgstr "" + +#: src/linearextrude.cc:77 +msgid "" +"DEPRECATED: Support for reading files in linear_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" + +#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 +#, c-format +msgid "WARNING: No suitable PolySetEvaluator found for %s module!" +msgstr "" + +#: src/mainwin.cc:119 +msgid "" +"Copyright (C) 2009-2013 The OpenSCAD Developers\n" +"\n" +"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." +msgstr "" + +#: src/mainwin.cc:525 +msgid "OpenSCAD - New Document[*]" +msgstr "" + +#: src/mainwin.cc:529 +msgid "[*]" +msgstr "" + +#: src/mainwin.cc:603 +#, c-format +msgid "Failed to open file %s: %s" +msgstr "" + +#: src/mainwin.cc:610 +#, c-format +msgid "Loaded design '%s'." +msgstr "" + +#: src/mainwin.cc:741 +msgid "Compiling design (CSG Tree generation)..." +msgstr "" + +#: src/mainwin.cc:767 +msgid "ERROR: Compilation failed! (no top level object found)" +msgstr "" + +#: src/mainwin.cc:769 +msgid "ERROR: Compilation failed!" +msgstr "" + +#: src/mainwin.cc:782 +msgid "Compiling design (CSG Products generation)..." +msgstr "" + +#: src/mainwin.cc:804 +msgid "ERROR: CSG generation failed! (no top level object found)" +msgstr "" + +#: src/mainwin.cc:813 +msgid "CSG generation cancelled." +msgstr "" + +#: src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "" + +#: src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "" + +#: src/mainwin.cc:839 +#, c-format +msgid "Compiling highlights (%d CSG Trees)..." +msgstr "" + +#: src/mainwin.cc:851 +#, c-format +msgid "Compiling background (%d CSG Trees)..." +msgstr "" + +#: src/mainwin.cc:864 +#, c-format +msgid "WARNING: Normalized tree has %d elements!" +msgstr "" + +#: src/mainwin.cc:865 +msgid "WARNING: OpenCSG rendering has been disabled." +msgstr "" + +#: src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "" + +#: src/mainwin.cc:878 +msgid "CSG generation finished." +msgstr "" + +#: src/mainwin.cc:880 src/mainwin.cc:1346 +#, c-format +msgid "Total rendering time: %d hours, %d minutes, %d seconds" +msgstr "" + +#: src/mainwin.cc:907 +msgid "Open File" +msgstr "" + +#: src/mainwin.cc:908 +msgid "OpenSCAD Designs (*.scad *.csg)" +msgstr "" + +#: src/mainwin.cc:1002 +#, c-format +msgid "Failed to open file for writing: %s (%s)" +msgstr "" + +#: src/mainwin.cc:1010 +#, c-format +msgid "Saved design '%s'." +msgstr "" + +#: src/mainwin.cc:1020 +msgid "Save File" +msgstr "" + +#: src/mainwin.cc:1021 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1022 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1032 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1184 src/mainwin.cc:1857 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1185 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1235 src/mainwin.cc:1279 +msgid "Parsing design (AST generation)..." +msgstr "" + +#: src/mainwin.cc:1263 +#, c-format +msgid "frame%05d.png" +msgstr "" + +#: src/mainwin.cc:1300 +msgid "Rendering Polygon Mesh using CGAL..." +msgstr "" + +#: src/mainwin.cc:1321 +msgid " Top level object is a 2D object:" +msgstr "" + +#: src/mainwin.cc:1322 +#, c-format +msgid " Empty: %6s" +msgstr "" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "yes" +msgstr "" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "no" +msgstr "" + +#: src/mainwin.cc:1323 +#, c-format +msgid " Plane: %6s" +msgstr "" + +#: src/mainwin.cc:1324 src/mainwin.cc:1336 +#, c-format +msgid " Vertices: %6d" +msgstr "" + +#: src/mainwin.cc:1325 src/mainwin.cc:1337 +#, c-format +msgid " Halfedges: %6d" +msgstr "" + +#: src/mainwin.cc:1326 src/mainwin.cc:1338 +#, c-format +msgid " Edges: %6d" +msgstr "" + +#: src/mainwin.cc:1327 +#, c-format +msgid " Faces: %6d" +msgstr "" + +#: src/mainwin.cc:1328 +#, c-format +msgid " FaceCycles: %6d" +msgstr "" + +#: src/mainwin.cc:1329 +#, c-format +msgid " ConnComp: %6d" +msgstr "" + +#: src/mainwin.cc:1333 +msgid " Top level object is a 3D object:" +msgstr "" + +#: src/mainwin.cc:1334 +#, c-format +msgid " Simple: %6s" +msgstr "" + +#: src/mainwin.cc:1335 +#, c-format +msgid " Valid: %6s" +msgstr "" + +#: src/mainwin.cc:1339 +#, c-format +msgid " Halffacets: %6d" +msgstr "" + +#: src/mainwin.cc:1340 +#, c-format +msgid " Facets: %6d" +msgstr "" + +#: src/mainwin.cc:1341 +#, c-format +msgid " Volumes: %6d" +msgstr "" + +#: src/mainwin.cc:1359 +msgid "Rendering finished." +msgstr "" + +#: src/mainwin.cc:1362 +msgid "WARNING: No top level geometry to render" +msgstr "" + +#: src/mainwin.cc:1380 +msgid "AST Dump" +msgstr "" + +#: src/mainwin.cc:1385 +msgid "No AST to dump. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1398 +msgid "CSG Tree Dump" +msgstr "" + +#: src/mainwin.cc:1403 +msgid "No CSG to dump. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1416 +msgid "CSG Products Dump" +msgstr "" + +#: src/mainwin.cc:1418 +msgid "" +"\n" +"CSG before normalization:\n" +"%1\n" +"\n" +"\n" +"CSG after normalization:\n" +"%2\n" +"\n" +"\n" +"CSG rendering chain:\n" +"%3\n" +"\n" +"\n" +"Highlights CSG rendering chain:\n" +"%4\n" +"\n" +"\n" +"Background CSG rendering chain:\n" +"%5\n" +msgstr "" + +#: src/mainwin.cc:1441 src/mainwin.cc:1501 +msgid "Nothing to export! Try building first (press F6)." +msgstr "" + +#: src/mainwin.cc:1447 +msgid "Current top level object is not a 3D object." +msgstr "" + +#: src/mainwin.cc:1453 +msgid "" +"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." +"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" + +#: src/mainwin.cc:1460 +msgid "Export STL File" +msgstr "" + +#: src/mainwin.cc:1460 +msgid "Export OFF File" +msgstr "" + +#: src/mainwin.cc:1462 +msgid "STL Files (*.stl)" +msgstr "" + +#: src/mainwin.cc:1462 +msgid "OFF Files (*.off)" +msgstr "" + +#: src/mainwin.cc:1464 +#, c-format +msgid "No filename specified. %s export aborted." +msgstr "" + +#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 +#, c-format +msgid "Can't open file \"%s\" for export" +msgstr "" + +#: src/mainwin.cc:1478 +#, c-format +msgid "%s export finished." +msgstr "" + +#: src/mainwin.cc:1507 +msgid "Current top level object is not a 2D object." +msgstr "" + +#: src/mainwin.cc:1513 +msgid "Export DXF File" +msgstr "" + +#: src/mainwin.cc:1514 +msgid "Untitled.dxf" +msgstr "" + +#: src/mainwin.cc:1515 +msgid "DXF Files (*.dxf)" +msgstr "" + +#: src/mainwin.cc:1517 +msgid "No filename specified. DXF export aborted." +msgstr "" + +#: src/mainwin.cc:1529 +msgid "DXF export finished." +msgstr "" + +#: src/mainwin.cc:1541 +msgid "Nothing to export. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1546 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:1547 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:1548 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:1550 +msgid "No filename specified. CSG export aborted." +msgstr "" + +#: src/mainwin.cc:1562 +msgid "CSG export finished." +msgstr "" + +#: src/mainwin.cc:1573 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:1573 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:1575 +msgid "No filename specified. Image export aborted." +msgstr "" + +#: src/mainwin.cc:1842 +msgid "OpenGL Info" +msgstr "" + +#: src/mainwin.cc:1842 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "" + +#: src/mainwin.cc:1858 +msgid "" +"The document has been modified.\n" +"Do you want to save your changes?" +msgstr "" + +#: src/ModuleCache.cc:70 +#, c-format +msgid "Recompiling cached library: %s (%s)" +msgstr "" + +#: src/ModuleCache.cc:73 +#, c-format +msgid "Compiling library '%s'." +msgstr "" + +#: src/ModuleCache.cc:81 +#, c-format +msgid "WARNING: Can't open library file '%s'\n" +msgstr "" + +#: src/ModuleCache.cc:99 +#, c-format +msgid " compiled module: %p" +msgstr "" + +#: src/module.cc:298 +#, c-format +msgid "WARNING: Failed to compile library '%s'." +msgstr "" + +#: src/openscad.cc:109 +msgid "" +"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" +"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" +"%2%[ --version ] [ --info ] \\\n" +"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" +"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" +"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" +"%2%[ --render | --preview[=throwntogether] ] \\\n" +"%2%[ --enable= ] \\\n" +"%2%filename\n" +msgstr "" + +#: src/openscad.cc:126 +#, c-format +msgid "OpenSCAD version %s\n" +msgstr "" + +#: src/openscad.cc:583 +msgid "Allowed options" +msgstr "" + +#: src/openscad.cc:601 +msgid "Hidden options" +msgstr "" + +#: src/openscad.cc:637 +msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" +msgstr "" + +#: src/openscad.cc:642 +msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" +msgstr "" + +#: src/openscad.cc:699 +msgid "Requested GUI mode but can't open display!\n" +msgstr "" + +#: src/PolySetCache.cc:24 +#, c-format +msgid "PolySets in cache: %d" +msgstr "" + +#: src/PolySetCache.cc:25 +#, c-format +msgid "PolySet cache size in bytes: %d" +msgstr "" + +#: src/polyset.cc:55 +msgid "PolySet:" +msgstr "" + +#: src/polyset.cc:56 +msgid "" +"\n" +" dimensions:" +msgstr "" + +#: src/polyset.cc:57 +msgid "" +"\n" +" convexity:" +msgstr "" + +#: src/polyset.cc:58 +msgid "" +"\n" +" num polygons: " +msgstr "" + +#: src/polyset.cc:59 +msgid "" +"\n" +" num borders: " +msgstr "" + +#: src/polyset.cc:60 +msgid "" +"\n" +" polygons data:" +msgstr "" + +#: src/polyset.cc:62 +msgid "" +"\n" +" polygon begin:" +msgstr "" + +#: src/polyset.cc:66 src/polyset.cc:75 +msgid "" +"\n" +" vertex:" +msgstr "" + +#: src/polyset.cc:69 +msgid "" +"\n" +" borders data:" +msgstr "" + +#: src/polyset.cc:71 +msgid "" +"\n" +" border polygon begin:" +msgstr "" + +#: src/polyset.cc:78 +msgid "" +"\n" +"PolySet end" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:46 +msgid "" +"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " +"design.." +msgstr "" + +#: src/PolySetCGALEvaluator.cc:63 +#, c-format +msgid "CGAL error in projection node during plane intersection: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:65 +msgid "Trying alternative intersection using very large thin box: " +msgstr "" + +#: src/PolySetCGALEvaluator.cc:80 +#, c-format +msgid "CGAL error in projection node during bigbox intersection: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:87 +msgid "WARNING: projection() failed." +msgstr "" + +#: src/PolySetCGALEvaluator.cc:109 +#, c-format +msgid "CGAL error in projection node while flattening: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:303 +msgid "ERROR: linear_extrude() is not defined for 3D child objects!" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:343 +#, c-format +msgid "" +"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:403 +msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:441 +msgid "WARNING: Body of render() isn't valid 2-manifold!" +msgstr "" + +#: src/primitives.cc:183 +#, c-format +msgid "WARNING: $fs too small - clamping to %f" +msgstr "" + +#: src/primitives.cc:187 +#, c-format +msgid "WARNING: $fa too small - clamping to %f" +msgstr "" + +#: src/primitives.cc:536 +#, c-format +msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" +msgstr "" + +#: src/rotateextrude.cc:72 +msgid "" +"DEPRECATED: Support for reading files in rotate_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" + +#: src/surface.cc:107 +#, c-format +msgid "WARNING: Can't open DAT file '%s'." +msgstr "" + +#: src/surface.cc:139 +#, c-format +msgid "WARNING: Illegal value in '%s': %s" +msgstr "" diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh new file mode 100755 index 00000000..ddc6ecf8 --- /dev/null +++ b/scripts/translation-update.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# see doc/translation.txt for more info + +updatepot() +{ + if [ ! -e objects/ui_MainWindow.h ]; then + echo cannot find objects/ui_xxxxx.h files. perhaps if you run make...? + exit 1 + fi + VER=`date +"%Y.%m.%d"` + OPTS= + OPTS=$OPTS' --package-name=OpenSCAD' + OPTS=$OPTS' --package-version='$VER + OPTS=$OPTS' --default-domain=openscad' + OPTS=$OPTS' --keyword=_' + OPTS=$OPTS' --files-from=./po/POTFILES.in' + cmd='xgettext '$OPTS' -o ./po/openscad.pot' + echo $cmd + $cmd + if [ ! $? = 0 ]; then + echo error running xgettext + exit 1 + fi + sed -i s/"CHARSET"/"UTF-8"/g ./po/openscad.pot +} + +updatepo() +{ + for LANGCODE in `cat ./po/LINGUAS | grep -v "#"`; do + OPTS='--update --backup=t' + cmd='msgmerge '$OPTS' ./po/'$LANGCODE'.po ./po/openscad.pot' + echo $cmd + $cmd + if [ ! $? = 0 ]; then + echo error running msgmerge + exit 1 + fi + done +} + +updatemo() +{ + for LANGCODE in `cat po/LINGUAS | grep -v "#"`; do + mkdir -p ./po/$LANGCODE/LC_MESSAGES + OPTS='-c -v' + cmd='msgfmt '$OPTS' -o ./po/'$LANGCODE'/LC_MESSAGES/openscad.mo ./po/'$LANGCODE'.po' + echo $cmd + $cmd + if [ ! $? = 0 ]; then + echo error running msgfmt + exit 1 + fi + done +} + +updatepot && updatepo && updatemo + diff --git a/src/AboutDialog.h b/src/AboutDialog.h index 73c52a5e..a0c1d3f6 100644 --- a/src/AboutDialog.h +++ b/src/AboutDialog.h @@ -1,5 +1,6 @@ #pragma once +#include "qtgettext.h" #include "ui_AboutDialog.h" #define STRINGIFY(x) #x diff --git a/src/MainWindow.h b/src/MainWindow.h index 482cb205..d2e18431 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -1,5 +1,6 @@ #pragma once +#include "qtgettext.h" #include #include #include "ui_MainWindow.h" diff --git a/src/OpenCSGWarningDialog.h b/src/OpenCSGWarningDialog.h index 4cf9ec05..2ece9497 100644 --- a/src/OpenCSGWarningDialog.h +++ b/src/OpenCSGWarningDialog.h @@ -1,5 +1,6 @@ #pragma once +#include "qtgettext.h" #include "ui_OpenCSGWarningDialog.h" class OpenCSGWarningDialog : public QDialog, public Ui::OpenCSGWarningDialog diff --git a/src/Preferences.h b/src/Preferences.h index 881814e2..ec354b16 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -1,5 +1,6 @@ #pragma once +#include "qtgettext.h" #include #include #include "ui_Preferences.h" diff --git a/src/ProgressWidget.h b/src/ProgressWidget.h index 357e4c27..098cd7fe 100644 --- a/src/ProgressWidget.h +++ b/src/ProgressWidget.h @@ -1,5 +1,6 @@ #pragma once +#include "qtgettext.h" #include "ui_ProgressWidget.h" #include diff --git a/src/printutils.h b/src/printutils.h index 18eb79f1..971a6211 100644 --- a/src/printutils.h +++ b/src/printutils.h @@ -5,6 +5,10 @@ #include #include +#include +#include +inline char * _( const char * msgid ) { return gettext( msgid ); } + typedef void (OutputHandlerFunc)(const std::string &msg, void *userdata); extern OutputHandlerFunc *outputhandler; extern void *outputhandler_data; diff --git a/src/qtgettext.h b/src/qtgettext.h new file mode 100644 index 00000000..0c658606 --- /dev/null +++ b/src/qtgettext.h @@ -0,0 +1,18 @@ +#ifndef __openscad_qtgettext_h__ +#define __openscad_qtgettext_h__ + +// see doc/translation.txt + +#include "printutils.h" +#include +#include +#include + +inline QString _( const char *msgid, int category ) +{ + Q_UNUSED( category ); + return QString::fromUtf8( _( msgid ) ); +} + +#endif + From f12ff0597dd2714ec745eded67d5c7169263b6e6 Mon Sep 17 00:00:00 2001 From: don bright Date: Sat, 18 Oct 2014 19:15:27 +0200 Subject: [PATCH 002/263] First attempt at getting .mo files working with windows (wine). --- scripts/installer.nsi | 2 ++ scripts/release-common.sh | 10 ++++++++++ scripts/translation-update.sh | 6 +++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/installer.nsi b/scripts/installer.nsi index 96396169..dbc68bcd 100644 --- a/scripts/installer.nsi +++ b/scripts/installer.nsi @@ -13,6 +13,7 @@ File openscad.com File /r /x mingw-cross-env examples File /r /x mingw-cross-env libraries File /r /x mingw-cross-env fonts +File /r /x mingw-cross-env po ${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File" CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe WriteUninstaller $INSTDIR\Uninstall.exe @@ -29,6 +30,7 @@ DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Unins RMDir /r $INSTDIR\fonts RMDir /r $INSTDIR\examples RMDir /r $INSTDIR\libraries\mcad +RMDir /r $INSTDIR\po Delete $INSTDIR\libraries\boxes.scad Delete $INSTDIR\libraries\shapes.scad RMDir $INSTDIR\libraries diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 80402ef2..3eedab13 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -326,12 +326,14 @@ case $OS in EXAMPLESDIR=OpenSCAD.app/Contents/Resources/examples LIBRARYDIR=OpenSCAD.app/Contents/Resources/libraries FONTDIR=OpenSCAD.app/Contents/Resources/fonts + TRANSLATIONDIR=OpenSCAD.app/Contents/Resources/po ;; UNIX_CROSS_WIN) cd $OPENSCADDIR EXAMPLESDIR=$DEPLOYDIR/openscad-$VERSION/examples/ LIBRARYDIR=$DEPLOYDIR/openscad-$VERSION/libraries/ FONTDIR=$DEPLOYDIR/openscad-$VERSION/fonts/ + TRANSLATIONDIR=$DEPLOYDIR/openscad-$VERSION/po/ rm -rf $DEPLOYDIR/openscad-$VERSION mkdir $DEPLOYDIR/openscad-$VERSION ;; @@ -339,6 +341,7 @@ case $OS in EXAMPLESDIR=openscad-$VERSION/examples/ LIBRARYDIR=openscad-$VERSION/libraries/ FONTDIR=openscad-$VERSION/fonts/ + TRANSLATIONDIR=openscad-$VERSION/po/ rm -rf openscad-$VERSION mkdir openscad-$VERSION ;; @@ -378,6 +381,13 @@ if [ -n $LIBRARYDIR ]; then rm -f libraries.tar chmod -R u=rwx,go=r,+X $LIBRARYDIR/* fi +if [ -n $TRANSLATIONDIR ]; then + echo $TRANSLATIONDIR + mkdir -p $TRANSLATIONDIR + tar cvf translations.tar po + cd $TRANSLATIONDIR/.. && tar xvf $OPENSCADDIR/translations.tar && cd $OPENSCADDIR + rm -f translations.tar +fi echo "Creating archive.." diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index ddc6ecf8..4f2cfacf 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -54,5 +54,9 @@ updatemo() done } -updatepot && updatepo && updatemo +if [ $1 = updatemo ]; then + updatemo +else + updatepot && updatepo && updatemo +fi From 21abad2dbd3510c3842603c93db3ee0fc98d47be Mon Sep 17 00:00:00 2001 From: don bright Date: Mon, 6 Jan 2014 05:11:00 +0100 Subject: [PATCH 003/263] Add Russian stub translation. --- po/LINGUAS | 2 +- po/POTFILES.in | 2 +- po/openscad.pot | 2 +- po/ru.po | 1554 +++++++++++++++++++++++++++++++++ scripts/translation-update.sh | 2 +- 5 files changed, 1558 insertions(+), 4 deletions(-) create mode 100644 po/ru.po diff --git a/po/LINGUAS b/po/LINGUAS index f2b5b5a0..b91c4cec 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1,2 +1,2 @@ # available languages -fr +fr ru diff --git a/po/POTFILES.in b/po/POTFILES.in index 624cf316..07a3472f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -8,7 +8,7 @@ objects/ui_ProgressWidget.h objects/ui_MainWindow.h objects/ui_Preferences.h -# C++ +# C++ files src/AppleEvents.cc src/builtin.cc src/cgaladv.cc diff --git a/po/openscad.pot b/po/openscad.pot index f3b716dd..cd0fe5bf 100644 --- a/po/openscad.pot +++ b/po/openscad.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.06\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 05:06+0100\n" +"POT-Creation-Date: 2014-01-06 05:10+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 00000000..7a19222f --- /dev/null +++ b/po/ru.po @@ -0,0 +1,1554 @@ +# Russian translations for OpenSCAD package. +# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER +# This file is distributed under the same license as the OpenSCAD package. +# , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2014.01.05\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-01-06 04:13+0100\n" +"PO-Revision-Date: 2013-02-24 17:50+0100\n" +"Last-Translator: \n" +"Language-Team: Russian\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 +msgid "Close" +msgstr "" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: objects/ui_MainWindow.h:470 +msgid "MainWindow" +msgstr "" + +#: objects/ui_MainWindow.h:471 +msgid "&New" +msgstr "&Создать" + +#: objects/ui_MainWindow.h:472 +msgid "Ctrl+N" +msgstr "" + +#: objects/ui_MainWindow.h:473 +msgid "&Open..." +msgstr "&Открыть..." + +#: objects/ui_MainWindow.h:474 +msgid "Ctrl+O" +msgstr "" + +#: objects/ui_MainWindow.h:475 +msgid "&Save" +msgstr "&Сохранить" + +#: objects/ui_MainWindow.h:476 +msgid "Ctrl+S" +msgstr "" + +#: objects/ui_MainWindow.h:477 +msgid "Save &As..." +msgstr "Сохранить &как..." + +#: objects/ui_MainWindow.h:478 +msgid "Ctrl+Shift+S" +msgstr "" + +#: objects/ui_MainWindow.h:479 +msgid "&Reload" +msgstr "" + +#: objects/ui_MainWindow.h:480 +msgid "Ctrl+R" +msgstr "" + +#: objects/ui_MainWindow.h:481 +msgid "&Quit" +msgstr "&Выход" + +#: objects/ui_MainWindow.h:482 +msgid "Ctrl+Q" +msgstr "" + +#: objects/ui_MainWindow.h:483 +msgid "&Undo" +msgstr "&Отменить" + +#: objects/ui_MainWindow.h:484 +msgid "Ctrl+Z" +msgstr "" + +#: objects/ui_MainWindow.h:485 +msgid "&Redo" +msgstr "" + +#: objects/ui_MainWindow.h:486 +msgid "Ctrl+Shift+Z" +msgstr "" + +#: objects/ui_MainWindow.h:487 +msgid "Cu&t" +msgstr "" + +#: objects/ui_MainWindow.h:488 +msgid "Ctrl+X" +msgstr "" + +#: objects/ui_MainWindow.h:489 +msgid "&Copy" +msgstr "" + +#: objects/ui_MainWindow.h:490 +msgid "Ctrl+C" +msgstr "" + +#: objects/ui_MainWindow.h:491 +msgid "&Paste" +msgstr "" + +#: objects/ui_MainWindow.h:492 +msgid "Ctrl+V" +msgstr "" + +#: objects/ui_MainWindow.h:493 +msgid "&Indent" +msgstr "" + +#: objects/ui_MainWindow.h:494 +msgid "Ctrl+I" +msgstr "" + +#: objects/ui_MainWindow.h:495 +msgid "U&nindent" +msgstr "" + +#: objects/ui_MainWindow.h:496 +msgid "Ctrl+Shift+I" +msgstr "" + +#: objects/ui_MainWindow.h:497 +msgid "C&omment" +msgstr "" + +#: objects/ui_MainWindow.h:498 +msgid "Ctrl+D" +msgstr "" + +#: objects/ui_MainWindow.h:499 +msgid "Unco&mment" +msgstr "" + +#: objects/ui_MainWindow.h:500 +msgid "Ctrl+Shift+D" +msgstr "" + +#: objects/ui_MainWindow.h:501 +msgid "Paste viewport translation" +msgstr "" + +#: objects/ui_MainWindow.h:502 +msgid "Ctrl+T" +msgstr "" + +#: objects/ui_MainWindow.h:503 +msgid "Paste viewport rotation" +msgstr "" + +#: objects/ui_MainWindow.h:504 +msgid "Zoom In" +msgstr "" + +#: objects/ui_MainWindow.h:505 +msgid "Ctrl++" +msgstr "" + +#: objects/ui_MainWindow.h:506 +msgid "Zoom Out" +msgstr "" + +#: objects/ui_MainWindow.h:507 +msgid "Ctrl+-" +msgstr "" + +#: objects/ui_MainWindow.h:508 +msgid "Hide editor" +msgstr "" + +#: objects/ui_MainWindow.h:509 +msgid "&Reload and Compile" +msgstr "" + +#: objects/ui_MainWindow.h:510 +msgid "F4" +msgstr "" + +#: objects/ui_MainWindow.h:511 +msgid "&Compile" +msgstr "" + +#: objects/ui_MainWindow.h:512 +msgid "F5" +msgstr "" + +#: objects/ui_MainWindow.h:513 +msgid "Compile and &Render (CGAL)" +msgstr "" + +#: objects/ui_MainWindow.h:514 +msgid "F6" +msgstr "" + +#: objects/ui_MainWindow.h:515 +msgid "Display &AST..." +msgstr "" + +#: objects/ui_MainWindow.h:516 +msgid "Display CSG &Tree..." +msgstr "" + +#: objects/ui_MainWindow.h:517 +msgid "Display CSG &Products..." +msgstr "" + +#: objects/ui_MainWindow.h:518 +msgid "Export as &STL..." +msgstr "" + +#: objects/ui_MainWindow.h:519 +msgid "Export as &OFF..." +msgstr "" + +#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 +msgid "OpenCSG" +msgstr "" + +#: objects/ui_MainWindow.h:521 +msgid "F9" +msgstr "" + +#: objects/ui_MainWindow.h:522 +msgid "CGAL Surfaces" +msgstr "" + +#: objects/ui_MainWindow.h:523 +msgid "F10" +msgstr "" + +#: objects/ui_MainWindow.h:524 +msgid "CGAL Grid Only" +msgstr "" + +#: objects/ui_MainWindow.h:525 +msgid "F11" +msgstr "" + +#: objects/ui_MainWindow.h:526 +msgid "Thrown Together" +msgstr "" + +#: objects/ui_MainWindow.h:527 +msgid "F12" +msgstr "" + +#: objects/ui_MainWindow.h:528 +msgid "Show Edges" +msgstr "" + +#: objects/ui_MainWindow.h:529 +msgid "Ctrl+1" +msgstr "" + +#: objects/ui_MainWindow.h:530 +msgid "Show Axes" +msgstr "" + +#: objects/ui_MainWindow.h:531 +msgid "Ctrl+2" +msgstr "" + +#: objects/ui_MainWindow.h:532 +msgid "Show Crosshairs" +msgstr "" + +#: objects/ui_MainWindow.h:533 +msgid "Ctrl+3" +msgstr "" + +#: objects/ui_MainWindow.h:534 +msgid "Animate" +msgstr "" + +#: objects/ui_MainWindow.h:535 +msgid "Top" +msgstr "" + +#: objects/ui_MainWindow.h:536 +msgid "Ctrl+4" +msgstr "" + +#: objects/ui_MainWindow.h:537 +msgid "Bottom" +msgstr "" + +#: objects/ui_MainWindow.h:538 +msgid "Ctrl+5" +msgstr "" + +#: objects/ui_MainWindow.h:539 +msgid "Left" +msgstr "" + +#: objects/ui_MainWindow.h:540 +msgid "Ctrl+6" +msgstr "" + +#: objects/ui_MainWindow.h:541 +msgid "Right" +msgstr "" + +#: objects/ui_MainWindow.h:542 +msgid "Ctrl+7" +msgstr "" + +#: objects/ui_MainWindow.h:543 +msgid "Front" +msgstr "" + +#: objects/ui_MainWindow.h:544 +msgid "Ctrl+8" +msgstr "" + +#: objects/ui_MainWindow.h:545 +msgid "Back" +msgstr "" + +#: objects/ui_MainWindow.h:546 +msgid "Ctrl+9" +msgstr "" + +#: objects/ui_MainWindow.h:547 +msgid "Diagonal" +msgstr "" + +#: objects/ui_MainWindow.h:548 +msgid "Ctrl+0" +msgstr "" + +#: objects/ui_MainWindow.h:549 +msgid "Center" +msgstr "" + +#: objects/ui_MainWindow.h:550 +msgid "Ctrl+P" +msgstr "" + +#: objects/ui_MainWindow.h:551 +msgid "Perspective" +msgstr "" + +#: objects/ui_MainWindow.h:552 +msgid "Orthogonal" +msgstr "" + +#: objects/ui_MainWindow.h:553 +msgid "Hide console" +msgstr "" + +#: objects/ui_MainWindow.h:554 +msgid "About" +msgstr "" + +#: objects/ui_MainWindow.h:555 +msgid "Documentation" +msgstr "" + +#: objects/ui_MainWindow.h:556 +msgid "Clear Recent" +msgstr "" + +#: objects/ui_MainWindow.h:557 +msgid "Export as DXF..." +msgstr "" + +#: objects/ui_MainWindow.h:559 +msgid "Ctrl+W" +msgstr "" + +#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +msgid "Preferences" +msgstr "" + +#: objects/ui_MainWindow.h:561 +msgid "Flush Caches" +msgstr "" + +#: objects/ui_MainWindow.h:562 +msgid "OpenSCAD Homepage" +msgstr "" + +#: objects/ui_MainWindow.h:563 +msgid "Automatic Reload and Compile" +msgstr "" + +#: objects/ui_MainWindow.h:564 +msgid "Export as Image..." +msgstr "" + +#: objects/ui_MainWindow.h:565 +msgid "Export as CSG..." +msgstr "" + +#: objects/ui_MainWindow.h:566 +msgid "Library info" +msgstr "" + +#: objects/ui_MainWindow.h:567 +msgid "Check for Update.." +msgstr "" + +#: objects/ui_MainWindow.h:568 +msgid "Show Library Folder..." +msgstr "" + +#: objects/ui_MainWindow.h:569 +msgid "Reset View" +msgstr "" + +#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 +msgid "Editor" +msgstr "" + +#: objects/ui_MainWindow.h:574 +msgid "Editor for SCAD code" +msgstr "" + +#: objects/ui_MainWindow.h:577 +msgid "Console" +msgstr "" + +#: objects/ui_MainWindow.h:580 +msgid "Console messages" +msgstr "" + +#: objects/ui_MainWindow.h:582 +msgid "Time:" +msgstr "" + +#: objects/ui_MainWindow.h:583 +msgid "FPS:" +msgstr "" + +#: objects/ui_MainWindow.h:584 +msgid "Steps:" +msgstr "" + +#: objects/ui_MainWindow.h:585 +msgid "Dump Pictures" +msgstr "" + +#: objects/ui_MainWindow.h:586 +msgid "&File" +msgstr "&Файл" + +#: objects/ui_MainWindow.h:587 +msgid "Open Recent" +msgstr "" + +#: objects/ui_MainWindow.h:588 +msgid "Examples" +msgstr "" + +#: objects/ui_MainWindow.h:589 +msgid "&Edit" +msgstr "&Правка" + +#: objects/ui_MainWindow.h:590 +msgid "&Design" +msgstr "" + +#: objects/ui_MainWindow.h:591 +msgid "&View" +msgstr "" + +#: objects/ui_MainWindow.h:592 +msgid "&Help" +msgstr "&Справка" + +#: objects/ui_Preferences.h:515 +msgid "3D View" +msgstr "" + +#: objects/ui_Preferences.h:516 +msgid "Advanced" +msgstr "" + +#: objects/ui_Preferences.h:518 +msgid "Update" +msgstr "" + +#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +msgid "Features" +msgstr "" + +#: objects/ui_Preferences.h:521 +msgid "Enable/Disable experimental features" +msgstr "" + +#: objects/ui_Preferences.h:523 +msgid "Color scheme:" +msgstr "" + +#: objects/ui_Preferences.h:528 +msgid "Cornfield" +msgstr "" + +#: objects/ui_Preferences.h:530 +msgid "Metallic" +msgstr "" + +#: objects/ui_Preferences.h:532 +msgid "Sunset" +msgstr "" + +#: objects/ui_Preferences.h:535 +msgid "Font" +msgstr "" + +#: objects/ui_Preferences.h:536 +msgid "Color syntax highlighting" +msgstr "" + +#: objects/ui_Preferences.h:539 +msgid "For Light Background" +msgstr "" + +#: objects/ui_Preferences.h:540 +msgid "For Dark Background" +msgstr "" + +#: objects/ui_Preferences.h:541 +msgid "Off" +msgstr "" + +#: objects/ui_Preferences.h:543 +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:544 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:545 +msgid "Check Now" +msgstr "" + +#: objects/ui_Preferences.h:546 +msgid "Last checked: " +msgstr "" + +#: objects/ui_Preferences.h:549 +msgid "Show capability warning" +msgstr "" + +#: objects/ui_Preferences.h:550 +msgid "Enable for OpenGL 1.x" +msgstr "" + +#: objects/ui_Preferences.h:551 +msgid "Turn off rendering at " +msgstr "" + +#: objects/ui_Preferences.h:552 +msgid "elements" +msgstr "" + +#: objects/ui_Preferences.h:553 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:554 +msgid "CGAL Cache size" +msgstr "" + +#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 +msgid "bytes" +msgstr "" + +#: objects/ui_Preferences.h:556 +msgid "PolySet Cache size" +msgstr "" + +#: objects/ui_Preferences.h:558 +msgid "toolBar" +msgstr "" + +#: src/cgaladv_minkowski2.cc:43 +msgid " vertices:" +msgstr "" + +#: src/cgaladv_minkowski2.cc:55 +msgid "{ Outer boundary = " +msgstr "" + +#: src/cgaladv_minkowski2.cc:58 +msgid "{ Unbounded polygon." +msgstr "" + +#: src/cgaladv_minkowski2.cc:63 +msgid " holes:" +msgstr "" + +#: src/cgaladv_minkowski2.cc:65 +msgid " Hole #" +msgstr "" + +#: src/cgaladv_minkowski2.cc:90 +msgid "" +"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" +msgstr "" + +#: src/cgaladv_minkowski2.cc:123 +msgid "WARNING: minkowski() could not get any points from object 1!" +msgstr "" + +#: src/cgaladv_minkowski2.cc:126 +msgid "WARNING: minkowski() could not get any points from object 2!" +msgstr "" + +#: src/CGALEvaluator.cc:89 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +msgstr "" + +#: src/CGALEvaluator.cc:141 +msgid "WARNING: hull() does not support mixing 2D and 3D objects." +msgstr "" + +#: src/CGALEvaluator.cc:159 +msgid "" +"Hull() currently requires a valid 2-manifold. Please modify your design. See " +"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" + +#: src/CGALEvaluator.cc:336 +msgid "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." +msgstr "" + +#: src/CGALEvaluator.cc:384 +msgid "WARNING: glide() is not implemented yet!" +msgstr "" + +#: src/CGALEvaluator.cc:388 +msgid "WARNING: subdiv() is not implemented yet!" +msgstr "" + +#: src/CGALEvaluator.cc:422 +msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" +msgstr "" + +#: src/CGALEvaluator.cc:708 +#, c-format +msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "" + +#: src/CGAL_Nef_polyhedron.cc:113 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +msgstr "" + +#: src/cgalutils.cc:138 +#, c-format +msgid "CGAL error in CGAL_Build_PolySet: %s" +msgstr "" + +#: src/cgalworker.cc:36 +msgid "Rendering cancelled." +msgstr "" + +#: src/color.cc:69 +#, c-format +msgid "" +"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " +"large." +msgstr "" + +#: src/color.cc:81 +#, c-format +msgid "WARNING: Color name \"%s\" unknown. Please see" +msgstr "" + +#: src/color.cc:82 +msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" +msgstr "" + +#: src/context.cc:97 +#, c-format +msgid "WARNING: Attempt to modify constant '%s'." +msgstr "" + +#: src/context.cc:121 +#, c-format +msgid "WARNING: Ignoring unknown variable '%s'." +msgstr "" + +#: src/context.cc:128 +#, c-format +msgid "WARNING: Ignoring unknown function '%s'." +msgstr "" + +#: src/context.cc:135 +#, c-format +msgid "WARNING: Ignoring unknown module '%s'." +msgstr "" + +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#, c-format +msgid "" +"WARNING: Normalized tree is growing past %d elements. Aborting " +"normalization.\n" +msgstr "" + +#: src/dxfdata.cc:83 +#, c-format +msgid "WARNING: Can't open DXF file '%s'." +msgstr "" + +#: src/dxfdata.cc:147 +#, c-format +msgid "WARNING: Illegal ID '%s' in `%s'" +msgstr "" + +#: src/dxfdata.cc:386 +#, c-format +msgid "WARNING: Illegal value %s in '%s'" +msgstr "" + +#: src/dxfdata.cc:392 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." +msgstr "" + +#: src/dxfdata.cc:395 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." +msgstr "" + +#: src/dxfdim.cc:131 +#, c-format +msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" +msgstr "" + +#: src/dxfdim.cc:136 +#, c-format +msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" +msgstr "" + +#: src/dxfdim.cc:211 +#, c-format +msgid "WARNING: Can't find cross in '%s', layer '%s'!" +msgstr "" + +#: src/dxftess-cgal.cc:170 +msgid "" +"WARNING: Duplicate vertices and/or intersecting lines found during DXF " +"Tessellation." +msgstr "" + +#: src/dxftess-cgal.cc:171 +msgid "" +"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." +msgstr "" + +#: src/dxftess-cgal.cc:176 +#, c-format +msgid "CGAL error in dxf_tesselate(): %s" +msgstr "" + +#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 +#, c-format +msgid "GLU tesselation error %s" +msgstr "" + +#: src/export.cc:120 src/export.cc:137 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" +msgstr "" + +#: src/func.cc:503 src/func.cc:536 +#, c-format +msgid " WARNING: search term not found: \"%s\"" +msgstr "" + +#: src/func.cc:533 +#, c-format +msgid " WARNING: search term not found: %s" +msgstr "" + +#: src/func.cc:545 +#, c-format +msgid " WARNING: search: none performed on input %s" +msgstr "" + +#: src/glview.cc:149 +#, c-format +msgid "GLEW Error: %s\n" +msgstr "" + +#: src/glview.cc:161 +#, c-format +msgid "" +"GLEW version %s\n" +"OpenGL version %s\n" +"%s (%s)\n" +"\n" +"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" +"Extensions:\n" +"%s\n" +msgstr "" + +#: src/glview.cc:304 +#, c-format +msgid "" +"OpenGL Program Linker Error:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:310 +#, c-format +msgid "" +"OpenGL Program Link OK:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:315 +#, c-format +msgid "" +"OpenGL Program Validation results:\n" +"%.*s" +msgstr "" + +#: src/glview.cc:329 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/glview.cc:332 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/glview.cc:335 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/glview.cc:339 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/handle_dep.cc:36 +#, c-format +msgid "Can't open dependencies file `%s' for writing!\n" +msgstr "" + +#: src/import.cc:195 +#, c-format +msgid "WARNING: Can't open import file '%s'." +msgstr "" + +#: src/import.cc:247 +#, c-format +msgid "WARNING: Can't parse vertex line '%s'." +msgstr "" + +#: src/import.cc:292 +msgid "WARNING: OFF import requires CGAL." +msgstr "" + +#: src/import.cc:306 +#, c-format +msgid "ERROR: Unsupported file format while trying to import file '%s'" +msgstr "" + +#: src/linearextrude.cc:77 +msgid "" +"DEPRECATED: Support for reading files in linear_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" + +#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 +#, c-format +msgid "WARNING: No suitable PolySetEvaluator found for %s module!" +msgstr "" + +#: src/mainwin.cc:119 +msgid "" +"Copyright (C) 2009-2013 The OpenSCAD Developers\n" +"\n" +"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." +msgstr "" + +#: src/mainwin.cc:525 +msgid "OpenSCAD - New Document[*]" +msgstr "" + +#: src/mainwin.cc:529 +msgid "[*]" +msgstr "" + +#: src/mainwin.cc:603 +#, c-format +msgid "Failed to open file %s: %s" +msgstr "" + +#: src/mainwin.cc:610 +#, c-format +msgid "Loaded design '%s'." +msgstr "" + +#: src/mainwin.cc:741 +msgid "Compiling design (CSG Tree generation)..." +msgstr "" + +#: src/mainwin.cc:767 +msgid "ERROR: Compilation failed! (no top level object found)" +msgstr "" + +#: src/mainwin.cc:769 +msgid "ERROR: Compilation failed!" +msgstr "" + +#: src/mainwin.cc:782 +msgid "Compiling design (CSG Products generation)..." +msgstr "" + +#: src/mainwin.cc:804 +msgid "ERROR: CSG generation failed! (no top level object found)" +msgstr "" + +#: src/mainwin.cc:813 +msgid "CSG generation cancelled." +msgstr "" + +#: src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "" + +#: src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "" + +#: src/mainwin.cc:839 +#, c-format +msgid "Compiling highlights (%d CSG Trees)..." +msgstr "" + +#: src/mainwin.cc:851 +#, c-format +msgid "Compiling background (%d CSG Trees)..." +msgstr "" + +#: src/mainwin.cc:864 +#, c-format +msgid "WARNING: Normalized tree has %d elements!" +msgstr "" + +#: src/mainwin.cc:865 +msgid "WARNING: OpenCSG rendering has been disabled." +msgstr "" + +#: src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "" + +#: src/mainwin.cc:878 +msgid "CSG generation finished." +msgstr "" + +#: src/mainwin.cc:880 src/mainwin.cc:1346 +#, c-format +msgid "Total rendering time: %d hours, %d minutes, %d seconds" +msgstr "" + +#: src/mainwin.cc:907 +msgid "Open File" +msgstr "Открыть файл" + +#: src/mainwin.cc:908 +msgid "OpenSCAD Designs (*.scad *.csg)" +msgstr "" + +#: src/mainwin.cc:1002 +#, c-format +msgid "Failed to open file for writing: %s (%s)" +msgstr "" + +#: src/mainwin.cc:1010 +#, c-format +msgid "Saved design '%s'." +msgstr "" + +#: src/mainwin.cc:1020 +msgid "Save File" +msgstr "Сохранить файл" + +#: src/mainwin.cc:1021 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1022 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1032 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1184 src/mainwin.cc:1857 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1185 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1235 src/mainwin.cc:1279 +msgid "Parsing design (AST generation)..." +msgstr "" + +#: src/mainwin.cc:1263 +#, c-format +msgid "frame%05d.png" +msgstr "" + +#: src/mainwin.cc:1300 +msgid "Rendering Polygon Mesh using CGAL..." +msgstr "" + +#: src/mainwin.cc:1321 +msgid " Top level object is a 2D object:" +msgstr "" + +#: src/mainwin.cc:1322 +#, c-format +msgid " Empty: %6s" +msgstr "" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "yes" +msgstr "" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "no" +msgstr "" + +#: src/mainwin.cc:1323 +#, c-format +msgid " Plane: %6s" +msgstr "" + +#: src/mainwin.cc:1324 src/mainwin.cc:1336 +#, c-format +msgid " Vertices: %6d" +msgstr "" + +#: src/mainwin.cc:1325 src/mainwin.cc:1337 +#, c-format +msgid " Halfedges: %6d" +msgstr "" + +#: src/mainwin.cc:1326 src/mainwin.cc:1338 +#, c-format +msgid " Edges: %6d" +msgstr "" + +#: src/mainwin.cc:1327 +#, c-format +msgid " Faces: %6d" +msgstr "" + +#: src/mainwin.cc:1328 +#, c-format +msgid " FaceCycles: %6d" +msgstr "" + +#: src/mainwin.cc:1329 +#, c-format +msgid " ConnComp: %6d" +msgstr "" + +#: src/mainwin.cc:1333 +msgid " Top level object is a 3D object:" +msgstr "" + +#: src/mainwin.cc:1334 +#, c-format +msgid " Simple: %6s" +msgstr "" + +#: src/mainwin.cc:1335 +#, c-format +msgid " Valid: %6s" +msgstr "" + +#: src/mainwin.cc:1339 +#, c-format +msgid " Halffacets: %6d" +msgstr "" + +#: src/mainwin.cc:1340 +#, c-format +msgid " Facets: %6d" +msgstr "" + +#: src/mainwin.cc:1341 +#, c-format +msgid " Volumes: %6d" +msgstr "" + +#: src/mainwin.cc:1359 +msgid "Rendering finished." +msgstr "" + +#: src/mainwin.cc:1362 +msgid "WARNING: No top level geometry to render" +msgstr "" + +#: src/mainwin.cc:1380 +msgid "AST Dump" +msgstr "" + +#: src/mainwin.cc:1385 +msgid "No AST to dump. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1398 +msgid "CSG Tree Dump" +msgstr "" + +#: src/mainwin.cc:1403 +msgid "No CSG to dump. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1416 +msgid "CSG Products Dump" +msgstr "" + +#: src/mainwin.cc:1418 +msgid "" +"\n" +"CSG before normalization:\n" +"%1\n" +"\n" +"\n" +"CSG after normalization:\n" +"%2\n" +"\n" +"\n" +"CSG rendering chain:\n" +"%3\n" +"\n" +"\n" +"Highlights CSG rendering chain:\n" +"%4\n" +"\n" +"\n" +"Background CSG rendering chain:\n" +"%5\n" +msgstr "" + +#: src/mainwin.cc:1441 src/mainwin.cc:1501 +msgid "Nothing to export! Try building first (press F6)." +msgstr "" + +#: src/mainwin.cc:1447 +msgid "Current top level object is not a 3D object." +msgstr "" + +#: src/mainwin.cc:1453 +msgid "" +"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." +"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" + +#: src/mainwin.cc:1460 +msgid "Export STL File" +msgstr "" + +#: src/mainwin.cc:1460 +msgid "Export OFF File" +msgstr "" + +#: src/mainwin.cc:1462 +msgid "STL Files (*.stl)" +msgstr "" + +#: src/mainwin.cc:1462 +msgid "OFF Files (*.off)" +msgstr "" + +#: src/mainwin.cc:1464 +#, c-format +msgid "No filename specified. %s export aborted." +msgstr "" + +#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 +#, c-format +msgid "Can't open file \"%s\" for export" +msgstr "" + +#: src/mainwin.cc:1478 +#, c-format +msgid "%s export finished." +msgstr "" + +#: src/mainwin.cc:1507 +msgid "Current top level object is not a 2D object." +msgstr "" + +#: src/mainwin.cc:1513 +msgid "Export DXF File" +msgstr "" + +#: src/mainwin.cc:1514 +msgid "Untitled.dxf" +msgstr "" + +#: src/mainwin.cc:1515 +msgid "DXF Files (*.dxf)" +msgstr "" + +#: src/mainwin.cc:1517 +msgid "No filename specified. DXF export aborted." +msgstr "" + +#: src/mainwin.cc:1529 +msgid "DXF export finished." +msgstr "" + +#: src/mainwin.cc:1541 +msgid "Nothing to export. Please try compiling first..." +msgstr "" + +#: src/mainwin.cc:1546 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:1547 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:1548 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:1550 +msgid "No filename specified. CSG export aborted." +msgstr "" + +#: src/mainwin.cc:1562 +msgid "CSG export finished." +msgstr "" + +#: src/mainwin.cc:1573 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:1573 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:1575 +msgid "No filename specified. Image export aborted." +msgstr "" + +#: src/mainwin.cc:1842 +msgid "OpenGL Info" +msgstr "" + +#: src/mainwin.cc:1842 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "" + +#: src/mainwin.cc:1858 +msgid "" +"The document has been modified.\n" +"Do you want to save your changes?" +msgstr "" + +#: src/ModuleCache.cc:70 +#, c-format +msgid "Recompiling cached library: %s (%s)" +msgstr "" + +#: src/ModuleCache.cc:73 +#, c-format +msgid "Compiling library '%s'." +msgstr "" + +#: src/ModuleCache.cc:81 +#, c-format +msgid "WARNING: Can't open library file '%s'\n" +msgstr "" + +#: src/ModuleCache.cc:99 +#, c-format +msgid " compiled module: %p" +msgstr "" + +#: src/module.cc:298 +#, c-format +msgid "WARNING: Failed to compile library '%s'." +msgstr "" + +#: src/openscad.cc:109 +msgid "" +"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" +"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" +"%2%[ --version ] [ --info ] \\\n" +"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" +"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" +"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" +"%2%[ --render | --preview[=throwntogether] ] \\\n" +"%2%[ --enable= ] \\\n" +"%2%filename\n" +msgstr "" + +#: src/openscad.cc:126 +#, c-format +msgid "OpenSCAD version %s\n" +msgstr "" + +#: src/openscad.cc:583 +msgid "Allowed options" +msgstr "" + +#: src/openscad.cc:601 +msgid "Hidden options" +msgstr "" + +#: src/openscad.cc:637 +msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" +msgstr "" + +#: src/openscad.cc:642 +msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" +msgstr "" + +#: src/openscad.cc:699 +msgid "Requested GUI mode but can't open display!\n" +msgstr "" + +#: src/PolySetCache.cc:24 +#, c-format +msgid "PolySets in cache: %d" +msgstr "" + +#: src/PolySetCache.cc:25 +#, c-format +msgid "PolySet cache size in bytes: %d" +msgstr "" + +#: src/polyset.cc:55 +msgid "PolySet:" +msgstr "" + +#: src/polyset.cc:56 +msgid "" +"\n" +" dimensions:" +msgstr "" + +#: src/polyset.cc:57 +msgid "" +"\n" +" convexity:" +msgstr "" + +#: src/polyset.cc:58 +msgid "" +"\n" +" num polygons: " +msgstr "" + +#: src/polyset.cc:59 +msgid "" +"\n" +" num borders: " +msgstr "" + +#: src/polyset.cc:60 +msgid "" +"\n" +" polygons data:" +msgstr "" + +#: src/polyset.cc:62 +msgid "" +"\n" +" polygon begin:" +msgstr "" + +#: src/polyset.cc:66 src/polyset.cc:75 +msgid "" +"\n" +" vertex:" +msgstr "" + +#: src/polyset.cc:69 +msgid "" +"\n" +" borders data:" +msgstr "" + +#: src/polyset.cc:71 +msgid "" +"\n" +" border polygon begin:" +msgstr "" + +#: src/polyset.cc:78 +msgid "" +"\n" +"PolySet end" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:46 +msgid "" +"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " +"design.." +msgstr "" + +#: src/PolySetCGALEvaluator.cc:63 +#, c-format +msgid "CGAL error in projection node during plane intersection: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:65 +msgid "Trying alternative intersection using very large thin box: " +msgstr "" + +#: src/PolySetCGALEvaluator.cc:80 +#, c-format +msgid "CGAL error in projection node during bigbox intersection: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:87 +msgid "WARNING: projection() failed." +msgstr "" + +#: src/PolySetCGALEvaluator.cc:109 +#, c-format +msgid "CGAL error in projection node while flattening: %s" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:303 +msgid "ERROR: linear_extrude() is not defined for 3D child objects!" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:343 +#, c-format +msgid "" +"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:403 +msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" +msgstr "" + +#: src/PolySetCGALEvaluator.cc:441 +msgid "WARNING: Body of render() isn't valid 2-manifold!" +msgstr "" + +#: src/primitives.cc:183 +#, c-format +msgid "WARNING: $fs too small - clamping to %f" +msgstr "" + +#: src/primitives.cc:187 +#, c-format +msgid "WARNING: $fa too small - clamping to %f" +msgstr "" + +#: src/primitives.cc:536 +#, c-format +msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" +msgstr "" + +#: src/rotateextrude.cc:72 +msgid "" +"DEPRECATED: Support for reading files in rotate_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" + +#: src/surface.cc:107 +#, c-format +msgid "WARNING: Can't open DAT file '%s'." +msgstr "" + +#: src/surface.cc:139 +#, c-format +msgid "WARNING: Illegal value in '%s': %s" +msgstr "" diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index 4f2cfacf..b2db9de9 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -54,7 +54,7 @@ updatemo() done } -if [ $1 = updatemo ]; then +if [ "x$1" = xupdatemo ]; then updatemo else updatepot && updatepo && updatemo From 17244af2f9c834e540b21abd5fdd8cd0208a7b91 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:18:01 +0200 Subject: [PATCH 004/263] Add more gettext calls. --- po/fr.po | 363 +++++++++++++++++++++++++++++++++++++++++++++- po/openscad.pot | 363 +++++++++++++++++++++++++++++++++++++++++++++- po/ru.po | 363 +++++++++++++++++++++++++++++++++++++++++++++- src/AboutDialog.h | 2 +- src/QGLView.cc | 16 +- 5 files changed, 1092 insertions(+), 15 deletions(-) diff --git a/po/fr.po b/po/fr.po index 6663821d..4c2009b2 100644 --- a/po/fr.po +++ b/po/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2013.02.07\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 05:06+0100\n" +"POT-Creation-Date: 2014-01-06 05:16+0100\n" "PO-Revision-Date: 2013-02-08 15:06-0600\n" "Last-Translator: don bright \n" "Language-Team: French\n" @@ -659,6 +659,31 @@ msgstr "" msgid "WARNING: minkowski() could not get any points from object 2!" msgstr "" +#: src/CGALCache.cc:15 +#, c-format +msgid "CGAL Cache hit: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:24 +#, c-format +msgid "CGAL Cache insert: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:25 +#, c-format +msgid "CGAL Cache insert failed: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:47 +#, c-format +msgid "CGAL Polyhedrons in cache: %d" +msgstr "" + +#: src/CGALCache.cc:48 +#, c-format +msgid "CGAL cache size in bytes: %d" +msgstr "" + #: src/CGALEvaluator.cc:89 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" @@ -674,6 +699,19 @@ msgid "" "http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" +#: src/CGALEvaluator.cc:172 +#, c-format +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +msgstr "" + +#: src/CGALEvaluator.cc:207 +msgid "WARNING: Cannot resize to sizes less than 0." +msgstr "" + +#: src/CGALEvaluator.cc:234 +msgid "WARNING: Resize in direction normal to flat object is not implemented" +msgstr "" + #: src/CGALEvaluator.cc:336 msgid "" "Warning: Transformation matrix contains Not-a-Number and/or Infinity - " @@ -692,6 +730,15 @@ msgstr "" msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" msgstr "" +#: src/CGALEvaluator.cc:693 +msgid "PolySet has nonplanar faces. Attempting alternate construction" +msgstr "" + +#: src/CGALEvaluator.cc:697 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "" + #: src/CGALEvaluator.cc:708 #, c-format msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" @@ -701,6 +748,19 @@ msgstr "" msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." msgstr "" +#: src/CGAL_Nef_polyhedron.cc:114 +#, c-format +msgid "ERROR: %s" +msgstr "" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:107 +msgid "Warning: Scaling a 2D object with 0 - removing object" +msgstr "" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:137 +msgid "Warning: Scaling a 3D object with 0 - removing object" +msgstr "" + #: src/cgalutils.cc:138 #, c-format msgid "CGAL error in CGAL_Build_PolySet: %s" @@ -746,6 +806,66 @@ msgstr "" msgid "WARNING: Ignoring unknown module '%s'." msgstr "" +#: src/context.cc:156 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p)" +msgstr "" + +#: src/context.cc:158 +#, c-format +msgid "Context: %p (%p)" +msgstr "" + +#: src/context.cc:159 +#, c-format +msgid " document path: %s" +msgstr "" + +#: src/context.cc:163 +msgid " module args:" +msgstr "" + +#: src/context.cc:170 +msgid " vars:" +msgstr "" + +#: src/control.cc:83 +#, c-format +msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." +msgstr "" + +#: src/control.cc:133 src/control.cc:138 src/control.cc:247 +#, c-format +msgid "" +"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " +"vector, range." +msgstr "" + +#: src/control.cc:144 +#, c-format +msgid "WARNING: Negative children index (%d) not allowed" +msgstr "" + +#: src/control.cc:150 +#, c-format +msgid "WARNING: Children index (%d) out of bounds (%d children)" +msgstr "" + +#: src/control.cc:170 +#, c-format +msgid "WARNING: Negative child index (%d) not allowed" +msgstr "" + +#: src/control.cc:189 +#, c-format +msgid "WARNING: Child index (%d) out of bounds (%d children)" +msgstr "" + +#: src/control.cc:234 +#, c-format +msgid "WARNING: Bad range parameter for children: too many elements (%lu)." +msgstr "" + #: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 #, c-format msgid "" @@ -809,16 +929,37 @@ msgstr "" msgid "CGAL error in dxf_tesselate(): %s" msgstr "" +#: src/dxftess-cgal.cc:475 +#, c-format +msgid "CGAL error in dxftess triangulate_polygon: %s" +msgstr "" + +#: src/dxftess-cgal.cc:491 +msgid "WARNING: PolySet has polygon with <3 points" +msgstr "" + +#: src/dxftess-cgal.cc:496 +msgid "WARNING: PolySet has degenerate polygon" +msgstr "" + #: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 #, c-format msgid "GLU tesselation error %s" msgstr "" +#: src/export.cc:48 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" +msgstr "" + #: src/export.cc:120 src/export.cc:137 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" msgstr "" +#: src/export.cc:123 +msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" +msgstr "" + #: src/func.cc:503 src/func.cc:536 #, c-format msgid " WARNING: search term not found: \"%s\"" @@ -834,6 +975,18 @@ msgstr "" msgid " WARNING: search: none performed on input %s" msgstr "" +#: src/func.cc:591 +#, c-format +msgid "WARNING: Negative parent module index (%d) not allowed" +msgstr "" + +#: src/func.cc:595 +#, c-format +msgid "" +"WARNING: Parent module index (%d) greater than the number of modules on the " +"stack" +msgstr "" + #: src/glview.cc:149 #, c-format msgid "GLEW Error: %s\n" @@ -900,12 +1053,27 @@ msgid "" "OpenGL version %s\n" msgstr "" +#: src/glview.cc:537 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" msgstr "" -#: src/import.cc:195 +#: src/import.cc:98 +msgid "DEPRECATED: filename= is deprecated. Please use file=" +msgstr "" + +#: src/import.cc:122 +msgid "DEPRECATED: layername= is deprecated. Please use layer=" +msgstr "" + +#: src/import.cc:195 src/import.cc:281 #, c-format msgid "WARNING: Can't open import file '%s'." msgstr "" @@ -949,6 +1117,10 @@ msgstr "" msgid "OpenSCAD - New Document[*]" msgstr "" +#: src/mainwin.cc:529 +msgid "OpenSCAD - " +msgstr "" + #: src/mainwin.cc:529 msgid "[*]" msgstr "" @@ -963,6 +1135,11 @@ msgstr "" msgid "Loaded design '%s'." msgstr "" +#: src/mainwin.cc:657 +#, c-format +msgid "Module cache size: %d modules" +msgstr "" + #: src/mainwin.cc:741 msgid "Compiling design (CSG Tree generation)..." msgstr "" @@ -1041,6 +1218,12 @@ msgstr "" msgid "Failed to open file for writing: %s (%s)" msgstr "" +#: src/mainwin.cc:1003 +msgid "" +"Failed to open file for writing:\n" +" %1 (%2)" +msgstr "" + #: src/mainwin.cc:1010 #, c-format msgid "Saved design '%s'." @@ -1064,6 +1247,16 @@ msgid "" "Do you want to replace it?" msgstr "" +#: src/mainwin.cc:1047 +#, c-format +msgid "WARNING: Library path %s doesn't exist. Creating" +msgstr "" + +#: src/mainwin.cc:1049 +#, c-format +msgid "ERROR: Cannot create library path: %s" +msgstr "" + #: src/mainwin.cc:1184 src/mainwin.cc:1857 msgid "Application" msgstr "" @@ -1257,6 +1450,9 @@ msgid "No filename specified. %s export aborted." msgstr "" #: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 +#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 +#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 +#: src/openscad.cc:418 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" @@ -1326,6 +1522,14 @@ msgstr "" msgid "No filename specified. Image export aborted." msgstr "" +#: src/mainwin.cc:1827 +msgid "http://openscad.org/" +msgstr "" + +#: src/mainwin.cc:1833 +msgid "http://www.openscad.org/documentation.html" +msgstr "" + #: src/mainwin.cc:1842 msgid "OpenGL Info" msgstr "Information OpenGL" @@ -1360,6 +1564,11 @@ msgstr "" msgid " compiled module: %p" msgstr "" +#: src/module.cc:180 +#, c-format +msgid "ERROR: Recursion detected calling module '%s'" +msgstr "" + #: src/module.cc:298 #, c-format msgid "WARNING: Failed to compile library '%s'." @@ -1383,14 +1592,140 @@ msgstr "" msgid "OpenSCAD version %s\n" msgstr "" +#: src/openscad.cc:138 +#, c-format +msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" +msgstr "" + +#: src/openscad.cc:160 +msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" +msgstr "" + +#: src/openscad.cc:161 +msgid "or 6 numbers for Vector Camera\n" +msgstr "" + +#: src/openscad.cc:177 +msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" +msgstr "" + +#: src/openscad.cc:188 +msgid "Need 2 numbers for imgsize\n" +msgstr "" + +#: src/openscad.cc:236 +#, c-format +msgid "Unknown suffix for output file %s\n" +msgstr "" + +#: src/openscad.cc:260 +#, c-format +msgid "Can't open input file '%s'!\n" +msgstr "" + +#: src/openscad.cc:269 +#, c-format +msgid "Can't parse file '%s'!\n" +msgstr "" + +#: src/openscad.cc:351 +#, c-format +msgid "Output file:%s\n" +msgstr "" + +#: src/openscad.cc:352 +msgid "Sorry, don't know how to write deps for that file type. Exiting\n" +msgstr "" + +#: src/openscad.cc:357 +msgid "error writing deps" +msgstr "" + +#: src/openscad.cc:364 src/openscad.cc:383 +msgid "Current top level object is not a 3D object.\n" +msgstr "" + +#: src/openscad.cc:368 src/openscad.cc:387 +msgid "Object isn't a valid 2-manifold! Modify your design.\n" +msgstr "" + +#: src/openscad.cc:402 +msgid "Current top level object is not a 2D object.\n" +msgstr "" + #: src/openscad.cc:583 msgid "Allowed options" msgstr "" +#: src/openscad.cc:585 +msgid "help message" +msgstr "" + +#: src/openscad.cc:586 +msgid "print the version" +msgstr "" + +#: src/openscad.cc:587 +msgid "print information about the building process" +msgstr "" + +#: src/openscad.cc:588 +msgid "if exporting a png image, do a full CGAL render" +msgstr "" + +#: src/openscad.cc:589 +msgid "" +"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" +msgstr "" + +#: src/openscad.cc:590 +msgid "parameters for camera when exporting png" +msgstr "" + +#: src/openscad.cc:591 +msgid "=width,height for exporting png" +msgstr "" + +#: src/openscad.cc:592 +msgid "(o)rtho or (p)erspective when exporting png" +msgstr "" + +#: src/openscad.cc:593 +msgid "out-file" +msgstr "" + +#: src/openscad.cc:594 +msgid "stl-file" +msgstr "" + +#: src/openscad.cc:595 +msgid "dxf-file" +msgstr "" + +#: src/openscad.cc:596 +msgid "deps-file" +msgstr "" + +#: src/openscad.cc:597 +msgid "makefile" +msgstr "" + +#: src/openscad.cc:598 +msgid "var=val" +msgstr "" + +#: src/openscad.cc:599 +msgid "enable experimental features" +msgstr "" + #: src/openscad.cc:601 msgid "Hidden options" msgstr "" +#: src/openscad.cc:603 +msgid "input file" +msgstr "" + #: src/openscad.cc:637 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" @@ -1524,6 +1859,18 @@ msgstr "" msgid "WARNING: Body of render() isn't valid 2-manifold!" msgstr "" +#: src/PolySetCGALEvaluator.cc:466 +#, c-format +msgid "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" +msgstr "" + +#: src/primitives.cc:130 +#, c-format +msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." +msgstr "" + #: src/primitives.cc:183 #, c-format msgid "WARNING: $fs too small - clamping to %f" @@ -1534,6 +1881,12 @@ msgstr "" msgid "WARNING: $fa too small - clamping to %f" msgstr "" +#: src/primitives.cc:244 +msgid "" +"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " +"polyhedron(faces=[]) instead." +msgstr "" + #: src/primitives.cc:536 #, c-format msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" @@ -1554,3 +1907,9 @@ msgstr "" #, c-format msgid "WARNING: Illegal value in '%s': %s" msgstr "" + +#: src/value.cc:640 +msgid "" +"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " +"than the end value is deprecated." +msgstr "" diff --git a/po/openscad.pot b/po/openscad.pot index cd0fe5bf..ddc4bcbd 100644 --- a/po/openscad.pot +++ b/po/openscad.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.06\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 05:10+0100\n" +"POT-Creation-Date: 2014-01-06 05:16+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -656,6 +656,31 @@ msgstr "" msgid "WARNING: minkowski() could not get any points from object 2!" msgstr "" +#: src/CGALCache.cc:15 +#, c-format +msgid "CGAL Cache hit: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:24 +#, c-format +msgid "CGAL Cache insert: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:25 +#, c-format +msgid "CGAL Cache insert failed: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:47 +#, c-format +msgid "CGAL Polyhedrons in cache: %d" +msgstr "" + +#: src/CGALCache.cc:48 +#, c-format +msgid "CGAL cache size in bytes: %d" +msgstr "" + #: src/CGALEvaluator.cc:89 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" @@ -671,6 +696,19 @@ msgid "" "http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" +#: src/CGALEvaluator.cc:172 +#, c-format +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +msgstr "" + +#: src/CGALEvaluator.cc:207 +msgid "WARNING: Cannot resize to sizes less than 0." +msgstr "" + +#: src/CGALEvaluator.cc:234 +msgid "WARNING: Resize in direction normal to flat object is not implemented" +msgstr "" + #: src/CGALEvaluator.cc:336 msgid "" "Warning: Transformation matrix contains Not-a-Number and/or Infinity - " @@ -689,6 +727,15 @@ msgstr "" msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" msgstr "" +#: src/CGALEvaluator.cc:693 +msgid "PolySet has nonplanar faces. Attempting alternate construction" +msgstr "" + +#: src/CGALEvaluator.cc:697 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "" + #: src/CGALEvaluator.cc:708 #, c-format msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" @@ -698,6 +745,19 @@ msgstr "" msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." msgstr "" +#: src/CGAL_Nef_polyhedron.cc:114 +#, c-format +msgid "ERROR: %s" +msgstr "" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:107 +msgid "Warning: Scaling a 2D object with 0 - removing object" +msgstr "" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:137 +msgid "Warning: Scaling a 3D object with 0 - removing object" +msgstr "" + #: src/cgalutils.cc:138 #, c-format msgid "CGAL error in CGAL_Build_PolySet: %s" @@ -743,6 +803,66 @@ msgstr "" msgid "WARNING: Ignoring unknown module '%s'." msgstr "" +#: src/context.cc:156 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p)" +msgstr "" + +#: src/context.cc:158 +#, c-format +msgid "Context: %p (%p)" +msgstr "" + +#: src/context.cc:159 +#, c-format +msgid " document path: %s" +msgstr "" + +#: src/context.cc:163 +msgid " module args:" +msgstr "" + +#: src/context.cc:170 +msgid " vars:" +msgstr "" + +#: src/control.cc:83 +#, c-format +msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." +msgstr "" + +#: src/control.cc:133 src/control.cc:138 src/control.cc:247 +#, c-format +msgid "" +"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " +"vector, range." +msgstr "" + +#: src/control.cc:144 +#, c-format +msgid "WARNING: Negative children index (%d) not allowed" +msgstr "" + +#: src/control.cc:150 +#, c-format +msgid "WARNING: Children index (%d) out of bounds (%d children)" +msgstr "" + +#: src/control.cc:170 +#, c-format +msgid "WARNING: Negative child index (%d) not allowed" +msgstr "" + +#: src/control.cc:189 +#, c-format +msgid "WARNING: Child index (%d) out of bounds (%d children)" +msgstr "" + +#: src/control.cc:234 +#, c-format +msgid "WARNING: Bad range parameter for children: too many elements (%lu)." +msgstr "" + #: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 #, c-format msgid "" @@ -806,16 +926,37 @@ msgstr "" msgid "CGAL error in dxf_tesselate(): %s" msgstr "" +#: src/dxftess-cgal.cc:475 +#, c-format +msgid "CGAL error in dxftess triangulate_polygon: %s" +msgstr "" + +#: src/dxftess-cgal.cc:491 +msgid "WARNING: PolySet has polygon with <3 points" +msgstr "" + +#: src/dxftess-cgal.cc:496 +msgid "WARNING: PolySet has degenerate polygon" +msgstr "" + #: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 #, c-format msgid "GLU tesselation error %s" msgstr "" +#: src/export.cc:48 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" +msgstr "" + #: src/export.cc:120 src/export.cc:137 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" msgstr "" +#: src/export.cc:123 +msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" +msgstr "" + #: src/func.cc:503 src/func.cc:536 #, c-format msgid " WARNING: search term not found: \"%s\"" @@ -831,6 +972,18 @@ msgstr "" msgid " WARNING: search: none performed on input %s" msgstr "" +#: src/func.cc:591 +#, c-format +msgid "WARNING: Negative parent module index (%d) not allowed" +msgstr "" + +#: src/func.cc:595 +#, c-format +msgid "" +"WARNING: Parent module index (%d) greater than the number of modules on the " +"stack" +msgstr "" + #: src/glview.cc:149 #, c-format msgid "GLEW Error: %s\n" @@ -897,12 +1050,27 @@ msgid "" "OpenGL version %s\n" msgstr "" +#: src/glview.cc:537 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" msgstr "" -#: src/import.cc:195 +#: src/import.cc:98 +msgid "DEPRECATED: filename= is deprecated. Please use file=" +msgstr "" + +#: src/import.cc:122 +msgid "DEPRECATED: layername= is deprecated. Please use layer=" +msgstr "" + +#: src/import.cc:195 src/import.cc:281 #, c-format msgid "WARNING: Can't open import file '%s'." msgstr "" @@ -946,6 +1114,10 @@ msgstr "" msgid "OpenSCAD - New Document[*]" msgstr "" +#: src/mainwin.cc:529 +msgid "OpenSCAD - " +msgstr "" + #: src/mainwin.cc:529 msgid "[*]" msgstr "" @@ -960,6 +1132,11 @@ msgstr "" msgid "Loaded design '%s'." msgstr "" +#: src/mainwin.cc:657 +#, c-format +msgid "Module cache size: %d modules" +msgstr "" + #: src/mainwin.cc:741 msgid "Compiling design (CSG Tree generation)..." msgstr "" @@ -1038,6 +1215,12 @@ msgstr "" msgid "Failed to open file for writing: %s (%s)" msgstr "" +#: src/mainwin.cc:1003 +msgid "" +"Failed to open file for writing:\n" +" %1 (%2)" +msgstr "" + #: src/mainwin.cc:1010 #, c-format msgid "Saved design '%s'." @@ -1061,6 +1244,16 @@ msgid "" "Do you want to replace it?" msgstr "" +#: src/mainwin.cc:1047 +#, c-format +msgid "WARNING: Library path %s doesn't exist. Creating" +msgstr "" + +#: src/mainwin.cc:1049 +#, c-format +msgid "ERROR: Cannot create library path: %s" +msgstr "" + #: src/mainwin.cc:1184 src/mainwin.cc:1857 msgid "Application" msgstr "" @@ -1254,6 +1447,9 @@ msgid "No filename specified. %s export aborted." msgstr "" #: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 +#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 +#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 +#: src/openscad.cc:418 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" @@ -1323,6 +1519,14 @@ msgstr "" msgid "No filename specified. Image export aborted." msgstr "" +#: src/mainwin.cc:1827 +msgid "http://openscad.org/" +msgstr "" + +#: src/mainwin.cc:1833 +msgid "http://www.openscad.org/documentation.html" +msgstr "" + #: src/mainwin.cc:1842 msgid "OpenGL Info" msgstr "" @@ -1357,6 +1561,11 @@ msgstr "" msgid " compiled module: %p" msgstr "" +#: src/module.cc:180 +#, c-format +msgid "ERROR: Recursion detected calling module '%s'" +msgstr "" + #: src/module.cc:298 #, c-format msgid "WARNING: Failed to compile library '%s'." @@ -1380,14 +1589,140 @@ msgstr "" msgid "OpenSCAD version %s\n" msgstr "" +#: src/openscad.cc:138 +#, c-format +msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" +msgstr "" + +#: src/openscad.cc:160 +msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" +msgstr "" + +#: src/openscad.cc:161 +msgid "or 6 numbers for Vector Camera\n" +msgstr "" + +#: src/openscad.cc:177 +msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" +msgstr "" + +#: src/openscad.cc:188 +msgid "Need 2 numbers for imgsize\n" +msgstr "" + +#: src/openscad.cc:236 +#, c-format +msgid "Unknown suffix for output file %s\n" +msgstr "" + +#: src/openscad.cc:260 +#, c-format +msgid "Can't open input file '%s'!\n" +msgstr "" + +#: src/openscad.cc:269 +#, c-format +msgid "Can't parse file '%s'!\n" +msgstr "" + +#: src/openscad.cc:351 +#, c-format +msgid "Output file:%s\n" +msgstr "" + +#: src/openscad.cc:352 +msgid "Sorry, don't know how to write deps for that file type. Exiting\n" +msgstr "" + +#: src/openscad.cc:357 +msgid "error writing deps" +msgstr "" + +#: src/openscad.cc:364 src/openscad.cc:383 +msgid "Current top level object is not a 3D object.\n" +msgstr "" + +#: src/openscad.cc:368 src/openscad.cc:387 +msgid "Object isn't a valid 2-manifold! Modify your design.\n" +msgstr "" + +#: src/openscad.cc:402 +msgid "Current top level object is not a 2D object.\n" +msgstr "" + #: src/openscad.cc:583 msgid "Allowed options" msgstr "" +#: src/openscad.cc:585 +msgid "help message" +msgstr "" + +#: src/openscad.cc:586 +msgid "print the version" +msgstr "" + +#: src/openscad.cc:587 +msgid "print information about the building process" +msgstr "" + +#: src/openscad.cc:588 +msgid "if exporting a png image, do a full CGAL render" +msgstr "" + +#: src/openscad.cc:589 +msgid "" +"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" +msgstr "" + +#: src/openscad.cc:590 +msgid "parameters for camera when exporting png" +msgstr "" + +#: src/openscad.cc:591 +msgid "=width,height for exporting png" +msgstr "" + +#: src/openscad.cc:592 +msgid "(o)rtho or (p)erspective when exporting png" +msgstr "" + +#: src/openscad.cc:593 +msgid "out-file" +msgstr "" + +#: src/openscad.cc:594 +msgid "stl-file" +msgstr "" + +#: src/openscad.cc:595 +msgid "dxf-file" +msgstr "" + +#: src/openscad.cc:596 +msgid "deps-file" +msgstr "" + +#: src/openscad.cc:597 +msgid "makefile" +msgstr "" + +#: src/openscad.cc:598 +msgid "var=val" +msgstr "" + +#: src/openscad.cc:599 +msgid "enable experimental features" +msgstr "" + #: src/openscad.cc:601 msgid "Hidden options" msgstr "" +#: src/openscad.cc:603 +msgid "input file" +msgstr "" + #: src/openscad.cc:637 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" @@ -1521,6 +1856,18 @@ msgstr "" msgid "WARNING: Body of render() isn't valid 2-manifold!" msgstr "" +#: src/PolySetCGALEvaluator.cc:466 +#, c-format +msgid "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" +msgstr "" + +#: src/primitives.cc:130 +#, c-format +msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." +msgstr "" + #: src/primitives.cc:183 #, c-format msgid "WARNING: $fs too small - clamping to %f" @@ -1531,6 +1878,12 @@ msgstr "" msgid "WARNING: $fa too small - clamping to %f" msgstr "" +#: src/primitives.cc:244 +msgid "" +"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " +"polyhedron(faces=[]) instead." +msgstr "" + #: src/primitives.cc:536 #, c-format msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" @@ -1551,3 +1904,9 @@ msgstr "" #, c-format msgid "WARNING: Illegal value in '%s': %s" msgstr "" + +#: src/value.cc:640 +msgid "" +"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " +"than the end value is deprecated." +msgstr "" diff --git a/po/ru.po b/po/ru.po index 7a19222f..8701f829 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 04:13+0100\n" +"POT-Creation-Date: 2014-01-06 05:16+0100\n" "PO-Revision-Date: 2013-02-24 17:50+0100\n" "Last-Translator: \n" "Language-Team: Russian\n" @@ -657,6 +657,31 @@ msgstr "" msgid "WARNING: minkowski() could not get any points from object 2!" msgstr "" +#: src/CGALCache.cc:15 +#, c-format +msgid "CGAL Cache hit: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:24 +#, c-format +msgid "CGAL Cache insert: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:25 +#, c-format +msgid "CGAL Cache insert failed: %s (%d bytes)" +msgstr "" + +#: src/CGALCache.cc:47 +#, c-format +msgid "CGAL Polyhedrons in cache: %d" +msgstr "" + +#: src/CGALCache.cc:48 +#, c-format +msgid "CGAL cache size in bytes: %d" +msgstr "" + #: src/CGALEvaluator.cc:89 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" @@ -672,6 +697,19 @@ msgid "" "http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" +#: src/CGALEvaluator.cc:172 +#, c-format +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +msgstr "" + +#: src/CGALEvaluator.cc:207 +msgid "WARNING: Cannot resize to sizes less than 0." +msgstr "" + +#: src/CGALEvaluator.cc:234 +msgid "WARNING: Resize in direction normal to flat object is not implemented" +msgstr "" + #: src/CGALEvaluator.cc:336 msgid "" "Warning: Transformation matrix contains Not-a-Number and/or Infinity - " @@ -690,6 +728,15 @@ msgstr "" msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" msgstr "" +#: src/CGALEvaluator.cc:693 +msgid "PolySet has nonplanar faces. Attempting alternate construction" +msgstr "" + +#: src/CGALEvaluator.cc:697 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "" + #: src/CGALEvaluator.cc:708 #, c-format msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" @@ -699,6 +746,19 @@ msgstr "" msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." msgstr "" +#: src/CGAL_Nef_polyhedron.cc:114 +#, c-format +msgid "ERROR: %s" +msgstr "" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:107 +msgid "Warning: Scaling a 2D object with 0 - removing object" +msgstr "" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:137 +msgid "Warning: Scaling a 3D object with 0 - removing object" +msgstr "" + #: src/cgalutils.cc:138 #, c-format msgid "CGAL error in CGAL_Build_PolySet: %s" @@ -744,6 +804,66 @@ msgstr "" msgid "WARNING: Ignoring unknown module '%s'." msgstr "" +#: src/context.cc:156 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p)" +msgstr "" + +#: src/context.cc:158 +#, c-format +msgid "Context: %p (%p)" +msgstr "" + +#: src/context.cc:159 +#, c-format +msgid " document path: %s" +msgstr "" + +#: src/context.cc:163 +msgid " module args:" +msgstr "" + +#: src/context.cc:170 +msgid " vars:" +msgstr "" + +#: src/control.cc:83 +#, c-format +msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." +msgstr "" + +#: src/control.cc:133 src/control.cc:138 src/control.cc:247 +#, c-format +msgid "" +"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " +"vector, range." +msgstr "" + +#: src/control.cc:144 +#, c-format +msgid "WARNING: Negative children index (%d) not allowed" +msgstr "" + +#: src/control.cc:150 +#, c-format +msgid "WARNING: Children index (%d) out of bounds (%d children)" +msgstr "" + +#: src/control.cc:170 +#, c-format +msgid "WARNING: Negative child index (%d) not allowed" +msgstr "" + +#: src/control.cc:189 +#, c-format +msgid "WARNING: Child index (%d) out of bounds (%d children)" +msgstr "" + +#: src/control.cc:234 +#, c-format +msgid "WARNING: Bad range parameter for children: too many elements (%lu)." +msgstr "" + #: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 #, c-format msgid "" @@ -807,16 +927,37 @@ msgstr "" msgid "CGAL error in dxf_tesselate(): %s" msgstr "" +#: src/dxftess-cgal.cc:475 +#, c-format +msgid "CGAL error in dxftess triangulate_polygon: %s" +msgstr "" + +#: src/dxftess-cgal.cc:491 +msgid "WARNING: PolySet has polygon with <3 points" +msgstr "" + +#: src/dxftess-cgal.cc:496 +msgid "WARNING: PolySet has degenerate polygon" +msgstr "" + #: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 #, c-format msgid "GLU tesselation error %s" msgstr "" +#: src/export.cc:48 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" +msgstr "" + #: src/export.cc:120 src/export.cc:137 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" msgstr "" +#: src/export.cc:123 +msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" +msgstr "" + #: src/func.cc:503 src/func.cc:536 #, c-format msgid " WARNING: search term not found: \"%s\"" @@ -832,6 +973,18 @@ msgstr "" msgid " WARNING: search: none performed on input %s" msgstr "" +#: src/func.cc:591 +#, c-format +msgid "WARNING: Negative parent module index (%d) not allowed" +msgstr "" + +#: src/func.cc:595 +#, c-format +msgid "" +"WARNING: Parent module index (%d) greater than the number of modules on the " +"stack" +msgstr "" + #: src/glview.cc:149 #, c-format msgid "GLEW Error: %s\n" @@ -898,12 +1051,27 @@ msgid "" "OpenGL version %s\n" msgstr "" +#: src/glview.cc:537 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" msgstr "" -#: src/import.cc:195 +#: src/import.cc:98 +msgid "DEPRECATED: filename= is deprecated. Please use file=" +msgstr "" + +#: src/import.cc:122 +msgid "DEPRECATED: layername= is deprecated. Please use layer=" +msgstr "" + +#: src/import.cc:195 src/import.cc:281 #, c-format msgid "WARNING: Can't open import file '%s'." msgstr "" @@ -947,6 +1115,10 @@ msgstr "" msgid "OpenSCAD - New Document[*]" msgstr "" +#: src/mainwin.cc:529 +msgid "OpenSCAD - " +msgstr "" + #: src/mainwin.cc:529 msgid "[*]" msgstr "" @@ -961,6 +1133,11 @@ msgstr "" msgid "Loaded design '%s'." msgstr "" +#: src/mainwin.cc:657 +#, c-format +msgid "Module cache size: %d modules" +msgstr "" + #: src/mainwin.cc:741 msgid "Compiling design (CSG Tree generation)..." msgstr "" @@ -1039,6 +1216,12 @@ msgstr "" msgid "Failed to open file for writing: %s (%s)" msgstr "" +#: src/mainwin.cc:1003 +msgid "" +"Failed to open file for writing:\n" +" %1 (%2)" +msgstr "" + #: src/mainwin.cc:1010 #, c-format msgid "Saved design '%s'." @@ -1062,6 +1245,16 @@ msgid "" "Do you want to replace it?" msgstr "" +#: src/mainwin.cc:1047 +#, c-format +msgid "WARNING: Library path %s doesn't exist. Creating" +msgstr "" + +#: src/mainwin.cc:1049 +#, c-format +msgid "ERROR: Cannot create library path: %s" +msgstr "" + #: src/mainwin.cc:1184 src/mainwin.cc:1857 msgid "Application" msgstr "" @@ -1255,6 +1448,9 @@ msgid "No filename specified. %s export aborted." msgstr "" #: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 +#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 +#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 +#: src/openscad.cc:418 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" @@ -1324,6 +1520,14 @@ msgstr "" msgid "No filename specified. Image export aborted." msgstr "" +#: src/mainwin.cc:1827 +msgid "http://openscad.org/" +msgstr "" + +#: src/mainwin.cc:1833 +msgid "http://www.openscad.org/documentation.html" +msgstr "" + #: src/mainwin.cc:1842 msgid "OpenGL Info" msgstr "" @@ -1358,6 +1562,11 @@ msgstr "" msgid " compiled module: %p" msgstr "" +#: src/module.cc:180 +#, c-format +msgid "ERROR: Recursion detected calling module '%s'" +msgstr "" + #: src/module.cc:298 #, c-format msgid "WARNING: Failed to compile library '%s'." @@ -1381,14 +1590,140 @@ msgstr "" msgid "OpenSCAD version %s\n" msgstr "" +#: src/openscad.cc:138 +#, c-format +msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" +msgstr "" + +#: src/openscad.cc:160 +msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" +msgstr "" + +#: src/openscad.cc:161 +msgid "or 6 numbers for Vector Camera\n" +msgstr "" + +#: src/openscad.cc:177 +msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" +msgstr "" + +#: src/openscad.cc:188 +msgid "Need 2 numbers for imgsize\n" +msgstr "" + +#: src/openscad.cc:236 +#, c-format +msgid "Unknown suffix for output file %s\n" +msgstr "" + +#: src/openscad.cc:260 +#, c-format +msgid "Can't open input file '%s'!\n" +msgstr "" + +#: src/openscad.cc:269 +#, c-format +msgid "Can't parse file '%s'!\n" +msgstr "" + +#: src/openscad.cc:351 +#, c-format +msgid "Output file:%s\n" +msgstr "" + +#: src/openscad.cc:352 +msgid "Sorry, don't know how to write deps for that file type. Exiting\n" +msgstr "" + +#: src/openscad.cc:357 +msgid "error writing deps" +msgstr "" + +#: src/openscad.cc:364 src/openscad.cc:383 +msgid "Current top level object is not a 3D object.\n" +msgstr "" + +#: src/openscad.cc:368 src/openscad.cc:387 +msgid "Object isn't a valid 2-manifold! Modify your design.\n" +msgstr "" + +#: src/openscad.cc:402 +msgid "Current top level object is not a 2D object.\n" +msgstr "" + #: src/openscad.cc:583 msgid "Allowed options" msgstr "" +#: src/openscad.cc:585 +msgid "help message" +msgstr "" + +#: src/openscad.cc:586 +msgid "print the version" +msgstr "" + +#: src/openscad.cc:587 +msgid "print information about the building process" +msgstr "" + +#: src/openscad.cc:588 +msgid "if exporting a png image, do a full CGAL render" +msgstr "" + +#: src/openscad.cc:589 +msgid "" +"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" +msgstr "" + +#: src/openscad.cc:590 +msgid "parameters for camera when exporting png" +msgstr "" + +#: src/openscad.cc:591 +msgid "=width,height for exporting png" +msgstr "" + +#: src/openscad.cc:592 +msgid "(o)rtho or (p)erspective when exporting png" +msgstr "" + +#: src/openscad.cc:593 +msgid "out-file" +msgstr "" + +#: src/openscad.cc:594 +msgid "stl-file" +msgstr "" + +#: src/openscad.cc:595 +msgid "dxf-file" +msgstr "" + +#: src/openscad.cc:596 +msgid "deps-file" +msgstr "" + +#: src/openscad.cc:597 +msgid "makefile" +msgstr "" + +#: src/openscad.cc:598 +msgid "var=val" +msgstr "" + +#: src/openscad.cc:599 +msgid "enable experimental features" +msgstr "" + #: src/openscad.cc:601 msgid "Hidden options" msgstr "" +#: src/openscad.cc:603 +msgid "input file" +msgstr "" + #: src/openscad.cc:637 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" @@ -1522,6 +1857,18 @@ msgstr "" msgid "WARNING: Body of render() isn't valid 2-manifold!" msgstr "" +#: src/PolySetCGALEvaluator.cc:466 +#, c-format +msgid "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" +msgstr "" + +#: src/primitives.cc:130 +#, c-format +msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." +msgstr "" + #: src/primitives.cc:183 #, c-format msgid "WARNING: $fs too small - clamping to %f" @@ -1532,6 +1879,12 @@ msgstr "" msgid "WARNING: $fa too small - clamping to %f" msgstr "" +#: src/primitives.cc:244 +msgid "" +"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " +"polyhedron(faces=[]) instead." +msgstr "" + #: src/primitives.cc:536 #, c-format msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" @@ -1552,3 +1905,9 @@ msgstr "" #, c-format msgid "WARNING: Illegal value in '%s': %s" msgstr "" + +#: src/value.cc:640 +msgid "" +"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " +"than the end value is deprecated." +msgstr "" diff --git a/src/AboutDialog.h b/src/AboutDialog.h index a0c1d3f6..76055b23 100644 --- a/src/AboutDialog.h +++ b/src/AboutDialog.h @@ -12,7 +12,7 @@ class AboutDialog : public QDialog, public Ui::AboutDialog public: AboutDialog(QWidget *) { setupUi(this); - this->setWindowTitle( QString("About OpenSCAD ") + QString(TOSTRING( OPENSCAD_VERSION)) ); + this->setWindowTitle( QString(_("About OpenSCAD ")) + QString(TOSTRING( OPENSCAD_VERSION)) ); this->aboutText->setOpenExternalLinks(true); QUrl flattr_qurl(":icons/flattr.png" ); this->aboutText->loadResource( QTextDocument::ImageResource, flattr_qurl ); diff --git a/src/QGLView.cc b/src/QGLView.cc index ab830fa4..e26673b1 100644 --- a/src/QGLView.cc +++ b/src/QGLView.cc @@ -110,7 +110,7 @@ std::string QGLView::getRendererInfo() const { std::string glewinfo = glew_dump(); std::string glextlist = glew_extensions_dump(); - return glewinfo + std::string("\nUsing QGLWidget\n\n") + glextlist; + return glewinfo + std::string(_("\nUsing QGLWidget\n\n")) + glextlist; } #ifdef ENABLE_OPENCSG @@ -127,19 +127,19 @@ void QGLView::display_opencsg_warning_dialog() QString message; if (this->is_opencsg_capable) { - message += "Warning: You may experience OpenCSG rendering errors.\n\n"; + message += _("Warning: You may experience OpenCSG rendering errors.\n\n"); } else { - message += "Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n\n"; + message += _("Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n\n"); dialog->enableOpenCSGBox->hide(); } - message += "It is highly recommended to use OpenSCAD on a system with " + message += _("It is highly recommended to use OpenSCAD on a system with " "OpenGL 2.0 or later.\n" - "Your renderer information is as follows:\n"; + "Your renderer information is as follows:\n"); QString rendererinfo; - rendererinfo.sprintf("GLEW version %s\n" + rendererinfo.sprintf(_("GLEW version %s\n" "%s (%s)\n" - "OpenGL version %s\n", + "OpenGL version %s\n"), glewGetString(GLEW_VERSION), glGetString(GL_RENDERER), glGetString(GL_VENDOR), glGetString(GL_VERSION)); @@ -167,7 +167,7 @@ void QGLView::paintGL() Camera nc(cam); nc.gimbalDefaultTranslate(); - msg.sprintf("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f", + msg.sprintf(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f"), nc.object_trans.x(), nc.object_trans.y(), nc.object_trans.z(), nc.object_rot.x(), nc.object_rot.y(), nc.object_rot.z(), nc.viewer_distance ); From 753f7160f940b1da25cc8a515daba82e5fad88a0 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 6 Jan 2014 05:25:46 +0100 Subject: [PATCH 005/263] Add German translation. --- po/LINGUAS | 2 +- po/de.po | 2045 +++++++++++++++++++++++++++++++++++++++++++++++ po/openscad.pot | 2 +- 3 files changed, 2047 insertions(+), 2 deletions(-) create mode 100644 po/de.po diff --git a/po/LINGUAS b/po/LINGUAS index b91c4cec..f7f046e1 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1,2 +1,2 @@ # available languages -fr ru +fr ru de diff --git a/po/de.po b/po/de.po new file mode 100644 index 00000000..2c38f534 --- /dev/null +++ b/po/de.po @@ -0,0 +1,2045 @@ +# German translations for OpenSCAD package. +# opyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER +# This file is distributed under the same license as the OpenSCAD package. +# Torsten Paul , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2014.01.05\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-01-06 04:16+0100\n" +"PO-Revision-Date: 2014-01-06 05:25+0100\n" +"Last-Translator: Torsten Paul \n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "About OpenSCAD" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "OpenGL Warning" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" +"\n" +"\n" +"

" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "Enable OpenCSG" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "Show this message again" + +#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 +msgid "Close" +msgstr "Schließen" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "Form" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "%v / %m" + +#: objects/ui_MainWindow.h:470 +msgid "MainWindow" +msgstr "MainWindow" + +#: objects/ui_MainWindow.h:471 +msgid "&New" +msgstr "&Neu" + +#: objects/ui_MainWindow.h:472 +msgid "Ctrl+N" +msgstr "Ctrl+N" + +#: objects/ui_MainWindow.h:473 +msgid "&Open..." +msgstr "Ö&ffnen" + +#: objects/ui_MainWindow.h:474 +msgid "Ctrl+O" +msgstr "Ctrl+O" + +#: objects/ui_MainWindow.h:475 +msgid "&Save" +msgstr "&Speichern" + +#: objects/ui_MainWindow.h:476 +msgid "Ctrl+S" +msgstr "Ctrl+S" + +#: objects/ui_MainWindow.h:477 +msgid "Save &As..." +msgstr "Speichern &Unter..." + +#: objects/ui_MainWindow.h:478 +msgid "Ctrl+Shift+S" +msgstr "Ctrl+Shift+S" + +#: objects/ui_MainWindow.h:479 +msgid "&Reload" +msgstr "Neu &laden" + +#: objects/ui_MainWindow.h:480 +msgid "Ctrl+R" +msgstr "Ctrl+R" + +#: objects/ui_MainWindow.h:481 +msgid "&Quit" +msgstr "&Beenden" + +#: objects/ui_MainWindow.h:482 +msgid "Ctrl+Q" +msgstr "Ctrl+Q" + +#: objects/ui_MainWindow.h:483 +msgid "&Undo" +msgstr "&Rückgängig" + +#: objects/ui_MainWindow.h:484 +msgid "Ctrl+Z" +msgstr "Ctrl+Z" + +#: objects/ui_MainWindow.h:485 +msgid "&Redo" +msgstr "&Wiederholen" + +#: objects/ui_MainWindow.h:486 +msgid "Ctrl+Shift+Z" +msgstr "Ctrl+Shift+Z" + +#: objects/ui_MainWindow.h:487 +msgid "Cu&t" +msgstr "Ausschneiden" + +#: objects/ui_MainWindow.h:488 +msgid "Ctrl+X" +msgstr "Ctrl+X" + +#: objects/ui_MainWindow.h:489 +msgid "&Copy" +msgstr "Kopieren" + +#: objects/ui_MainWindow.h:490 +msgid "Ctrl+C" +msgstr "Ctrl+C" + +#: objects/ui_MainWindow.h:491 +msgid "&Paste" +msgstr "Einfügen" + +#: objects/ui_MainWindow.h:492 +msgid "Ctrl+V" +msgstr "Ctrl+V" + +#: objects/ui_MainWindow.h:493 +msgid "&Indent" +msgstr "Einzug erhöhen" + +#: objects/ui_MainWindow.h:494 +msgid "Ctrl+I" +msgstr "Ctrl+I" + +#: objects/ui_MainWindow.h:495 +msgid "U&nindent" +msgstr "Einzug vermindern" + +#: objects/ui_MainWindow.h:496 +msgid "Ctrl+Shift+I" +msgstr "Ctrl+Shift+I" + +#: objects/ui_MainWindow.h:497 +msgid "C&omment" +msgstr "K&ommentieren" + +#: objects/ui_MainWindow.h:498 +msgid "Ctrl+D" +msgstr "Ctrl+D" + +#: objects/ui_MainWindow.h:499 +msgid "Unco&mment" +msgstr "Kommentar entfernen" + +#: objects/ui_MainWindow.h:500 +msgid "Ctrl+Shift+D" +msgstr "Ctrl+Shift+D" + +#: objects/ui_MainWindow.h:501 +msgid "Paste viewport translation" +msgstr "Aktuelle Verschiebung einfügen" + +#: objects/ui_MainWindow.h:502 +msgid "Ctrl+T" +msgstr "Ctrl+T" + +#: objects/ui_MainWindow.h:503 +msgid "Paste viewport rotation" +msgstr "Aktuelle Rotation einfügen" + +#: objects/ui_MainWindow.h:504 +msgid "Zoom In" +msgstr "Vergrößern" + +#: objects/ui_MainWindow.h:505 +msgid "Ctrl++" +msgstr "Ctrl++" + +#: objects/ui_MainWindow.h:506 +msgid "Zoom Out" +msgstr "Verkleinern" + +#: objects/ui_MainWindow.h:507 +msgid "Ctrl+-" +msgstr "Ctrl+-" + +#: objects/ui_MainWindow.h:508 +msgid "Hide editor" +msgstr "Editor verstecken" + +#: objects/ui_MainWindow.h:509 +msgid "&Reload and Compile" +msgstr "Neu laden und übersetzen" + +#: objects/ui_MainWindow.h:510 +msgid "F4" +msgstr "F4" + +#: objects/ui_MainWindow.h:511 +msgid "&Compile" +msgstr "Übersetzen" + +#: objects/ui_MainWindow.h:512 +msgid "F5" +msgstr "F5" + +#: objects/ui_MainWindow.h:513 +msgid "Compile and &Render (CGAL)" +msgstr "Übersetzen und Rendern (CGAL)" + +#: objects/ui_MainWindow.h:514 +msgid "F6" +msgstr "F6" + +#: objects/ui_MainWindow.h:515 +msgid "Display &AST..." +msgstr "&AST Baum anzeigen..." + +#: objects/ui_MainWindow.h:516 +msgid "Display CSG &Tree..." +msgstr "CSG Baum anzeigen..." + +#: objects/ui_MainWindow.h:517 +msgid "Display CSG &Products..." +msgstr "CSG Gleichungen anzeigen..." + +#: objects/ui_MainWindow.h:518 +msgid "Export as &STL..." +msgstr "&STL exportieren..." + +#: objects/ui_MainWindow.h:519 +msgid "Export as &OFF..." +msgstr "&OFF exportieren..." + +#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 +msgid "OpenCSG" +msgstr "OpenCSG" + +#: objects/ui_MainWindow.h:521 +msgid "F9" +msgstr "F9" + +#: objects/ui_MainWindow.h:522 +msgid "CGAL Surfaces" +msgstr "CGAL Flächen anzeigen" + +#: objects/ui_MainWindow.h:523 +msgid "F10" +msgstr "F10" + +#: objects/ui_MainWindow.h:524 +msgid "CGAL Grid Only" +msgstr "CGAL Gitter anzeigen" + +#: objects/ui_MainWindow.h:525 +msgid "F11" +msgstr "F11" + +#: objects/ui_MainWindow.h:526 +msgid "Thrown Together" +msgstr "Kombinierte Anzeige" + +#: objects/ui_MainWindow.h:527 +msgid "F12" +msgstr "F12" + +#: objects/ui_MainWindow.h:528 +msgid "Show Edges" +msgstr "Kanten anzeigen" + +#: objects/ui_MainWindow.h:529 +msgid "Ctrl+1" +msgstr "Ctrl+1" + +#: objects/ui_MainWindow.h:530 +msgid "Show Axes" +msgstr "Koordinatenachsen anzeigen" + +#: objects/ui_MainWindow.h:531 +msgid "Ctrl+2" +msgstr "Ctrl+2" + +#: objects/ui_MainWindow.h:532 +msgid "Show Crosshairs" +msgstr "Diagonalen anzeigen" + +#: objects/ui_MainWindow.h:533 +msgid "Ctrl+3" +msgstr "Ctrl+3" + +#: objects/ui_MainWindow.h:534 +msgid "Animate" +msgstr "Animation" + +#: objects/ui_MainWindow.h:535 +msgid "Top" +msgstr "Oben" + +#: objects/ui_MainWindow.h:536 +msgid "Ctrl+4" +msgstr "Ctrl+4" + +#: objects/ui_MainWindow.h:537 +msgid "Bottom" +msgstr "Unten" + +#: objects/ui_MainWindow.h:538 +msgid "Ctrl+5" +msgstr "Ctrl+5" + +#: objects/ui_MainWindow.h:539 +msgid "Left" +msgstr "Links" + +#: objects/ui_MainWindow.h:540 +msgid "Ctrl+6" +msgstr "Ctrl+6" + +#: objects/ui_MainWindow.h:541 +msgid "Right" +msgstr "Rechts" + +#: objects/ui_MainWindow.h:542 +msgid "Ctrl+7" +msgstr "Ctrl+7" + +#: objects/ui_MainWindow.h:543 +msgid "Front" +msgstr "Vorn" + +#: objects/ui_MainWindow.h:544 +msgid "Ctrl+8" +msgstr "Ctrl+8" + +#: objects/ui_MainWindow.h:545 +msgid "Back" +msgstr "Hinten" + +#: objects/ui_MainWindow.h:546 +msgid "Ctrl+9" +msgstr "Ctrl+9" + +#: objects/ui_MainWindow.h:547 +msgid "Diagonal" +msgstr "Diagonal" + +#: objects/ui_MainWindow.h:548 +msgid "Ctrl+0" +msgstr "Ctrl+0" + +#: objects/ui_MainWindow.h:549 +msgid "Center" +msgstr "Zentriert" + +#: objects/ui_MainWindow.h:550 +msgid "Ctrl+P" +msgstr "Ctrl+P" + +#: objects/ui_MainWindow.h:551 +msgid "Perspective" +msgstr "Perspektivisch" + +#: objects/ui_MainWindow.h:552 +msgid "Orthogonal" +msgstr "Orthogonal" + +#: objects/ui_MainWindow.h:553 +msgid "Hide console" +msgstr "Konsole verstecken" + +#: objects/ui_MainWindow.h:554 +msgid "About" +msgstr "Über OpenSCAD" + +#: objects/ui_MainWindow.h:555 +msgid "Documentation" +msgstr "Dokumentation" + +#: objects/ui_MainWindow.h:556 +msgid "Clear Recent" +msgstr "Clear Recent" + +#: objects/ui_MainWindow.h:557 +msgid "Export as DXF..." +msgstr "DXF exportieren..." + +#: objects/ui_MainWindow.h:559 +msgid "Ctrl+W" +msgstr "Ctrl+W" + +#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +msgid "Preferences" +msgstr "Einstellungen" + +#: objects/ui_MainWindow.h:561 +msgid "Flush Caches" +msgstr "Cache leeren" + +#: objects/ui_MainWindow.h:562 +msgid "OpenSCAD Homepage" +msgstr "OpenSCAD Homepage" + +#: objects/ui_MainWindow.h:563 +msgid "Automatic Reload and Compile" +msgstr "Automatisch neu Laden und Übersetzen" + +#: objects/ui_MainWindow.h:564 +msgid "Export as Image..." +msgstr "Image exportieren..." + +#: objects/ui_MainWindow.h:565 +msgid "Export as CSG..." +msgstr "CSG exportieren..." + +#: objects/ui_MainWindow.h:566 +msgid "Library info" +msgstr "System Informationen" + +#: objects/ui_MainWindow.h:567 +msgid "Check for Update.." +msgstr "Neue Version suchen..." + +#: objects/ui_MainWindow.h:568 +msgid "Show Library Folder..." +msgstr "Bibliotheken anzeigen..." + +#: objects/ui_MainWindow.h:569 +msgid "Reset View" +msgstr "Ansicht zurücksetzen" + +#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 +msgid "Editor" +msgstr "Editor" + +#: objects/ui_MainWindow.h:574 +msgid "Editor for SCAD code" +msgstr "Editor for SCAD code" + +#: objects/ui_MainWindow.h:577 +msgid "Console" +msgstr "Console" + +#: objects/ui_MainWindow.h:580 +msgid "Console messages" +msgstr "Console messages" + +#: objects/ui_MainWindow.h:582 +msgid "Time:" +msgstr "Zeit:" + +#: objects/ui_MainWindow.h:583 +msgid "FPS:" +msgstr "FPS:" + +#: objects/ui_MainWindow.h:584 +msgid "Steps:" +msgstr "Schritte:" + +#: objects/ui_MainWindow.h:585 +msgid "Dump Pictures" +msgstr "Bilder ausgeben" + +#: objects/ui_MainWindow.h:586 +msgid "&File" +msgstr "&Datei" + +#: objects/ui_MainWindow.h:587 +msgid "Open Recent" +msgstr "Zuletzt benutze Dateien" + +#: objects/ui_MainWindow.h:588 +msgid "Examples" +msgstr "Beispiele" + +#: objects/ui_MainWindow.h:589 +msgid "&Edit" +msgstr "&Bearbeiten" + +#: objects/ui_MainWindow.h:590 +msgid "&Design" +msgstr "&Design" + +#: objects/ui_MainWindow.h:591 +msgid "&View" +msgstr "&Ansicht" + +#: objects/ui_MainWindow.h:592 +msgid "&Help" +msgstr "&Hilfe" + +#: objects/ui_Preferences.h:515 +msgid "3D View" +msgstr "3D Ansicht" + +#: objects/ui_Preferences.h:516 +msgid "Advanced" +msgstr "Erweitert" + +#: objects/ui_Preferences.h:518 +msgid "Update" +msgstr "Aktualisieren" + +#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +msgid "Features" +msgstr "Funktionen" + +#: objects/ui_Preferences.h:521 +msgid "Enable/Disable experimental features" +msgstr "Enable/Disable experimental features" + +#: objects/ui_Preferences.h:523 +msgid "Color scheme:" +msgstr "Farbschema:" + +#: objects/ui_Preferences.h:528 +msgid "Cornfield" +msgstr "Cornfield" + +#: objects/ui_Preferences.h:530 +msgid "Metallic" +msgstr "Metallic" + +#: objects/ui_Preferences.h:532 +msgid "Sunset" +msgstr "Sunset" + +#: objects/ui_Preferences.h:535 +msgid "Font" +msgstr "Font" + +#: objects/ui_Preferences.h:536 +msgid "Color syntax highlighting" +msgstr "Color syntax highlighting" + +#: objects/ui_Preferences.h:539 +msgid "For Light Background" +msgstr "Für hellen Hintergrund" + +#: objects/ui_Preferences.h:540 +msgid "For Dark Background" +msgstr "Für dunklen Hintergrund" + +#: objects/ui_Preferences.h:541 +msgid "Off" +msgstr "Aus" + +#: objects/ui_Preferences.h:543 +msgid "Automatically check for updates" +msgstr "Automatisch nach Aktualisierungen suchen" + +#: objects/ui_Preferences.h:544 +msgid "Include development snapshots" +msgstr "Entwickler-Versionen einschließen" + +#: objects/ui_Preferences.h:545 +msgid "Check Now" +msgstr "Jetzt suchen" + +#: objects/ui_Preferences.h:546 +msgid "Last checked: " +msgstr "Zuletzt gesucht: " + +#: objects/ui_Preferences.h:549 +msgid "Show capability warning" +msgstr "Kompatibilitätswarnung anzeigen" + +#: objects/ui_Preferences.h:550 +msgid "Enable for OpenGL 1.x" +msgstr "Aktivieren bei OpenGL 1.x" + +#: objects/ui_Preferences.h:551 +msgid "Turn off rendering at " +msgstr "Rendern abbrechen ab " + +#: objects/ui_Preferences.h:552 +msgid "elements" +msgstr "Elementen" + +#: objects/ui_Preferences.h:553 +msgid "Force Goldfeather" +msgstr "Goldfeather Algorithmus erzwingen" + +#: objects/ui_Preferences.h:554 +msgid "CGAL Cache size" +msgstr "CGAL Cache Größe" + +#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 +msgid "bytes" +msgstr "Byte" + +#: objects/ui_Preferences.h:556 +msgid "PolySet Cache size" +msgstr "PolySet Cache Größe" + +#: objects/ui_Preferences.h:558 +msgid "toolBar" +msgstr "toolBar" + +#: src/cgaladv_minkowski2.cc:43 +msgid " vertices:" +msgstr " vertices:" + +#: src/cgaladv_minkowski2.cc:55 +msgid "{ Outer boundary = " +msgstr "{ Outer boundary = " + +#: src/cgaladv_minkowski2.cc:58 +msgid "{ Unbounded polygon." +msgstr "{ Unbounded polygon." + +#: src/cgaladv_minkowski2.cc:63 +msgid " holes:" +msgstr " holes:" + +#: src/cgaladv_minkowski2.cc:65 +msgid " Hole #" +msgstr " Hole #" + +#: src/cgaladv_minkowski2.cc:90 +msgid "" +"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" +msgstr "" +"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" + +#: src/cgaladv_minkowski2.cc:123 +msgid "WARNING: minkowski() could not get any points from object 1!" +msgstr "WARNING: minkowski() could not get any points from object 1!" + +#: src/cgaladv_minkowski2.cc:126 +msgid "WARNING: minkowski() could not get any points from object 2!" +msgstr "WARNING: minkowski() could not get any points from object 2!" + +#: src/CGALCache.cc:15 +#, c-format +msgid "CGAL Cache hit: %s (%d bytes)" +msgstr "CGAL Cache hit: %s (%d bytes)" + +#: src/CGALCache.cc:24 +#, c-format +msgid "CGAL Cache insert: %s (%d bytes)" +msgstr "CGAL Cache insert: %s (%d bytes)" + +#: src/CGALCache.cc:25 +#, c-format +msgid "CGAL Cache insert failed: %s (%d bytes)" +msgstr "CGAL Cache insert failed: %s (%d bytes)" + +#: src/CGALCache.cc:47 +#, c-format +msgid "CGAL Polyhedrons in cache: %d" +msgstr "CGAL Polyhedrons im Cache: %d" + +#: src/CGALCache.cc:48 +#, c-format +msgid "CGAL cache size in bytes: %d" +msgstr "CGAL Cache Größe in Bytes: %d" + +#: src/CGALEvaluator.cc:89 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +msgstr "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" + +#: src/CGALEvaluator.cc:141 +msgid "WARNING: hull() does not support mixing 2D and 3D objects." +msgstr "WARNING: hull() does not support mixing 2D and 3D objects." + +#: src/CGALEvaluator.cc:159 +msgid "" +"Hull() currently requires a valid 2-manifold. Please modify your design. See " +"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" +"Hull() currently requires a valid 2-manifold. Please modify your design. See " +"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" + +#: src/CGALEvaluator.cc:172 +#, c-format +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" + +#: src/CGALEvaluator.cc:207 +msgid "WARNING: Cannot resize to sizes less than 0." +msgstr "WARNING: Cannot resize to sizes less than 0." + +#: src/CGALEvaluator.cc:234 +msgid "WARNING: Resize in direction normal to flat object is not implemented" +msgstr "WARNING: Resize in direction normal to flat object is not implemented" + +#: src/CGALEvaluator.cc:336 +msgid "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." +msgstr "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." + +#: src/CGALEvaluator.cc:384 +msgid "WARNING: glide() is not implemented yet!" +msgstr "WARNING: glide() is not implemented yet!" + +#: src/CGALEvaluator.cc:388 +msgid "WARNING: subdiv() is not implemented yet!" +msgstr "WARNING: subdiv() is not implemented yet!" + +#: src/CGALEvaluator.cc:422 +msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" +msgstr "WARNING: CGAL Evaluator: Root node didn't fit into cache" + +#: src/CGALEvaluator.cc:693 +msgid "PolySet has nonplanar faces. Attempting alternate construction" +msgstr "PolySet has nonplanar faces. Attempting alternate construction" + +#: src/CGALEvaluator.cc:697 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "CGAL error in CGAL_Nef_polyhedron3(): %s" + +#: src/CGALEvaluator.cc:708 +#, c-format +msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" +msgstr "" +"Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" + +#: src/CGAL_Nef_polyhedron.cc:113 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." + +#: src/CGAL_Nef_polyhedron.cc:114 +#, c-format +msgid "ERROR: %s" +msgstr "ERROR: %s" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:107 +msgid "Warning: Scaling a 2D object with 0 - removing object" +msgstr "Warning: Scaling a 2D object with 0 - removing object" + +#: src/CGAL_Nef_polyhedron_DxfData.cc:137 +msgid "Warning: Scaling a 3D object with 0 - removing object" +msgstr "Warning: Scaling a 3D object with 0 - removing object" + +#: src/cgalutils.cc:138 +#, c-format +msgid "CGAL error in CGAL_Build_PolySet: %s" +msgstr "CGAL error in CGAL_Build_PolySet: %s" + +#: src/cgalworker.cc:36 +msgid "Rendering cancelled." +msgstr "Rendering cancelled." + +#: src/color.cc:69 +#, c-format +msgid "" +"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " +"large." +msgstr "" +"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " +"large." + +#: src/color.cc:81 +#, c-format +msgid "WARNING: Color name \"%s\" unknown. Please see" +msgstr "WARNING: Color name \"%s\" unknown. Please see" + +#: src/color.cc:82 +msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" +msgstr "WARNING: http://en.wikipedia.org/wiki/Web_colors" + +#: src/context.cc:97 +#, c-format +msgid "WARNING: Attempt to modify constant '%s'." +msgstr "WARNING: Attempt to modify constant '%s'." + +#: src/context.cc:121 +#, c-format +msgid "WARNING: Ignoring unknown variable '%s'." +msgstr "WARNING: Ignoring unknown variable '%s'." + +#: src/context.cc:128 +#, c-format +msgid "WARNING: Ignoring unknown function '%s'." +msgstr "WARNING: Ignoring unknown function '%s'." + +#: src/context.cc:135 +#, c-format +msgid "WARNING: Ignoring unknown module '%s'." +msgstr "WARNING: Ignoring unknown module '%s'." + +#: src/context.cc:156 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p)" +msgstr "ModuleContext %p (%p) for %s inst (%p)" + +#: src/context.cc:158 +#, c-format +msgid "Context: %p (%p)" +msgstr "Context: %p (%p)" + +#: src/context.cc:159 +#, c-format +msgid " document path: %s" +msgstr " document path: %s" + +#: src/context.cc:163 +msgid " module args:" +msgstr " module args:" + +#: src/context.cc:170 +msgid " vars:" +msgstr " vars:" + +#: src/control.cc:83 +#, c-format +msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." +msgstr "" +"WARNING: Bad range parameter in for statement: too many elements (%lu)." + +#: src/control.cc:133 src/control.cc:138 src/control.cc:247 +#, c-format +msgid "" +"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " +"vector, range." +msgstr "" +"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " +"vector, range." + +#: src/control.cc:144 +#, c-format +msgid "WARNING: Negative children index (%d) not allowed" +msgstr "WARNING: Negative children index (%d) not allowed" + +#: src/control.cc:150 +#, c-format +msgid "WARNING: Children index (%d) out of bounds (%d children)" +msgstr "WARNING: Children index (%d) out of bounds (%d children)" + +#: src/control.cc:170 +#, c-format +msgid "WARNING: Negative child index (%d) not allowed" +msgstr "WARNING: Negative child index (%d) not allowed" + +#: src/control.cc:189 +#, c-format +msgid "WARNING: Child index (%d) out of bounds (%d children)" +msgstr "WARNING: Child index (%d) out of bounds (%d children)" + +#: src/control.cc:234 +#, c-format +msgid "WARNING: Bad range parameter for children: too many elements (%lu)." +msgstr "WARNING: Bad range parameter for children: too many elements (%lu)." + +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#, c-format +msgid "" +"WARNING: Normalized tree is growing past %d elements. Aborting " +"normalization.\n" +msgstr "" +"WARNING: Normalized tree is growing past %d elements. Aborting " +"normalization.\n" + +#: src/dxfdata.cc:83 +#, c-format +msgid "WARNING: Can't open DXF file '%s'." +msgstr "WARNING: Can't open DXF file '%s'." + +#: src/dxfdata.cc:147 +#, c-format +msgid "WARNING: Illegal ID '%s' in `%s'" +msgstr "WARNING: Illegal ID '%s' in `%s'" + +#: src/dxfdata.cc:386 +#, c-format +msgid "WARNING: Illegal value %s in '%s'" +msgstr "WARNING: Illegal value %s in '%s'" + +#: src/dxfdata.cc:392 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." +msgstr "WARNING: Unsupported DXF Entity '%s' (%x) in %s." + +#: src/dxfdata.cc:395 +#, c-format +msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." +msgstr "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." + +#: src/dxfdim.cc:131 +#, c-format +msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" +msgstr "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" + +#: src/dxfdim.cc:136 +#, c-format +msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" +msgstr "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" + +#: src/dxfdim.cc:211 +#, c-format +msgid "WARNING: Can't find cross in '%s', layer '%s'!" +msgstr "WARNING: Can't find cross in '%s', layer '%s'!" + +#: src/dxftess-cgal.cc:170 +msgid "" +"WARNING: Duplicate vertices and/or intersecting lines found during DXF " +"Tessellation." +msgstr "" +"WARNING: Duplicate vertices and/or intersecting lines found during DXF " +"Tessellation." + +#: src/dxftess-cgal.cc:171 +msgid "" +"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." +msgstr "" +"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." + +#: src/dxftess-cgal.cc:176 +#, c-format +msgid "CGAL error in dxf_tesselate(): %s" +msgstr "CGAL error in dxf_tesselate(): %s" + +#: src/dxftess-cgal.cc:475 +#, c-format +msgid "CGAL error in dxftess triangulate_polygon: %s" +msgstr "CGAL error in dxftess triangulate_polygon: %s" + +#: src/dxftess-cgal.cc:491 +msgid "WARNING: PolySet has polygon with <3 points" +msgstr "WARNING: PolySet has polygon with <3 points" + +#: src/dxftess-cgal.cc:496 +msgid "WARNING: PolySet has degenerate polygon" +msgstr "WARNING: PolySet has degenerate polygon" + +#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 +#, c-format +msgid "GLU tesselation error %s" +msgstr "GLU tesselation error %s" + +#: src/export.cc:48 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" +msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" + +#: src/export.cc:120 src/export.cc:137 +#, c-format +msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" +msgstr "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" + +#: src/export.cc:123 +msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" +msgstr "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" + +#: src/func.cc:503 src/func.cc:536 +#, c-format +msgid " WARNING: search term not found: \"%s\"" +msgstr " WARNING: search term not found: \"%s\"" + +#: src/func.cc:533 +#, c-format +msgid " WARNING: search term not found: %s" +msgstr " WARNING: search term not found: %s" + +#: src/func.cc:545 +#, c-format +msgid " WARNING: search: none performed on input %s" +msgstr " WARNING: search: none performed on input %s" + +#: src/func.cc:591 +#, c-format +msgid "WARNING: Negative parent module index (%d) not allowed" +msgstr "WARNING: Negative parent module index (%d) not allowed" + +#: src/func.cc:595 +#, c-format +msgid "" +"WARNING: Parent module index (%d) greater than the number of modules on the " +"stack" +msgstr "" +"WARNING: Parent module index (%d) greater than the number of modules on the " +"stack" + +#: src/glview.cc:149 +#, c-format +msgid "GLEW Error: %s\n" +msgstr "GLEW Error: %s\n" + +#: src/glview.cc:161 +#, c-format +msgid "" +"GLEW version %s\n" +"OpenGL version %s\n" +"%s (%s)\n" +"\n" +"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" +"Extensions:\n" +"%s\n" +msgstr "" +"GLEW version %s\n" +"OpenGL version %s\n" +"%s (%s)\n" +"\n" +"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" +"Extensions:\n" +"%s\n" + +#: src/glview.cc:304 +#, c-format +msgid "" +"OpenGL Program Linker Error:\n" +"%.*s" +msgstr "" +"OpenGL Program Linker Error:\n" +"%.*s" + +#: src/glview.cc:310 +#, c-format +msgid "" +"OpenGL Program Link OK:\n" +"%.*s" +msgstr "" +"OpenGL Program Link OK:\n" +"%.*s" + +#: src/glview.cc:315 +#, c-format +msgid "" +"OpenGL Program Validation results:\n" +"%.*s" +msgstr "" +"OpenGL Program Validation results:\n" +"%.*s" + +#: src/glview.cc:329 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" + +#: src/glview.cc:332 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" + +#: src/glview.cc:335 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" + +#: src/glview.cc:339 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" + +#: src/glview.cc:537 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" +"Ansicht: Verschiebung = [ %.2f %.2f %.2f ], Rotation = [ %.2f %.2f %.2f ], " +"Abstand = %.2f" + +#: src/handle_dep.cc:36 +#, c-format +msgid "Can't open dependencies file `%s' for writing!\n" +msgstr "Can't open dependencies file `%s' for writing!\n" + +#: src/import.cc:98 +msgid "DEPRECATED: filename= is deprecated. Please use file=" +msgstr "DEPRECATED: filename= is deprecated. Please use file=" + +#: src/import.cc:122 +msgid "DEPRECATED: layername= is deprecated. Please use layer=" +msgstr "DEPRECATED: layername= is deprecated. Please use layer=" + +#: src/import.cc:195 src/import.cc:281 +#, c-format +msgid "WARNING: Can't open import file '%s'." +msgstr "WARNING: Can't open import file '%s'." + +#: src/import.cc:247 +#, c-format +msgid "WARNING: Can't parse vertex line '%s'." +msgstr "WARNING: Can't parse vertex line '%s'." + +#: src/import.cc:292 +msgid "WARNING: OFF import requires CGAL." +msgstr "WARNING: OFF import requires CGAL." + +#: src/import.cc:306 +#, c-format +msgid "ERROR: Unsupported file format while trying to import file '%s'" +msgstr "ERROR: Unsupported file format while trying to import file '%s'" + +#: src/linearextrude.cc:77 +msgid "" +"DEPRECATED: Support for reading files in linear_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" +"DEPRECATED: Support for reading files in linear_extrude will be removed in " +"future releases. Use a child import() instead." + +#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 +#, c-format +msgid "WARNING: No suitable PolySetEvaluator found for %s module!" +msgstr "WARNING: No suitable PolySetEvaluator found for %s module!" + +#: src/mainwin.cc:119 +msgid "" +"Copyright (C) 2009-2013 The OpenSCAD Developers\n" +"\n" +"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." +msgstr "" +"Copyright (C) 2009-2013 The OpenSCAD Developers\n" +"\n" +"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." + +#: src/mainwin.cc:525 +msgid "OpenSCAD - New Document[*]" +msgstr "OpenSCAD - Neue Datei[*]" + +#: src/mainwin.cc:529 +msgid "OpenSCAD - " +msgstr "OpenSCAD - " + +#: src/mainwin.cc:529 +msgid "[*]" +msgstr "[*]" + +#: src/mainwin.cc:603 +#, c-format +msgid "Failed to open file %s: %s" +msgstr "Failed to open file %s: %s" + +#: src/mainwin.cc:610 +#, c-format +msgid "Loaded design '%s'." +msgstr "Loaded design '%s'." + +#: src/mainwin.cc:657 +#, c-format +msgid "Module cache size: %d modules" +msgstr "Module cache size: %d modules" + +#: src/mainwin.cc:741 +msgid "Compiling design (CSG Tree generation)..." +msgstr "Compiling design (CSG Tree generation)..." + +#: src/mainwin.cc:767 +msgid "ERROR: Compilation failed! (no top level object found)" +msgstr "ERROR: Compilation failed! (no top level object found)" + +#: src/mainwin.cc:769 +msgid "ERROR: Compilation failed!" +msgstr "ERROR: Compilation failed!" + +#: src/mainwin.cc:782 +msgid "Compiling design (CSG Products generation)..." +msgstr "Compiling design (CSG Products generation)..." + +#: src/mainwin.cc:804 +msgid "ERROR: CSG generation failed! (no top level object found)" +msgstr "ERROR: CSG generation failed! (no top level object found)" + +#: src/mainwin.cc:813 +msgid "CSG generation cancelled." +msgstr "CSG generation cancelled." + +#: src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "Compiling design (CSG Products normalization)..." + +#: src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "WARNING: CSG normalization resulted in an empty tree" + +#: src/mainwin.cc:839 +#, c-format +msgid "Compiling highlights (%d CSG Trees)..." +msgstr "Compiling highlights (%d CSG Trees)..." + +#: src/mainwin.cc:851 +#, c-format +msgid "Compiling background (%d CSG Trees)..." +msgstr "Compiling background (%d CSG Trees)..." + +#: src/mainwin.cc:864 +#, c-format +msgid "WARNING: Normalized tree has %d elements!" +msgstr "WARNING: Normalized tree has %d elements!" + +#: src/mainwin.cc:865 +msgid "WARNING: OpenCSG rendering has been disabled." +msgstr "WARNING: OpenCSG rendering has been disabled." + +#: src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "Normalized CSG tree has %d elements" + +#: src/mainwin.cc:878 +msgid "CSG generation finished." +msgstr "CSG generation finished." + +#: src/mainwin.cc:880 src/mainwin.cc:1346 +#, c-format +msgid "Total rendering time: %d hours, %d minutes, %d seconds" +msgstr "Total rendering time: %d hours, %d minutes, %d seconds" + +#: src/mainwin.cc:907 +msgid "Open File" +msgstr "Open File" + +#: src/mainwin.cc:908 +msgid "OpenSCAD Designs (*.scad *.csg)" +msgstr "OpenSCAD Designs (*.scad *.csg)" + +#: src/mainwin.cc:1002 +#, c-format +msgid "Failed to open file for writing: %s (%s)" +msgstr "Failed to open file for writing: %s (%s)" + +#: src/mainwin.cc:1003 +msgid "" +"Failed to open file for writing:\n" +" %1 (%2)" +msgstr "" +"Failed to open file for writing:\n" +" %1 (%2)" + +#: src/mainwin.cc:1010 +#, c-format +msgid "Saved design '%s'." +msgstr "Saved design '%s'." + +#: src/mainwin.cc:1020 +msgid "Save File" +msgstr "Save File" + +#: src/mainwin.cc:1021 +msgid "Untitled.scad" +msgstr "Untitled.scad" + +#: src/mainwin.cc:1022 +msgid "OpenSCAD Designs (*.scad)" +msgstr "OpenSCAD Designs (*.scad)" + +#: src/mainwin.cc:1032 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" +"%1 existiert bereits.\n" +"Mochten Sie die Datei ersetzen?" + +#: src/mainwin.cc:1047 +#, c-format +msgid "WARNING: Library path %s doesn't exist. Creating" +msgstr "WARNING: Library path %s doesn't exist. Creating" + +#: src/mainwin.cc:1049 +#, c-format +msgid "ERROR: Cannot create library path: %s" +msgstr "ERROR: Cannot create library path: %s" + +#: src/mainwin.cc:1184 src/mainwin.cc:1857 +msgid "Application" +msgstr "Application" + +#: src/mainwin.cc:1185 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" +"The document has been modified.\n" +"Do you really want to reload the file?" + +#: src/mainwin.cc:1235 src/mainwin.cc:1279 +msgid "Parsing design (AST generation)..." +msgstr "Parsing design (AST generation)..." + +#: src/mainwin.cc:1263 +#, c-format +msgid "frame%05d.png" +msgstr "frame%05d.png" + +#: src/mainwin.cc:1300 +msgid "Rendering Polygon Mesh using CGAL..." +msgstr "Rendering Polygon Mesh using CGAL..." + +#: src/mainwin.cc:1321 +msgid " Top level object is a 2D object:" +msgstr " Top level object is a 2D object:" + +#: src/mainwin.cc:1322 +#, c-format +msgid " Empty: %6s" +msgstr " Empty: %6s" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "yes" +msgstr "yes" + +#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 +#: src/mainwin.cc:1335 +msgid "no" +msgstr "no" + +#: src/mainwin.cc:1323 +#, c-format +msgid " Plane: %6s" +msgstr " Plane: %6s" + +#: src/mainwin.cc:1324 src/mainwin.cc:1336 +#, c-format +msgid " Vertices: %6d" +msgstr " Vertices: %6d" + +#: src/mainwin.cc:1325 src/mainwin.cc:1337 +#, c-format +msgid " Halfedges: %6d" +msgstr " Halfedges: %6d" + +#: src/mainwin.cc:1326 src/mainwin.cc:1338 +#, c-format +msgid " Edges: %6d" +msgstr " Edges: %6d" + +#: src/mainwin.cc:1327 +#, c-format +msgid " Faces: %6d" +msgstr " Faces: %6d" + +#: src/mainwin.cc:1328 +#, c-format +msgid " FaceCycles: %6d" +msgstr " FaceCycles: %6d" + +#: src/mainwin.cc:1329 +#, c-format +msgid " ConnComp: %6d" +msgstr " ConnComp: %6d" + +#: src/mainwin.cc:1333 +msgid " Top level object is a 3D object:" +msgstr " Top level object is a 3D object:" + +#: src/mainwin.cc:1334 +#, c-format +msgid " Simple: %6s" +msgstr " Simple: %6s" + +#: src/mainwin.cc:1335 +#, c-format +msgid " Valid: %6s" +msgstr " Valid: %6s" + +#: src/mainwin.cc:1339 +#, c-format +msgid " Halffacets: %6d" +msgstr " Halffacets: %6d" + +#: src/mainwin.cc:1340 +#, c-format +msgid " Facets: %6d" +msgstr " Facets: %6d" + +#: src/mainwin.cc:1341 +#, c-format +msgid " Volumes: %6d" +msgstr " Volumes: %6d" + +#: src/mainwin.cc:1359 +msgid "Rendering finished." +msgstr "Rendering finished." + +#: src/mainwin.cc:1362 +msgid "WARNING: No top level geometry to render" +msgstr "WARNING: No top level geometry to render" + +#: src/mainwin.cc:1380 +msgid "AST Dump" +msgstr "AST Dump" + +#: src/mainwin.cc:1385 +msgid "No AST to dump. Please try compiling first..." +msgstr "No AST to dump. Please try compiling first..." + +#: src/mainwin.cc:1398 +msgid "CSG Tree Dump" +msgstr "CSG Tree Dump" + +#: src/mainwin.cc:1403 +msgid "No CSG to dump. Please try compiling first..." +msgstr "No CSG to dump. Please try compiling first..." + +#: src/mainwin.cc:1416 +msgid "CSG Products Dump" +msgstr "CSG Products Dump" + +#: src/mainwin.cc:1418 +msgid "" +"\n" +"CSG before normalization:\n" +"%1\n" +"\n" +"\n" +"CSG after normalization:\n" +"%2\n" +"\n" +"\n" +"CSG rendering chain:\n" +"%3\n" +"\n" +"\n" +"Highlights CSG rendering chain:\n" +"%4\n" +"\n" +"\n" +"Background CSG rendering chain:\n" +"%5\n" +msgstr "" +"\n" +"CSG before normalization:\n" +"%1\n" +"\n" +"\n" +"CSG after normalization:\n" +"%2\n" +"\n" +"\n" +"CSG rendering chain:\n" +"%3\n" +"\n" +"\n" +"Highlights CSG rendering chain:\n" +"%4\n" +"\n" +"\n" +"Background CSG rendering chain:\n" +"%5\n" + +#: src/mainwin.cc:1441 src/mainwin.cc:1501 +msgid "Nothing to export! Try building first (press F6)." +msgstr "Nothing to export! Try building first (press F6)." + +#: src/mainwin.cc:1447 +msgid "Current top level object is not a 3D object." +msgstr "Current top level object is not a 3D object." + +#: src/mainwin.cc:1453 +msgid "" +"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." +"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +msgstr "" +"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." +"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" + +#: src/mainwin.cc:1460 +msgid "Export STL File" +msgstr "Export STL File" + +#: src/mainwin.cc:1460 +msgid "Export OFF File" +msgstr "Export OFF File" + +#: src/mainwin.cc:1462 +msgid "STL Files (*.stl)" +msgstr "STL Files (*.stl)" + +#: src/mainwin.cc:1462 +msgid "OFF Files (*.off)" +msgstr "OFF Files (*.off)" + +#: src/mainwin.cc:1464 +#, c-format +msgid "No filename specified. %s export aborted." +msgstr "No filename specified. %s export aborted." + +#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 +#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 +#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 +#: src/openscad.cc:418 +#, c-format +msgid "Can't open file \"%s\" for export" +msgstr "Can't open file \"%s\" for export" + +#: src/mainwin.cc:1478 +#, c-format +msgid "%s export finished." +msgstr "%s export finished." + +#: src/mainwin.cc:1507 +msgid "Current top level object is not a 2D object." +msgstr "Current top level object is not a 2D object." + +#: src/mainwin.cc:1513 +msgid "Export DXF File" +msgstr "Export DXF File" + +#: src/mainwin.cc:1514 +msgid "Untitled.dxf" +msgstr "Untitled.dxf" + +#: src/mainwin.cc:1515 +msgid "DXF Files (*.dxf)" +msgstr "DXF Files (*.dxf)" + +#: src/mainwin.cc:1517 +msgid "No filename specified. DXF export aborted." +msgstr "No filename specified. DXF export aborted." + +#: src/mainwin.cc:1529 +msgid "DXF export finished." +msgstr "DXF export finished." + +#: src/mainwin.cc:1541 +msgid "Nothing to export. Please try compiling first..." +msgstr "Nothing to export. Please try compiling first..." + +#: src/mainwin.cc:1546 +msgid "Export CSG File" +msgstr "Export CSG File" + +#: src/mainwin.cc:1547 +msgid "Untitled.csg" +msgstr "Untitled.csg" + +#: src/mainwin.cc:1548 +msgid "CSG Files (*.csg)" +msgstr "CSG Files (*.csg)" + +#: src/mainwin.cc:1550 +msgid "No filename specified. CSG export aborted." +msgstr "No filename specified. CSG export aborted." + +#: src/mainwin.cc:1562 +msgid "CSG export finished." +msgstr "CSG export finished." + +#: src/mainwin.cc:1573 +msgid "Export Image" +msgstr "Bild exportieren" + +#: src/mainwin.cc:1573 +msgid "PNG Files (*.png)" +msgstr "PNG Files (*.png)" + +#: src/mainwin.cc:1575 +msgid "No filename specified. Image export aborted." +msgstr "No filename specified. Image export aborted." + +#: src/mainwin.cc:1827 +msgid "http://openscad.org/" +msgstr "http://openscad.org/" + +#: src/mainwin.cc:1833 +msgid "http://www.openscad.org/documentation.html" +msgstr "http://www.openscad.org/documentation.html" + +#: src/mainwin.cc:1842 +msgid "OpenGL Info" +msgstr "OpenGL Info" + +#: src/mainwin.cc:1842 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "OpenSCAD Detailed Library and Build Information" + +#: src/mainwin.cc:1858 +msgid "" +"The document has been modified.\n" +"Do you want to save your changes?" +msgstr "" +"The document has been modified.\n" +"Do you want to save your changes?" + +#: src/ModuleCache.cc:70 +#, c-format +msgid "Recompiling cached library: %s (%s)" +msgstr "Recompiling cached library: %s (%s)" + +#: src/ModuleCache.cc:73 +#, c-format +msgid "Compiling library '%s'." +msgstr "Compiling library '%s'." + +#: src/ModuleCache.cc:81 +#, c-format +msgid "WARNING: Can't open library file '%s'\n" +msgstr "WARNING: Can't open library file '%s'\n" + +#: src/ModuleCache.cc:99 +#, c-format +msgid " compiled module: %p" +msgstr " compiled module: %p" + +#: src/module.cc:180 +#, c-format +msgid "ERROR: Recursion detected calling module '%s'" +msgstr "ERROR: Recursion detected calling module '%s'" + +#: src/module.cc:298 +#, c-format +msgid "WARNING: Failed to compile library '%s'." +msgstr "WARNING: Failed to compile library '%s'." + +#: src/openscad.cc:109 +msgid "" +"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" +"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" +"%2%[ --version ] [ --info ] \\\n" +"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" +"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" +"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" +"%2%[ --render | --preview[=throwntogether] ] \\\n" +"%2%[ --enable= ] \\\n" +"%2%filename\n" +msgstr "" +"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" +"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" +"%2%[ --version ] [ --info ] \\\n" +"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" +"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" +"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" +"%2%[ --render | --preview[=throwntogether] ] \\\n" +"%2%[ --enable= ] \\\n" +"%2%filename\n" + +#: src/openscad.cc:126 +#, c-format +msgid "OpenSCAD version %s\n" +msgstr "OpenSCAD version %s\n" + +#: src/openscad.cc:138 +#, c-format +msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" +msgstr "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" + +#: src/openscad.cc:160 +msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" +msgstr "Camera setup requires either 7 numbers for Gimbal Camera\n" + +#: src/openscad.cc:161 +msgid "or 6 numbers for Vector Camera\n" +msgstr "or 6 numbers for Vector Camera\n" + +#: src/openscad.cc:177 +msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" +msgstr "projection needs to be 'o' or 'p' for ortho or perspective\n" + +#: src/openscad.cc:188 +msgid "Need 2 numbers for imgsize\n" +msgstr "Need 2 numbers for imgsize\n" + +#: src/openscad.cc:236 +#, c-format +msgid "Unknown suffix for output file %s\n" +msgstr "Unknown suffix for output file %s\n" + +#: src/openscad.cc:260 +#, c-format +msgid "Can't open input file '%s'!\n" +msgstr "Can't open input file '%s'!\n" + +#: src/openscad.cc:269 +#, c-format +msgid "Can't parse file '%s'!\n" +msgstr "Can't parse file '%s'!\n" + +#: src/openscad.cc:351 +#, c-format +msgid "Output file:%s\n" +msgstr "Output file:%s\n" + +#: src/openscad.cc:352 +msgid "Sorry, don't know how to write deps for that file type. Exiting\n" +msgstr "Sorry, don't know how to write deps for that file type. Exiting\n" + +#: src/openscad.cc:357 +msgid "error writing deps" +msgstr "error writing deps" + +#: src/openscad.cc:364 src/openscad.cc:383 +msgid "Current top level object is not a 3D object.\n" +msgstr "Current top level object is not a 3D object.\n" + +#: src/openscad.cc:368 src/openscad.cc:387 +msgid "Object isn't a valid 2-manifold! Modify your design.\n" +msgstr "Object isn't a valid 2-manifold! Modify your design.\n" + +#: src/openscad.cc:402 +msgid "Current top level object is not a 2D object.\n" +msgstr "Current top level object is not a 2D object.\n" + +#: src/openscad.cc:583 +msgid "Allowed options" +msgstr "Allowed options" + +#: src/openscad.cc:585 +msgid "help message" +msgstr "help message" + +#: src/openscad.cc:586 +msgid "print the version" +msgstr "print the version" + +#: src/openscad.cc:587 +msgid "print information about the building process" +msgstr "print information about the building process" + +#: src/openscad.cc:588 +msgid "if exporting a png image, do a full CGAL render" +msgstr "if exporting a png image, do a full CGAL render" + +#: src/openscad.cc:589 +msgid "" +"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" +msgstr "" +"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" + +#: src/openscad.cc:590 +msgid "parameters for camera when exporting png" +msgstr "parameters for camera when exporting png" + +#: src/openscad.cc:591 +msgid "=width,height for exporting png" +msgstr "=width,height for exporting png" + +#: src/openscad.cc:592 +msgid "(o)rtho or (p)erspective when exporting png" +msgstr "(o)rtho or (p)erspective when exporting png" + +#: src/openscad.cc:593 +msgid "out-file" +msgstr "out-file" + +#: src/openscad.cc:594 +msgid "stl-file" +msgstr "stl-file" + +#: src/openscad.cc:595 +msgid "dxf-file" +msgstr "dxf-file" + +#: src/openscad.cc:596 +msgid "deps-file" +msgstr "deps-file" + +#: src/openscad.cc:597 +msgid "makefile" +msgstr "makefile" + +#: src/openscad.cc:598 +msgid "var=val" +msgstr "var=val" + +#: src/openscad.cc:599 +msgid "enable experimental features" +msgstr "enable experimental features" + +#: src/openscad.cc:601 +msgid "Hidden options" +msgstr "Hidden options" + +#: src/openscad.cc:603 +msgid "input file" +msgstr "input file" + +#: src/openscad.cc:637 +msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" +msgstr "DEPRECATED: The -s option is deprecated. Use -o instead.\n" + +#: src/openscad.cc:642 +msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" +msgstr "DEPRECATED: The -x option is deprecated. Use -o instead.\n" + +#: src/openscad.cc:699 +msgid "Requested GUI mode but can't open display!\n" +msgstr "Requested GUI mode but can't open display!\n" + +#: src/PolySetCache.cc:24 +#, c-format +msgid "PolySets in cache: %d" +msgstr "PolySets in cache: %d" + +#: src/PolySetCache.cc:25 +#, c-format +msgid "PolySet cache size in bytes: %d" +msgstr "PolySet cache size in bytes: %d" + +#: src/polyset.cc:55 +msgid "PolySet:" +msgstr "PolySet:" + +#: src/polyset.cc:56 +msgid "" +"\n" +" dimensions:" +msgstr "" +"\n" +" dimensions:" + +#: src/polyset.cc:57 +msgid "" +"\n" +" convexity:" +msgstr "" +"\n" +" convexity:" + +#: src/polyset.cc:58 +msgid "" +"\n" +" num polygons: " +msgstr "" +"\n" +" num polygons: " + +#: src/polyset.cc:59 +msgid "" +"\n" +" num borders: " +msgstr "" +"\n" +" num borders: " + +#: src/polyset.cc:60 +msgid "" +"\n" +" polygons data:" +msgstr "" +"\n" +" polygons data:" + +#: src/polyset.cc:62 +msgid "" +"\n" +" polygon begin:" +msgstr "" +"\n" +" polygon begin:" + +#: src/polyset.cc:66 src/polyset.cc:75 +msgid "" +"\n" +" vertex:" +msgstr "" +"\n" +" vertex:" + +#: src/polyset.cc:69 +msgid "" +"\n" +" borders data:" +msgstr "" +"\n" +" borders data:" + +#: src/polyset.cc:71 +msgid "" +"\n" +" border polygon begin:" +msgstr "" +"\n" +" border polygon begin:" + +#: src/polyset.cc:78 +msgid "" +"\n" +"PolySet end" +msgstr "" +"\n" +"PolySet end" + +#: src/PolySetCGALEvaluator.cc:46 +msgid "" +"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " +"design.." +msgstr "" +"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " +"design.." + +#: src/PolySetCGALEvaluator.cc:63 +#, c-format +msgid "CGAL error in projection node during plane intersection: %s" +msgstr "CGAL error in projection node during plane intersection: %s" + +#: src/PolySetCGALEvaluator.cc:65 +msgid "Trying alternative intersection using very large thin box: " +msgstr "Trying alternative intersection using very large thin box: " + +#: src/PolySetCGALEvaluator.cc:80 +#, c-format +msgid "CGAL error in projection node during bigbox intersection: %s" +msgstr "CGAL error in projection node during bigbox intersection: %s" + +#: src/PolySetCGALEvaluator.cc:87 +msgid "WARNING: projection() failed." +msgstr "WARNING: projection() failed." + +#: src/PolySetCGALEvaluator.cc:109 +#, c-format +msgid "CGAL error in projection node while flattening: %s" +msgstr "CGAL error in projection node while flattening: %s" + +#: src/PolySetCGALEvaluator.cc:303 +msgid "ERROR: linear_extrude() is not defined for 3D child objects!" +msgstr "ERROR: linear_extrude() is not defined for 3D child objects!" + +#: src/PolySetCGALEvaluator.cc:343 +#, c-format +msgid "" +"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" +msgstr "" +"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" + +#: src/PolySetCGALEvaluator.cc:403 +msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" +msgstr "ERROR: rotate_extrude() is not defined for 3D child objects!" + +#: src/PolySetCGALEvaluator.cc:441 +msgid "WARNING: Body of render() isn't valid 2-manifold!" +msgstr "WARNING: Body of render() isn't valid 2-manifold!" + +#: src/PolySetCGALEvaluator.cc:466 +#, c-format +msgid "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" +msgstr "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" + +#: src/primitives.cc:130 +#, c-format +msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." +msgstr "" +"WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." + +#: src/primitives.cc:183 +#, c-format +msgid "WARNING: $fs too small - clamping to %f" +msgstr "WARNING: $fs too small - clamping to %f" + +#: src/primitives.cc:187 +#, c-format +msgid "WARNING: $fa too small - clamping to %f" +msgstr "WARNING: $fa too small - clamping to %f" + +#: src/primitives.cc:244 +msgid "" +"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " +"polyhedron(faces=[]) instead." +msgstr "" +"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " +"polyhedron(faces=[]) instead." + +#: src/primitives.cc:536 +#, c-format +msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" +msgstr "ERROR: Unable to convert point at index %d to a vec2 of numbers" + +#: src/rotateextrude.cc:72 +msgid "" +"DEPRECATED: Support for reading files in rotate_extrude will be removed in " +"future releases. Use a child import() instead." +msgstr "" +"DEPRECATED: Support for reading files in rotate_extrude will be removed in " +"future releases. Use a child import() instead." + +#: src/surface.cc:107 +#, c-format +msgid "WARNING: Can't open DAT file '%s'." +msgstr "WARNING: Can't open DAT file '%s'." + +#: src/surface.cc:139 +#, c-format +msgid "WARNING: Illegal value in '%s': %s" +msgstr "WARNING: Illegal value in '%s': %s" + +#: src/value.cc:640 +msgid "" +"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " +"than the end value is deprecated." +msgstr "" +"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " +"than the end value is deprecated." diff --git a/po/openscad.pot b/po/openscad.pot index ddc4bcbd..301e7619 100644 --- a/po/openscad.pot +++ b/po/openscad.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.06\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 05:16+0100\n" +"POT-Creation-Date: 2014-01-06 05:25+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" From a7e3c8639cb20d3b30c8936a255e22139f0eed27 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:21:45 +0200 Subject: [PATCH 006/263] Fix compile problem on MinGW and force UTF-8 as encoding. --- .gitignore | 5 ++--- po/de.po | 47 ++++++++++++++++++++------------------- po/fr.po | 44 ++++++++++++++++++------------------ po/openscad.pot | 44 ++++++++++++++++++------------------ po/ru.po | 44 ++++++++++++++++++------------------ scripts/release-common.sh | 2 +- src/QGLView.cc | 1 + src/openscad.cc | 6 +++++ src/qtgettext.h | 12 +++++++--- 9 files changed, 109 insertions(+), 96 deletions(-) diff --git a/.gitignore b/.gitignore index dee510fe..96e60faf 100644 --- a/.gitignore +++ b/.gitignore @@ -13,10 +13,9 @@ parser_yacc.h /tmp /OpenSCAD.app */#*# +/po/*/*/*.mo /nbproject /openscad -/mingw32 -/mingw64 /tests/openscad_nogui testdata/scad/features/import_dxf-tests.scad testdata/scad/features/import_stl-tests.scad @@ -25,4 +24,4 @@ testdata/scad/misc/use-tests.scad /mingw32 /mingw64 **/project.xcworkspace -**/xcuserdata \ No newline at end of file +**/xcuserdata diff --git a/po/de.po b/po/de.po index 2c38f534..26f46fa9 100644 --- a/po/de.po +++ b/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 04:16+0100\n" -"PO-Revision-Date: 2014-01-06 05:25+0100\n" +"POT-Creation-Date: 2014-01-06 21:19+0100\n" +"PO-Revision-Date: 2014-01-06 21:19+0100\n" "Last-Translator: Torsten Paul \n" "Language-Team: German\n" "Language: de\n" @@ -16,6 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" +"X-Poedit-SourceCharset: UTF-8\n" #: objects/ui_AboutDialog.h:51 msgid "About OpenSCAD" @@ -1750,89 +1751,89 @@ msgstr "Object isn't a valid 2-manifold! Modify your design.\n" msgid "Current top level object is not a 2D object.\n" msgstr "Current top level object is not a 2D object.\n" -#: src/openscad.cc:583 +#: src/openscad.cc:584 msgid "Allowed options" msgstr "Allowed options" -#: src/openscad.cc:585 +#: src/openscad.cc:586 msgid "help message" msgstr "help message" -#: src/openscad.cc:586 +#: src/openscad.cc:587 msgid "print the version" msgstr "print the version" -#: src/openscad.cc:587 +#: src/openscad.cc:588 msgid "print information about the building process" msgstr "print information about the building process" -#: src/openscad.cc:588 +#: src/openscad.cc:589 msgid "if exporting a png image, do a full CGAL render" msgstr "if exporting a png image, do a full CGAL render" -#: src/openscad.cc:589 +#: src/openscad.cc:590 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" -#: src/openscad.cc:590 +#: src/openscad.cc:591 msgid "parameters for camera when exporting png" msgstr "parameters for camera when exporting png" -#: src/openscad.cc:591 +#: src/openscad.cc:592 msgid "=width,height for exporting png" msgstr "=width,height for exporting png" -#: src/openscad.cc:592 +#: src/openscad.cc:593 msgid "(o)rtho or (p)erspective when exporting png" msgstr "(o)rtho or (p)erspective when exporting png" -#: src/openscad.cc:593 +#: src/openscad.cc:594 msgid "out-file" msgstr "out-file" -#: src/openscad.cc:594 +#: src/openscad.cc:595 msgid "stl-file" msgstr "stl-file" -#: src/openscad.cc:595 +#: src/openscad.cc:596 msgid "dxf-file" msgstr "dxf-file" -#: src/openscad.cc:596 +#: src/openscad.cc:597 msgid "deps-file" msgstr "deps-file" -#: src/openscad.cc:597 +#: src/openscad.cc:598 msgid "makefile" msgstr "makefile" -#: src/openscad.cc:598 +#: src/openscad.cc:599 msgid "var=val" msgstr "var=val" -#: src/openscad.cc:599 +#: src/openscad.cc:600 msgid "enable experimental features" msgstr "enable experimental features" -#: src/openscad.cc:601 +#: src/openscad.cc:602 msgid "Hidden options" msgstr "Hidden options" -#: src/openscad.cc:603 +#: src/openscad.cc:604 msgid "input file" msgstr "input file" -#: src/openscad.cc:637 +#: src/openscad.cc:638 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "DEPRECATED: The -s option is deprecated. Use -o instead.\n" -#: src/openscad.cc:642 +#: src/openscad.cc:643 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "DEPRECATED: The -x option is deprecated. Use -o instead.\n" -#: src/openscad.cc:699 +#: src/openscad.cc:700 msgid "Requested GUI mode but can't open display!\n" msgstr "Requested GUI mode but can't open display!\n" diff --git a/po/fr.po b/po/fr.po index 4c2009b2..962a2e14 100644 --- a/po/fr.po +++ b/po/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2013.02.07\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 05:16+0100\n" +"POT-Creation-Date: 2014-01-06 21:19+0100\n" "PO-Revision-Date: 2013-02-08 15:06-0600\n" "Last-Translator: don bright \n" "Language-Team: French\n" @@ -1653,88 +1653,88 @@ msgstr "" msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:583 +#: src/openscad.cc:584 msgid "Allowed options" msgstr "" -#: src/openscad.cc:585 +#: src/openscad.cc:586 msgid "help message" msgstr "" -#: src/openscad.cc:586 +#: src/openscad.cc:587 msgid "print the version" msgstr "" -#: src/openscad.cc:587 +#: src/openscad.cc:588 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:588 +#: src/openscad.cc:589 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:589 +#: src/openscad.cc:590 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:590 +#: src/openscad.cc:591 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:592 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:592 +#: src/openscad.cc:593 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:594 msgid "out-file" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:595 msgid "stl-file" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:596 msgid "dxf-file" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:597 msgid "deps-file" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:598 msgid "makefile" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:599 msgid "var=val" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:600 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:601 +#: src/openscad.cc:602 msgid "Hidden options" msgstr "" -#: src/openscad.cc:603 +#: src/openscad.cc:604 msgid "input file" msgstr "" -#: src/openscad.cc:637 +#: src/openscad.cc:638 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:642 +#: src/openscad.cc:643 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:699 +#: src/openscad.cc:700 msgid "Requested GUI mode but can't open display!\n" msgstr "" diff --git a/po/openscad.pot b/po/openscad.pot index 301e7619..66b595b3 100644 --- a/po/openscad.pot +++ b/po/openscad.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.06\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 05:25+0100\n" +"POT-Creation-Date: 2014-01-06 21:45+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1650,88 +1650,88 @@ msgstr "" msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:583 +#: src/openscad.cc:584 msgid "Allowed options" msgstr "" -#: src/openscad.cc:585 +#: src/openscad.cc:586 msgid "help message" msgstr "" -#: src/openscad.cc:586 +#: src/openscad.cc:587 msgid "print the version" msgstr "" -#: src/openscad.cc:587 +#: src/openscad.cc:588 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:588 +#: src/openscad.cc:589 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:589 +#: src/openscad.cc:590 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:590 +#: src/openscad.cc:591 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:592 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:592 +#: src/openscad.cc:593 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:594 msgid "out-file" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:595 msgid "stl-file" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:596 msgid "dxf-file" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:597 msgid "deps-file" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:598 msgid "makefile" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:599 msgid "var=val" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:600 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:601 +#: src/openscad.cc:602 msgid "Hidden options" msgstr "" -#: src/openscad.cc:603 +#: src/openscad.cc:604 msgid "input file" msgstr "" -#: src/openscad.cc:637 +#: src/openscad.cc:638 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:642 +#: src/openscad.cc:643 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:699 +#: src/openscad.cc:700 msgid "Requested GUI mode but can't open display!\n" msgstr "" diff --git a/po/ru.po b/po/ru.po index 8701f829..1f5054b3 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 05:16+0100\n" +"POT-Creation-Date: 2014-01-06 21:19+0100\n" "PO-Revision-Date: 2013-02-24 17:50+0100\n" "Last-Translator: \n" "Language-Team: Russian\n" @@ -1651,88 +1651,88 @@ msgstr "" msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:583 +#: src/openscad.cc:584 msgid "Allowed options" msgstr "" -#: src/openscad.cc:585 +#: src/openscad.cc:586 msgid "help message" msgstr "" -#: src/openscad.cc:586 +#: src/openscad.cc:587 msgid "print the version" msgstr "" -#: src/openscad.cc:587 +#: src/openscad.cc:588 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:588 +#: src/openscad.cc:589 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:589 +#: src/openscad.cc:590 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:590 +#: src/openscad.cc:591 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:592 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:592 +#: src/openscad.cc:593 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:594 msgid "out-file" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:595 msgid "stl-file" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:596 msgid "dxf-file" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:597 msgid "deps-file" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:598 msgid "makefile" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:599 msgid "var=val" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:600 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:601 +#: src/openscad.cc:602 msgid "Hidden options" msgstr "" -#: src/openscad.cc:603 +#: src/openscad.cc:604 msgid "input file" msgstr "" -#: src/openscad.cc:637 +#: src/openscad.cc:638 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:642 +#: src/openscad.cc:643 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:699 +#: src/openscad.cc:700 msgid "Requested GUI mode but can't open display!\n" msgstr "" diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 3eedab13..e06646a2 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -384,7 +384,7 @@ fi if [ -n $TRANSLATIONDIR ]; then echo $TRANSLATIONDIR mkdir -p $TRANSLATIONDIR - tar cvf translations.tar po + tar cvf translations.tar po/*/*/*.mo cd $TRANSLATIONDIR/.. && tar xvf $OPENSCADDIR/translations.tar && cd $OPENSCADDIR rm -f translations.tar fi diff --git a/src/QGLView.cc b/src/QGLView.cc index e26673b1..65410615 100644 --- a/src/QGLView.cc +++ b/src/QGLView.cc @@ -24,6 +24,7 @@ * */ +#include "qtgettext.h" #include "QGLView.h" #include "Preferences.h" #include "renderer.h" diff --git a/src/openscad.cc b/src/openscad.cc index 433f9aa1..e15d8358 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -624,6 +624,12 @@ int main(int argc, char **argv) #else PlatformUtils::ensureStdIO(); #endif + + setlocale(LC_ALL,""); + bindtextdomain("openscad","./po"); + bind_textdomain_codeset("openscad", "UTF-8"); + textdomain("openscad"); + #ifdef ENABLE_CGAL // Causes CGAL errors to abort directly instead of throwing exceptions // (which we don't catch). This gives us stack traces without rerunning in gdb. diff --git a/src/qtgettext.h b/src/qtgettext.h index 0c658606..eac628a5 100644 --- a/src/qtgettext.h +++ b/src/qtgettext.h @@ -3,10 +3,16 @@ // see doc/translation.txt -#include "printutils.h" -#include -#include +// MinGW defines sprintf to libintl_sprintf which breaks usage of the +// Qt sprintf in QString. This is skipped if sprintf and _GL_STDIO_H +// is already defined, so the workaround defines sprintf as itself. +#ifdef __MINGW32__ +#define _GL_STDIO_H +#define sprintf sprintf +#endif + #include +#include "printutils.h" inline QString _( const char *msgid, int category ) { From ae2d19241e352b16f3f5e92cfe082a9a921e6101 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:25:52 +0200 Subject: [PATCH 007/263] Use application resource path to locate the translation files. --- src/FontCache.cc | 1 + src/openscad.cc | 22 +++++++++++++++++++++- src/parsersettings.cc | 18 +++++++++++++++++- src/parsersettings.h | 22 ++++++++++++++++++++-- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/FontCache.cc b/src/FontCache.cc index 8f7beee5..1d2546f8 100644 --- a/src/FontCache.cc +++ b/src/FontCache.cc @@ -30,6 +30,7 @@ #include #include +#include "boosty.h" #include "FontCache.h" #include "PlatformUtils.h" #include "parsersettings.h" diff --git a/src/openscad.cc b/src/openscad.cc index e15d8358..ac290c73 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -155,6 +155,23 @@ static void info() exit(0); } +/** + * Initialize gettext. This must be called after the appliation path was + * determined so we can lookup the resource path for the language translation + * files. + */ +void localization_init() { + fs::path po_dir = get_resource_dir("po"); + if (fs::is_directory(po_dir)) { + setlocale(LC_ALL,""); + bindtextdomain("openscad", po_dir.string().c_str()); + bind_textdomain_codeset("openscad", "UTF-8"); + textdomain("openscad"); + } else { + PRINT("Could not initialize localization."); + } +} + Camera get_camera(po::variables_map vm) { Camera camera; @@ -258,6 +275,8 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c #endif PlatformUtils::registerApplicationPath(application_path); parser_init(PlatformUtils::applicationPath()); + localization_init(); + Tree tree; #ifdef ENABLE_CGAL GeometryEvaluator geomevaluator(tree); @@ -550,7 +569,8 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha const QString &app_path = app.applicationDirPath(); PlatformUtils::registerApplicationPath(app_path.toLocal8Bit().constData()); - parser_init(PlatformUtils::applicationPath()); + parser_init(PlatformUtils::applicationPath()); + localization_init(); #ifdef Q_OS_MAC installAppleEventHandlers(); diff --git a/src/parsersettings.cc b/src/parsersettings.cc index f8437f07..6390def4 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -7,13 +7,28 @@ namespace fs = boost::filesystem; +static std::string applicationdir; std::vector librarypath; -void add_librarydir(const std::string &libdir) +static void add_librarydir(const std::string &libdir) { librarypath.push_back(libdir); } +fs::path get_resource_dir(const std::string &resource_folder) +{ + if (!fs::is_directory(applicationdir)) { + return fs::path(); + } + + fs::path resource_dir = fs::path(applicationdir) / resource_folder; + if (!fs::is_directory(resource_dir)) { + return fs::path(); + } + + return resource_dir; +} + /*! Searces for the given file in library paths and returns the full path if found. Returns an empty path if file cannot be found or filename is a directory. @@ -91,6 +106,7 @@ fs::path find_valid_path(const fs::path &sourcepath, void parser_init(const std::string &applicationpath) { + applicationdir = applicationpath; // Add paths from OPENSCADPATH before adding built-in paths const char *openscadpaths = getenv("OPENSCADPATH"); if (openscadpaths) { diff --git a/src/parsersettings.h b/src/parsersettings.h index ab9d62bb..8ae7730b 100644 --- a/src/parsersettings.h +++ b/src/parsersettings.h @@ -1,12 +1,30 @@ #pragma once #include -#include "boosty.h" +#include + +namespace fs = boost::filesystem; extern int parser_error_pos; +/** + * Initialize application an library path. + * + * @param applicationpath path of the application binary, this is usually + * derived from the Qt application object. If Qt is disabled, argv[0] is used. + */ void parser_init(const std::string &applicationpath); -void add_librarydir(const std::string &libdir); + +/** + * Return a path to specific resources relative to the application binary. + * This is used to find resources bundled with the application, e.g. the + * translation files for the gettext library. + * + * @param folder subfolder for the resources (e.g. "po"). + * @return the resource path. + */ +fs::path get_resource_dir(const std::string &resource_folder); + fs::path search_libs(const fs::path &localpath); fs::path find_valid_path(const fs::path &sourcepath, const fs::path &localpath, From d620c8f40b07c49f54bafcc02202b29769262f3e Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:28:08 +0200 Subject: [PATCH 008/263] Allow localization to be enabled/disabled by configuration settings. This is only the logic to check the settings, no GUI. Changing the setting requires a restart as disabling localization simply skips the call to bindtextdomain() at the application start. --- src/Preferences.cc | 1 + src/openscad.cc | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index a48314ea..0e7e063c 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -104,6 +104,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->defaultmap["advanced/mdi"] = true; this->defaultmap["advanced/undockableWindows"] = false; this->defaultmap["launcher/showOnStartup"] = true; + this->defaultmap["advanced/localization"] = false; // Toolbar QActionGroup *group = new QActionGroup(this); diff --git a/src/openscad.cc b/src/openscad.cc index ac290c73..2ca899b4 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -505,6 +505,7 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets) #endif // MINGW64/MINGW32/MSCVER #include "MainWindow.h" #include "launchingscreen.h" +#include "qsettings.h" #ifdef __APPLE__ #include "EventFilter.h" #endif @@ -570,7 +571,10 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha PlatformUtils::registerApplicationPath(app_path.toLocal8Bit().constData()); parser_init(PlatformUtils::applicationPath()); - localization_init(); + QSettings settings; + if (settings.value("advanced/localization", false).toBool()) { + localization_init(); + } #ifdef Q_OS_MAC installAppleEventHandlers(); @@ -595,7 +599,6 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha inputFiles.push_back(""); } - QSettings settings; QVariant showOnStartup = settings.value("launcher/showOnStartup"); if (noInputFiles && (showOnStartup.isNull() || showOnStartup.toBool())) { LaunchingScreen *launcher = new LaunchingScreen(); From ee4b2ffef5bb9d160259a00b4ce9bb53af386c81 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:29:29 +0200 Subject: [PATCH 009/263] Fix library references and translation scripts on MacOS. --- common.pri | 1 + gettext.pri | 28 ++++++++++++++++++++++++++++ openscad.pro | 1 + scripts/translation-update.sh | 13 +++++++++---- 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 gettext.pri diff --git a/common.pri b/common.pri index 1a23b61a..98aa52e3 100644 --- a/common.pri +++ b/common.pri @@ -12,6 +12,7 @@ include(glew.pri) include(eigen.pri) include(boost.pri) include(glib-2.0.pri) +include(gettext.pri) include(sparkle.pri) include(harfbuzz.pri) include(freetype.pri) diff --git a/gettext.pri b/gettext.pri new file mode 100644 index 00000000..84fffa55 --- /dev/null +++ b/gettext.pri @@ -0,0 +1,28 @@ +# Detect gettext, then use this priority list to determine +# which library to use: +# +# Priority +# 1. GETTEXT_INCLUDEPATH / GETTEXT_LIBPATH (qmake parameter, not checked it given on commandline) +# 2. OPENSCAD_LIBRARIES (environment variable) +# 3. system's standard include paths from pkg-config + +gettext { + +# read environment variables +OPENSCAD_LIBRARIES_DIR = $$(OPENSCAD_LIBRARIES) +GETTEXT_DIR = $$(GETTEXTDIR) + +macx: { + isEmpty(GETTEXT_INCLUDEPATH) { + !isEmpty(OPENSCAD_LIBRARIES_DIR) { + GETTEXT_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include + GETTEXT_LIBPATH = $$OPENSCAD_LIBRARIES_DIR/lib + } + } + GETTEXT_CXXFLAGS=-I$$GETTEXT_INCLUDEPATH + GETTEXT_LIBS=-L$$GETTEXT_LIBPATH -lintl -liconv +} + +QMAKE_CXXFLAGS += $$GETTEXT_CXXFLAGS +LIBS += $$GETTEXT_LIBS +} diff --git a/openscad.pro b/openscad.pro index e9f6adc2..5d36d0d9 100644 --- a/openscad.pro +++ b/openscad.pro @@ -182,6 +182,7 @@ CONFIG += glib-2.0 CONFIG += harfbuzz CONFIG += freetype CONFIG += fontconfig +CONFIG += gettext #Uncomment the following line to enable the QScintilla editor CONFIG += scintilla diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index b2db9de9..adff93f1 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -15,21 +15,21 @@ updatepot() OPTS=$OPTS' --default-domain=openscad' OPTS=$OPTS' --keyword=_' OPTS=$OPTS' --files-from=./po/POTFILES.in' - cmd='xgettext '$OPTS' -o ./po/openscad.pot' + cmd="${GETTEXT_PATH}xgettext "$OPTS' -o ./po/openscad.pot' echo $cmd $cmd if [ ! $? = 0 ]; then echo error running xgettext exit 1 fi - sed -i s/"CHARSET"/"UTF-8"/g ./po/openscad.pot + sed -e s/"CHARSET"/"UTF-8"/g ./po/openscad.pot > ./po/openscad.pot.new && mv ./po/openscad.pot.new ./po/openscad.pot } updatepo() { for LANGCODE in `cat ./po/LINGUAS | grep -v "#"`; do OPTS='--update --backup=t' - cmd='msgmerge '$OPTS' ./po/'$LANGCODE'.po ./po/openscad.pot' + cmd="$GETTEXT_PATH"'msgmerge '$OPTS' ./po/'$LANGCODE'.po ./po/openscad.pot' echo $cmd $cmd if [ ! $? = 0 ]; then @@ -44,7 +44,7 @@ updatemo() for LANGCODE in `cat po/LINGUAS | grep -v "#"`; do mkdir -p ./po/$LANGCODE/LC_MESSAGES OPTS='-c -v' - cmd='msgfmt '$OPTS' -o ./po/'$LANGCODE'/LC_MESSAGES/openscad.mo ./po/'$LANGCODE'.po' + cmd="$GETTEXT_PATH"'msgfmt '$OPTS' -o ./po/'$LANGCODE'/LC_MESSAGES/openscad.mo ./po/'$LANGCODE'.po' echo $cmd $cmd if [ ! $? = 0 ]; then @@ -54,6 +54,11 @@ updatemo() done } +GETTEXT_PATH="" +if [ "x$OPENSCAD_LIBRARIES" != x ]; then + GETTEXT_PATH="$OPENSCAD_LIBRARIES/bin/" +fi + if [ "x$1" = xupdatemo ]; then updatemo else From a512a6442e48958d1b8ec1c4a05974f64aa23cb4 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 7 Jan 2014 19:47:31 +0100 Subject: [PATCH 010/263] Handle the MacOS application layout when finding resources. --- src/parsersettings.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 6390def4..8a24ecdf 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -20,8 +20,16 @@ fs::path get_resource_dir(const std::string &resource_folder) if (!fs::is_directory(applicationdir)) { return fs::path(); } + + fs::path basepath(applicationdir); +#ifdef __APPLE__ + fs::path bundlepath = basepath.parent_path().parent_path(); + if (bundlepath.filename().string() == "OpenSCAD.app") { + basepath = bundlepath / "Contents" / "Resources"; + } +#endif - fs::path resource_dir = fs::path(applicationdir) / resource_folder; + fs::path resource_dir = basepath / resource_folder; if (!fs::is_directory(resource_dir)) { return fs::path(); } From afd52b3075514031c7d467b3b90644287ead5892 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:31:29 +0200 Subject: [PATCH 011/263] Fix compilation of test cases. --- src/parsersettings.cc | 3 +++ tests/cgalcachetest.cc | 1 - tests/csgtexttest.cc | 1 - tests/modulecachetest.cc | 1 - 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 8a24ecdf..189f6562 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -22,6 +22,9 @@ fs::path get_resource_dir(const std::string &resource_folder) } fs::path basepath(applicationdir); +#ifdef OPENSCAD_TESTING + basepath = ".."; +#endif #ifdef __APPLE__ fs::path bundlepath = basepath.parent_path().parent_path(); if (bundlepath.filename().string() == "OpenSCAD.app") { diff --git a/tests/cgalcachetest.cc b/tests/cgalcachetest.cc index 97aa5be1..0d434cac 100644 --- a/tests/cgalcachetest.cc +++ b/tests/cgalcachetest.cc @@ -117,7 +117,6 @@ int main(int argc, char **argv) currentdir = boosty::stringy(fs::current_path()); parser_init(boosty::stringy(fs::path(argv[0]).branch_path())); - add_librarydir(boosty::stringy(fs::path(argv[0]).branch_path() / "../libraries")); ModuleContext top_ctx; top_ctx.registerBuiltin(); diff --git a/tests/csgtexttest.cc b/tests/csgtexttest.cc index 97902f60..95912f63 100644 --- a/tests/csgtexttest.cc +++ b/tests/csgtexttest.cc @@ -78,7 +78,6 @@ int main(int argc, char **argv) currentdir = boosty::stringy( fs::current_path() ); parser_init(boosty::stringy(fs::path(argv[0]).branch_path())); - add_librarydir(boosty::stringy(fs::path(argv[0]).branch_path() / "../libraries")); ModuleContext top_ctx; top_ctx.registerBuiltin(); diff --git a/tests/modulecachetest.cc b/tests/modulecachetest.cc index 5531461c..d996cd84 100644 --- a/tests/modulecachetest.cc +++ b/tests/modulecachetest.cc @@ -74,7 +74,6 @@ int main(int argc, char **argv) currentdir = boosty::stringy( fs::current_path() ); parser_init(boosty::stringy(fs::path(argv[0]).branch_path())); - add_librarydir(boosty::stringy(fs::path(argv[0]).branch_path() / "../libraries")); ModuleContext top_ctx; top_ctx.registerBuiltin(); From cfe14254d4f03bb870df4178bb0f3f0a285f7013 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:32:54 +0200 Subject: [PATCH 012/263] Handle resource layout on linux and add translation files to openscad.pro. --- openscad.pro | 20 +++++++++++++++++++- src/openscad.cc | 1 + src/parsersettings.cc | 38 +++++++++++++++++++++++++++----------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/openscad.pro b/openscad.pro index 5d36d0d9..d16da5d3 100644 --- a/openscad.pro +++ b/openscad.pro @@ -8,7 +8,12 @@ # OPENCSGDIR # OPENSCAD_LIBRARIES # -# Please see the 'Building' sections of the OpenSCAD user manual +# qmake Variables to define the installation: +# +# PREFIX defines the base installation folder +# LOCALE_PREFIX can overwrite the location of the gettext message catalogs +# +# Please see the 'Building' sections of the OpenSCAD user manual # for updated tips & workarounds. # # http://en.wikibooks.org/wiki/OpenSCAD_User_Manual @@ -473,6 +478,19 @@ isEmpty(PREFIX):PREFIX = /usr/local target.path = $$PREFIX/bin/ INSTALLS += target +LINGUAS = $$cat(po/LINGUAS) +isEmpty(LOCALE_PREFIX):LOCALE_PREFIX = $$PREFIX/share/openscad/po +for(language, LINGUAS) { + catalog = po/$$language/LC_MESSAGES/openscad.mo + exists($$catalog) { + translation_path = translation_$${language}.path + translation_files = translation_$${language}.files + $$translation_path = $$LOCALE_PREFIX/$$language/LC_MESSAGES/ + $$translation_files = $$catalog + INSTALLS += translation_$$language + } +} + examples.path = $$PREFIX/share/openscad/examples/ examples.files = examples/* INSTALLS += examples diff --git a/src/openscad.cc b/src/openscad.cc index 2ca899b4..25a2c392 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -571,6 +571,7 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha PlatformUtils::registerApplicationPath(app_path.toLocal8Bit().constData()); parser_init(PlatformUtils::applicationPath()); + QSettings settings; if (settings.value("advanced/localization", false).toBool()) { localization_init(); diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 189f6562..b47beccc 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -22,22 +22,38 @@ fs::path get_resource_dir(const std::string &resource_folder) } fs::path basepath(applicationdir); + + fs::path paths[] = { +#if __APPLE__ + // Application layout when installed on MacOS + basepath.parent_path().parent_path() / "Contents" / "Resources", +#endif +#ifdef __unix__ + // Different unix installation layouts are possible, this + // tries to capture the most obvious cases. + basepath.parent_path() / "share" / "openscad", + basepath.parent_path().parent_path() / "share" / "openscad", + fs::path("..") / "..", +#endif #ifdef OPENSCAD_TESTING - basepath = ".."; -#endif -#ifdef __APPLE__ - fs::path bundlepath = basepath.parent_path().parent_path(); - if (bundlepath.filename().string() == "OpenSCAD.app") { - basepath = bundlepath / "Contents" / "Resources"; - } + // Used when running the test cases from source code layout. + fs::path(".."), #endif + // Try to fall back to path relative to the executable and + // relative to the current working directory. + basepath, + fs::path("."), + fs::path(), // end of list marker + }; - fs::path resource_dir = basepath / resource_folder; - if (!fs::is_directory(resource_dir)) { - return fs::path(); + for (int a = 0;!paths[a].empty();a++) { + fs::path resource_dir = paths[a] / resource_folder; + if (fs::is_directory(resource_dir)) { + return resource_dir; + } } - return resource_dir; + return fs::path(); } /*! From 8f2491cd0a6a84c91b75232129181519fda18615 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:34:08 +0200 Subject: [PATCH 013/263] Support linux packaging structure with shared locale folder. --- openscad.pro | 11 ++++++++++- scripts/release-common.sh | 10 +++++----- src/openscad.cc | 11 ++++++++--- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/openscad.pro b/openscad.pro index d16da5d3..bbb4f71f 100644 --- a/openscad.pro +++ b/openscad.pro @@ -11,8 +11,15 @@ # qmake Variables to define the installation: # # PREFIX defines the base installation folder +# # LOCALE_PREFIX can overwrite the location of the gettext message catalogs # +# For linux packages that want to install the localization files into +# a folder shared by all packages, specify the LOCALE_PREFIX which will +# force usage of the given folder. +# The default layout is created by: LOCALE_PREFIX=/share/locale +# where is the base installation folder. +# # Please see the 'Building' sections of the OpenSCAD user manual # for updated tips & workarounds. # @@ -479,7 +486,9 @@ target.path = $$PREFIX/bin/ INSTALLS += target LINGUAS = $$cat(po/LINGUAS) -isEmpty(LOCALE_PREFIX):LOCALE_PREFIX = $$PREFIX/share/openscad/po + +!isEmpty(LOCALE_PREFIX): DEFINES += LOCALE_PREFIX=\'\"$$LOCALE_PREFIX\"\' +isEmpty(LOCALE_PREFIX): LOCALE_PREFIX = $$PREFIX/share/openscad/locale for(language, LINGUAS) { catalog = po/$$language/LC_MESSAGES/openscad.mo exists($$catalog) { diff --git a/scripts/release-common.sh b/scripts/release-common.sh index e06646a2..88f4f285 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -326,14 +326,14 @@ case $OS in EXAMPLESDIR=OpenSCAD.app/Contents/Resources/examples LIBRARYDIR=OpenSCAD.app/Contents/Resources/libraries FONTDIR=OpenSCAD.app/Contents/Resources/fonts - TRANSLATIONDIR=OpenSCAD.app/Contents/Resources/po + TRANSLATIONDIR=OpenSCAD.app/Contents/Resources/locale ;; UNIX_CROSS_WIN) cd $OPENSCADDIR EXAMPLESDIR=$DEPLOYDIR/openscad-$VERSION/examples/ LIBRARYDIR=$DEPLOYDIR/openscad-$VERSION/libraries/ FONTDIR=$DEPLOYDIR/openscad-$VERSION/fonts/ - TRANSLATIONDIR=$DEPLOYDIR/openscad-$VERSION/po/ + TRANSLATIONDIR=$DEPLOYDIR/openscad-$VERSION/locale/ rm -rf $DEPLOYDIR/openscad-$VERSION mkdir $DEPLOYDIR/openscad-$VERSION ;; @@ -341,7 +341,7 @@ case $OS in EXAMPLESDIR=openscad-$VERSION/examples/ LIBRARYDIR=openscad-$VERSION/libraries/ FONTDIR=openscad-$VERSION/fonts/ - TRANSLATIONDIR=openscad-$VERSION/po/ + TRANSLATIONDIR=openscad-$VERSION/locale/ rm -rf openscad-$VERSION mkdir openscad-$VERSION ;; @@ -384,8 +384,8 @@ fi if [ -n $TRANSLATIONDIR ]; then echo $TRANSLATIONDIR mkdir -p $TRANSLATIONDIR - tar cvf translations.tar po/*/*/*.mo - cd $TRANSLATIONDIR/.. && tar xvf $OPENSCADDIR/translations.tar && cd $OPENSCADDIR + cd po && tar cvf $OPENSCADDIR/translations.tar */*/*.mo && cd $OPENSCADDIR + cd $TRANSLATIONDIR && tar xvf $OPENSCADDIR/translations.tar && cd $OPENSCADDIR rm -f translations.tar fi diff --git a/src/openscad.cc b/src/openscad.cc index 25a2c392..12d20915 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -161,10 +161,15 @@ static void info() * files. */ void localization_init() { - fs::path po_dir = get_resource_dir("po"); - if (fs::is_directory(po_dir)) { +#ifdef LOCALE_PREFIX + std::string locale_path(LOCALE_PREFIX); +#else + fs::path po_dir = get_resource_dir("locale"); + std::string locale_path(po_dir.string()); +#endif + if (fs::is_directory(locale_path)) { setlocale(LC_ALL,""); - bindtextdomain("openscad", po_dir.string().c_str()); + bindtextdomain("openscad", locale_path.c_str()); bind_textdomain_codeset("openscad", "UTF-8"); textdomain("openscad"); } else { From e07d1d0320d379c86466ca78fba4bad4ce4a5ebf Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:34:45 +0200 Subject: [PATCH 014/263] Fix windows installer. --- scripts/installer.nsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/installer.nsi b/scripts/installer.nsi index dbc68bcd..9e243482 100644 --- a/scripts/installer.nsi +++ b/scripts/installer.nsi @@ -13,7 +13,7 @@ File openscad.com File /r /x mingw-cross-env examples File /r /x mingw-cross-env libraries File /r /x mingw-cross-env fonts -File /r /x mingw-cross-env po +File /r /x mingw-cross-env locale ${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File" CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe WriteUninstaller $INSTDIR\Uninstall.exe @@ -30,7 +30,7 @@ DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Unins RMDir /r $INSTDIR\fonts RMDir /r $INSTDIR\examples RMDir /r $INSTDIR\libraries\mcad -RMDir /r $INSTDIR\po +RMDir /r $INSTDIR\locale Delete $INSTDIR\libraries\boxes.scad Delete $INSTDIR\libraries\shapes.scad RMDir $INSTDIR\libraries From 54a6f2addbd18b993f2e623b43359878bc6f5c35 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 9 Jan 2014 19:34:42 +0100 Subject: [PATCH 015/263] Integrate message catalog creation into build process. --- .gitignore | 1 + openscad.pro | 10 +- po/POTFILES.in | 77 ------- po/openscad.pot | 400 +++++++++++++++++++--------------- scripts/generate-potfiles.sh | 16 ++ scripts/translation-update.sh | 2 +- 6 files changed, 254 insertions(+), 252 deletions(-) delete mode 100644 po/POTFILES.in create mode 100755 scripts/generate-potfiles.sh diff --git a/.gitignore b/.gitignore index 96e60faf..862b173e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ parser_yacc.h /OpenSCAD.app */#*# /po/*/*/*.mo +/po/POTFILES /nbproject /openscad /tests/openscad_nogui diff --git a/openscad.pro b/openscad.pro index bbb4f71f..c41e0aca 100644 --- a/openscad.pro +++ b/openscad.pro @@ -485,17 +485,23 @@ isEmpty(PREFIX):PREFIX = /usr/local target.path = $$PREFIX/bin/ INSTALLS += target -LINGUAS = $$cat(po/LINGUAS) - !isEmpty(LOCALE_PREFIX): DEFINES += LOCALE_PREFIX=\'\"$$LOCALE_PREFIX\"\' isEmpty(LOCALE_PREFIX): LOCALE_PREFIX = $$PREFIX/share/openscad/locale + +# Run translation update scripts as last step after linking the target +QMAKE_POST_LINK += ./scripts/generate-potfiles.sh > po/POTFILES ; ./scripts/translation-update.sh + +# Create install targets for the languages defined in LINGUAS +LINGUAS = $$cat(po/LINGUAS) for(language, LINGUAS) { catalog = po/$$language/LC_MESSAGES/openscad.mo exists($$catalog) { translation_path = translation_$${language}.path translation_files = translation_$${language}.files + translation_depends = translation_$${language}.depends $$translation_path = $$LOCALE_PREFIX/$$language/LC_MESSAGES/ $$translation_files = $$catalog + $$translation_depends = po/$${language}.po INSTALLS += translation_$$language } } diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index 07a3472f..00000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,77 +0,0 @@ -# see doc/translation.txt - -# ui_xxxx.h files created by qt's uic when make is run. -# if you add new .ui files, add their .h counterpart here -objects/ui_AboutDialog.h -objects/ui_OpenCSGWarningDialog.h -objects/ui_ProgressWidget.h -objects/ui_MainWindow.h -objects/ui_Preferences.h - -# C++ files -src/AppleEvents.cc -src/builtin.cc -src/cgaladv.cc -src/cgaladv_minkowski2.cc -src/CGALCache.cc -src/CGALEvaluator.cc -src/CGAL_Nef_polyhedron.cc -src/CGAL_Nef_polyhedron_DxfData.cc -src/CGALRenderer.cc -src/cgalutils.cc -src/cgalworker.cc -src/color.cc -src/context.cc -src/control.cc -src/csgops.cc -src/csgterm.cc -src/CSGTermEvaluator.cc -src/csgtermnormalizer.cc -src/dxfdata.cc -src/dxfdim.cc -src/dxftess.cc -src/dxftess-cgal.cc -src/dxftess-glu.cc -src/editor.cc -src/export.cc -src/expr.cc -src/func.cc -src/glview.cc -src/handle_dep.cc -src/highlighter.cc -src/import.cc -src/linalg.cc -src/linearextrude.cc -src/mainwin.cc -src/mathc99.cc -src/ModuleCache.cc -src/module.cc -src/node.cc -src/nodedumper.cc -src/OpenCSGRenderer.cc -src/OpenCSGWarningDialog.cc -src/openscad.cc -src/parsersettings.cc -src/PolySetCache.cc -src/polyset.cc -src/PolySetCGALEvaluator.cc -src/PolySetEvaluator.cc -src/Preferences.cc -src/primitives.cc -src/printutils.cc -src/progress.cc -src/ProgressWidget.cc -src/projection.cc -src/render.cc -src/renderer.cc -src/rendersettings.cc -src/rotateextrude.cc -src/stl-utils.cc -src/surface.cc -src/svg.cc -src/ThrownTogetherRenderer.cc -src/transform.cc -src/traverser.cc -src/Tree.cc -src/value.cc -src/version_check.cc diff --git a/po/openscad.pot b/po/openscad.pot index 66b595b3..a4a0f173 100644 --- a/po/openscad.pot +++ b/po/openscad.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: OpenSCAD 2014.01.06\n" +"Project-Id-Version: OpenSCAD 2014.01.09\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 21:45+0100\n" +"POT-Creation-Date: 2014-01-09 19:02+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,44 +21,6 @@ msgstr "" msgid "About OpenSCAD" msgstr "" -#: objects/ui_OpenCSGWarningDialog.h:86 -msgid "OpenGL Warning" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 -msgid "Close" -msgstr "" - -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "" - #: objects/ui_MainWindow.h:470 msgid "MainWindow" msgstr "" @@ -411,6 +373,10 @@ msgstr "" msgid "Export as DXF..." msgstr "" +#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "" + #: objects/ui_MainWindow.h:559 msgid "Ctrl+W" msgstr "" @@ -515,6 +481,32 @@ msgstr "" msgid "&Help" msgstr "" +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + #: objects/ui_Preferences.h:515 msgid "3D View" msgstr "" @@ -623,6 +615,53 @@ msgstr "" msgid "toolBar" msgstr "" +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: src/AboutDialog.h:16 +msgid "About OpenSCAD " +msgstr "" + +#: src/cache.h:181 +msgid "Trimming cache: %1% (%2% bytes)" +msgstr "" + +#: src/CGAL_Nef3_workaround.h:255 +msgid "ERROR: CGAL NefPolyhedron Triangulation failed" +msgstr "" + +#: src/CsgInfo.h:48 +msgid "Error: CSG generation failed! (no top level object found)" +msgstr "" + +#: src/CsgInfo.h:53 src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "" + +#: src/CsgInfo.h:60 src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "" + +#: src/CsgInfo.h:64 src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "" + +#: src/CsgInfo.h:69 +#, c-format +msgid "Compiling highlights (%i CSG Trees)..." +msgstr "" + +#: src/CsgInfo.h:79 +#, c-format +msgid "Compiling background (%i CSG Trees)..." +msgstr "" + #: src/cgaladv_minkowski2.cc:43 msgid " vertices:" msgstr "" @@ -745,7 +784,7 @@ msgstr "" msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." msgstr "" -#: src/CGAL_Nef_polyhedron.cc:114 +#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 #, c-format msgid "ERROR: %s" msgstr "" @@ -808,21 +847,21 @@ msgstr "" msgid "ModuleContext %p (%p) for %s inst (%p)" msgstr "" -#: src/context.cc:158 +#: src/context.cc:158 src/evalcontext.cc:40 #, c-format msgid "Context: %p (%p)" msgstr "" -#: src/context.cc:159 +#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 #, c-format msgid " document path: %s" msgstr "" -#: src/context.cc:163 +#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 msgid " module args:" msgstr "" -#: src/context.cc:170 +#: src/context.cc:170 src/modcontext.cc:159 msgid " vars:" msgstr "" @@ -863,7 +902,7 @@ msgstr "" msgid "WARNING: Bad range parameter for children: too many elements (%lu)." msgstr "" -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 #, c-format msgid "" "WARNING: Normalized tree is growing past %d elements. Aborting " @@ -944,6 +983,19 @@ msgstr "" msgid "GLU tesselation error %s" msgstr "" +#: src/evalcontext.cc:38 +#, c-format +msgid "EvalContext %p (%p) for %s inst (%p)" +msgstr "" + +#: src/evalcontext.cc:43 +msgid " eval args:" +msgstr "" + +#: src/evalcontext.cc:48 +msgid " children:" +msgstr "" + #: src/export.cc:48 msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" msgstr "" @@ -957,6 +1009,22 @@ msgstr "" msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" msgstr "" +#: src/feature.cc:21 +msgid "Enable the concat() function." +msgstr "" + +#: src/feature.cc:60 +#, c-format +msgid "WARNING: Ignoring request to enable unknown feature '%s'." +msgstr "" + +#: src/fileutils.cc:25 +#, c-format +msgid "" +"WARNING: Imported file (%s) found in document root instead of relative to " +"the importing module. This behavior is deprecated" +msgstr "" + #: src/func.cc:503 src/func.cc:536 #, c-format msgid " WARNING: search term not found: \"%s\"" @@ -984,79 +1052,6 @@ msgid "" "stack" msgstr "" -#: src/glview.cc:149 -#, c-format -msgid "GLEW Error: %s\n" -msgstr "" - -#: src/glview.cc:161 -#, c-format -msgid "" -"GLEW version %s\n" -"OpenGL version %s\n" -"%s (%s)\n" -"\n" -"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" -"Extensions:\n" -"%s\n" -msgstr "" - -#: src/glview.cc:304 -#, c-format -msgid "" -"OpenGL Program Linker Error:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:310 -#, c-format -msgid "" -"OpenGL Program Link OK:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:315 -#, c-format -msgid "" -"OpenGL Program Validation results:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:329 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" - -#: src/glview.cc:332 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" -msgstr "" - -#: src/glview.cc:335 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" -msgstr "" - -#: src/glview.cc:339 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" - -#: src/glview.cc:537 -#, c-format -msgid "" -"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " -"distance = %.2f" -msgstr "" - #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" @@ -1161,14 +1156,6 @@ msgstr "" msgid "CSG generation cancelled." msgstr "" -#: src/mainwin.cc:821 -msgid "Compiling design (CSG Products normalization)..." -msgstr "" - -#: src/mainwin.cc:833 -msgid "WARNING: CSG normalization resulted in an empty tree" -msgstr "" - #: src/mainwin.cc:839 #, c-format msgid "Compiling highlights (%d CSG Trees)..." @@ -1188,11 +1175,6 @@ msgstr "" msgid "WARNING: OpenCSG rendering has been disabled." msgstr "" -#: src/mainwin.cc:868 -#, c-format -msgid "Normalized CSG tree has %d elements" -msgstr "" - #: src/mainwin.cc:878 msgid "CSG generation finished." msgstr "" @@ -1447,9 +1429,9 @@ msgid "No filename specified. %s export aborted." msgstr "" #: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 -#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 -#: src/openscad.cc:418 +#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 +#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 +#: src/openscad.cc:442 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" @@ -1541,6 +1523,33 @@ msgid "" "Do you want to save your changes?" msgstr "" +#: src/modcontext.cc:100 +#, c-format +msgid "WARNING: Experimental builtin function '%s' is not enabled." +msgstr "" + +#: src/modcontext.cc:113 +#, c-format +msgid "WARNING: Experimental builtin module '%s' is not enabled." +msgstr "" + +#: src/modcontext.cc:118 +#, c-format +msgid "" +"DEPRECATED: The %s() module will be removed in future releases. Use %s() " +"instead." +msgstr "" + +#: src/modcontext.cc:145 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p) " +msgstr "" + +#: src/modcontext.cc:147 +#, c-format +msgid "ModuleContext: %p (%p)" +msgstr "" + #: src/ModuleCache.cc:70 #, c-format msgid "Recompiling cached library: %s (%s)" @@ -1594,147 +1603,152 @@ msgstr "" msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" msgstr "" -#: src/openscad.cc:160 +#: src/openscad.cc:182 msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" msgstr "" -#: src/openscad.cc:161 +#: src/openscad.cc:183 msgid "or 6 numbers for Vector Camera\n" msgstr "" -#: src/openscad.cc:177 +#: src/openscad.cc:199 msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" msgstr "" -#: src/openscad.cc:188 +#: src/openscad.cc:210 msgid "Need 2 numbers for imgsize\n" msgstr "" -#: src/openscad.cc:236 -#, c-format -msgid "Unknown suffix for output file %s\n" -msgstr "" - #: src/openscad.cc:260 #, c-format +msgid "Unknown suffix for output file %s\n" +msgstr "" + +#: src/openscad.cc:284 +#, c-format msgid "Can't open input file '%s'!\n" msgstr "" -#: src/openscad.cc:269 +#: src/openscad.cc:293 #, c-format msgid "Can't parse file '%s'!\n" msgstr "" -#: src/openscad.cc:351 +#: src/openscad.cc:375 #, c-format msgid "Output file:%s\n" msgstr "" -#: src/openscad.cc:352 +#: src/openscad.cc:376 msgid "Sorry, don't know how to write deps for that file type. Exiting\n" msgstr "" -#: src/openscad.cc:357 +#: src/openscad.cc:381 msgid "error writing deps" msgstr "" -#: src/openscad.cc:364 src/openscad.cc:383 +#: src/openscad.cc:388 src/openscad.cc:407 msgid "Current top level object is not a 3D object.\n" msgstr "" -#: src/openscad.cc:368 src/openscad.cc:387 +#: src/openscad.cc:392 src/openscad.cc:411 msgid "Object isn't a valid 2-manifold! Modify your design.\n" msgstr "" -#: src/openscad.cc:402 +#: src/openscad.cc:426 msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:584 +#: src/openscad.cc:591 msgid "Allowed options" msgstr "" -#: src/openscad.cc:586 +#: src/openscad.cc:593 msgid "help message" msgstr "" -#: src/openscad.cc:587 +#: src/openscad.cc:594 msgid "print the version" msgstr "" -#: src/openscad.cc:588 +#: src/openscad.cc:595 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:589 +#: src/openscad.cc:596 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:590 +#: src/openscad.cc:597 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:598 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:592 +#: src/openscad.cc:599 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:600 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:601 msgid "out-file" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:602 msgid "stl-file" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:603 msgid "dxf-file" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:604 msgid "deps-file" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:605 msgid "makefile" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:606 msgid "var=val" msgstr "" -#: src/openscad.cc:600 +#: src/openscad.cc:607 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:602 +#: src/openscad.cc:609 msgid "Hidden options" msgstr "" -#: src/openscad.cc:604 +#: src/openscad.cc:611 msgid "input file" msgstr "" -#: src/openscad.cc:638 +#: src/openscad.cc:645 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:643 +#: src/openscad.cc:650 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:700 +#: src/openscad.cc:707 msgid "Requested GUI mode but can't open display!\n" msgstr "" +#: src/PlatformUtils.cc:16 +#, c-format +msgid "ERROR: Cannot create %s" +msgstr "" + #: src/PolySetCache.cc:24 #, c-format msgid "PolySets in cache: %d" @@ -1889,6 +1903,48 @@ msgstr "" msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" msgstr "" +#: src/QGLView.cc:105 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" + +#: src/QGLView.cc:122 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:125 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:128 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/QGLView.cc:132 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/QGLView.cc:163 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + #: src/rotateextrude.cc:72 msgid "" "DEPRECATED: Support for reading files in rotate_extrude will be removed in " diff --git a/scripts/generate-potfiles.sh b/scripts/generate-potfiles.sh new file mode 100755 index 00000000..8414cc23 --- /dev/null +++ b/scripts/generate-potfiles.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Generate list of files for translation. The output is saved to po/POTFILES +# which is needed for the xgettext call. + +for ui in src/*.ui +do + UI="${ui#src/}" + UI="${UI%.ui}" + echo "objects/ui_$UI.h" +done + +for src in src/*.h src/*.cc +do + echo $src +done diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index adff93f1..9c4c8d60 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -14,7 +14,7 @@ updatepot() OPTS=$OPTS' --package-version='$VER OPTS=$OPTS' --default-domain=openscad' OPTS=$OPTS' --keyword=_' - OPTS=$OPTS' --files-from=./po/POTFILES.in' + OPTS=$OPTS' --files-from=./po/POTFILES' cmd="${GETTEXT_PATH}xgettext "$OPTS' -o ./po/openscad.pot' echo $cmd $cmd From 2a635f6797748a4d96e256b96ddb43ab36af6279 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 9 Jan 2014 19:38:46 +0100 Subject: [PATCH 016/263] Update translation files. --- po/de.po | 503 ++++++++++++++++++++++++++++++++----------------------- po/fr.po | 400 ++++++++++++++++++++++++------------------- po/ru.po | 398 ++++++++++++++++++++++++------------------- 3 files changed, 752 insertions(+), 549 deletions(-) diff --git a/po/de.po b/po/de.po index 26f46fa9..f8160a95 100644 --- a/po/de.po +++ b/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 21:19+0100\n" -"PO-Revision-Date: 2014-01-06 21:19+0100\n" +"POT-Creation-Date: 2014-01-09 18:17+0100\n" +"PO-Revision-Date: 2014-01-09 19:37+0100\n" "Last-Translator: Torsten Paul \n" "Language-Team: German\n" "Language: de\n" @@ -20,55 +20,7 @@ msgstr "" #: objects/ui_AboutDialog.h:51 msgid "About OpenSCAD" -msgstr "About OpenSCAD" - -#: objects/ui_OpenCSGWarningDialog.h:86 -msgid "OpenGL Warning" -msgstr "OpenGL Warning" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" -"\n" -"\n" -"

" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "Enable OpenCSG" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "Show this message again" - -#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 -msgid "Close" -msgstr "Schließen" - -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "Form" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "%v / %m" +msgstr "Über OpenSCAD" #: objects/ui_MainWindow.h:470 msgid "MainWindow" @@ -422,6 +374,10 @@ msgstr "Clear Recent" msgid "Export as DXF..." msgstr "DXF exportieren..." +#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "Schließen" + #: objects/ui_MainWindow.h:559 msgid "Ctrl+W" msgstr "Ctrl+W" @@ -526,6 +482,42 @@ msgstr "&Ansicht" msgid "&Help" msgstr "&Hilfe" +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "OpenGL Warning" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" +"\n" +"\n" +"

" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "Enable OpenCSG" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "Show this message again" + #: objects/ui_Preferences.h:515 msgid "3D View" msgstr "3D Ansicht" @@ -634,6 +626,53 @@ msgstr "PolySet Cache Größe" msgid "toolBar" msgstr "toolBar" +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "Form" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "%v / %m" + +#: src/AboutDialog.h:16 +msgid "About OpenSCAD " +msgstr "Über OpenSCAD" + +#: src/cache.h:181 +msgid "Trimming cache: %1% (%2% bytes)" +msgstr "Trimming cache: %1% (%2% bytes)" + +#: src/CGAL_Nef3_workaround.h:255 +msgid "ERROR: CGAL NefPolyhedron Triangulation failed" +msgstr "ERROR: CGAL NefPolyhedron Triangulation failed" + +#: src/CsgInfo.h:48 +msgid "Error: CSG generation failed! (no top level object found)" +msgstr "Error: CSG generation failed! (no top level object found)" + +#: src/CsgInfo.h:53 src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "Compiling design (CSG Products normalization)..." + +#: src/CsgInfo.h:60 src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "Normalized CSG tree has %d elements" + +#: src/CsgInfo.h:64 src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "WARNING: CSG normalization resulted in an empty tree" + +#: src/CsgInfo.h:69 +#, c-format +msgid "Compiling highlights (%i CSG Trees)..." +msgstr "Compiling highlights (%i CSG Trees)..." + +#: src/CsgInfo.h:79 +#, c-format +msgid "Compiling background (%i CSG Trees)..." +msgstr "Compiling background (%i CSG Trees)..." + #: src/cgaladv_minkowski2.cc:43 msgid " vertices:" msgstr " vertices:" @@ -762,7 +801,7 @@ msgstr "" msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." -#: src/CGAL_Nef_polyhedron.cc:114 +#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 #, c-format msgid "ERROR: %s" msgstr "ERROR: %s" @@ -827,21 +866,21 @@ msgstr "WARNING: Ignoring unknown module '%s'." msgid "ModuleContext %p (%p) for %s inst (%p)" msgstr "ModuleContext %p (%p) for %s inst (%p)" -#: src/context.cc:158 +#: src/context.cc:158 src/evalcontext.cc:40 #, c-format msgid "Context: %p (%p)" msgstr "Context: %p (%p)" -#: src/context.cc:159 +#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 #, c-format msgid " document path: %s" msgstr " document path: %s" -#: src/context.cc:163 +#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 msgid " module args:" msgstr " module args:" -#: src/context.cc:170 +#: src/context.cc:170 src/modcontext.cc:159 msgid " vars:" msgstr " vars:" @@ -885,7 +924,7 @@ msgstr "WARNING: Child index (%d) out of bounds (%d children)" msgid "WARNING: Bad range parameter for children: too many elements (%lu)." msgstr "WARNING: Bad range parameter for children: too many elements (%lu)." -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 #, c-format msgid "" "WARNING: Normalized tree is growing past %d elements. Aborting " @@ -971,6 +1010,19 @@ msgstr "WARNING: PolySet has degenerate polygon" msgid "GLU tesselation error %s" msgstr "GLU tesselation error %s" +#: src/evalcontext.cc:38 +#, c-format +msgid "EvalContext %p (%p) for %s inst (%p)" +msgstr "EvalContext %p (%p) for %s inst (%p)" + +#: src/evalcontext.cc:43 +msgid " eval args:" +msgstr " eval args:" + +#: src/evalcontext.cc:48 +msgid " children:" +msgstr " children:" + #: src/export.cc:48 msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" @@ -984,6 +1036,24 @@ msgstr "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" msgstr "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" +#: src/feature.cc:21 +msgid "Enable the concat() function." +msgstr "Funktion concat() aktivieren." + +#: src/feature.cc:60 +#, c-format +msgid "WARNING: Ignoring request to enable unknown feature '%s'." +msgstr "WARNING: Ignoring request to enable unknown feature '%s'." + +#: src/fileutils.cc:25 +#, c-format +msgid "" +"WARNING: Imported file (%s) found in document root instead of relative to " +"the importing module. This behavior is deprecated" +msgstr "" +"WARNING: Imported file (%s) found in document root instead of relative to " +"the importing module. This behavior is deprecated" + #: src/func.cc:503 src/func.cc:536 #, c-format msgid " WARNING: search term not found: \"%s\"" @@ -1013,105 +1083,6 @@ msgstr "" "WARNING: Parent module index (%d) greater than the number of modules on the " "stack" -#: src/glview.cc:149 -#, c-format -msgid "GLEW Error: %s\n" -msgstr "GLEW Error: %s\n" - -#: src/glview.cc:161 -#, c-format -msgid "" -"GLEW version %s\n" -"OpenGL version %s\n" -"%s (%s)\n" -"\n" -"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" -"Extensions:\n" -"%s\n" -msgstr "" -"GLEW version %s\n" -"OpenGL version %s\n" -"%s (%s)\n" -"\n" -"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" -"Extensions:\n" -"%s\n" - -#: src/glview.cc:304 -#, c-format -msgid "" -"OpenGL Program Linker Error:\n" -"%.*s" -msgstr "" -"OpenGL Program Linker Error:\n" -"%.*s" - -#: src/glview.cc:310 -#, c-format -msgid "" -"OpenGL Program Link OK:\n" -"%.*s" -msgstr "" -"OpenGL Program Link OK:\n" -"%.*s" - -#: src/glview.cc:315 -#, c-format -msgid "" -"OpenGL Program Validation results:\n" -"%.*s" -msgstr "" -"OpenGL Program Validation results:\n" -"%.*s" - -#: src/glview.cc:329 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" - -#: src/glview.cc:332 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" -msgstr "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" - -#: src/glview.cc:335 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" -msgstr "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" - -#: src/glview.cc:339 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" - -#: src/glview.cc:537 -#, c-format -msgid "" -"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " -"distance = %.2f" -msgstr "" -"Ansicht: Verschiebung = [ %.2f %.2f %.2f ], Rotation = [ %.2f %.2f %.2f ], " -"Abstand = %.2f" - #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" @@ -1224,14 +1195,6 @@ msgstr "ERROR: CSG generation failed! (no top level object found)" msgid "CSG generation cancelled." msgstr "CSG generation cancelled." -#: src/mainwin.cc:821 -msgid "Compiling design (CSG Products normalization)..." -msgstr "Compiling design (CSG Products normalization)..." - -#: src/mainwin.cc:833 -msgid "WARNING: CSG normalization resulted in an empty tree" -msgstr "WARNING: CSG normalization resulted in an empty tree" - #: src/mainwin.cc:839 #, c-format msgid "Compiling highlights (%d CSG Trees)..." @@ -1251,11 +1214,6 @@ msgstr "WARNING: Normalized tree has %d elements!" msgid "WARNING: OpenCSG rendering has been disabled." msgstr "WARNING: OpenCSG rendering has been disabled." -#: src/mainwin.cc:868 -#, c-format -msgid "Normalized CSG tree has %d elements" -msgstr "Normalized CSG tree has %d elements" - #: src/mainwin.cc:878 msgid "CSG generation finished." msgstr "CSG generation finished." @@ -1537,9 +1495,9 @@ msgid "No filename specified. %s export aborted." msgstr "No filename specified. %s export aborted." #: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 -#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 -#: src/openscad.cc:418 +#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 +#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 +#: src/openscad.cc:442 #, c-format msgid "Can't open file \"%s\" for export" msgstr "Can't open file \"%s\" for export" @@ -1633,6 +1591,35 @@ msgstr "" "The document has been modified.\n" "Do you want to save your changes?" +#: src/modcontext.cc:100 +#, c-format +msgid "WARNING: Experimental builtin function '%s' is not enabled." +msgstr "WARNING: Experimental builtin function '%s' is not enabled." + +#: src/modcontext.cc:113 +#, c-format +msgid "WARNING: Experimental builtin module '%s' is not enabled." +msgstr "WARNING: Experimental builtin module '%s' is not enabled." + +#: src/modcontext.cc:118 +#, c-format +msgid "" +"DEPRECATED: The %s() module will be removed in future releases. Use %s() " +"instead." +msgstr "" +"DEPRECATED: The %s() module will be removed in future releases. Use %s() " +"instead." + +#: src/modcontext.cc:145 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p) " +msgstr "ModuleContext %p (%p) for %s inst (%p) " + +#: src/modcontext.cc:147 +#, c-format +msgid "ModuleContext: %p (%p)" +msgstr "ModuleContext: %p (%p)" + #: src/ModuleCache.cc:70 #, c-format msgid "Recompiling cached library: %s (%s)" @@ -1695,148 +1682,153 @@ msgstr "OpenSCAD version %s\n" msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" msgstr "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" -#: src/openscad.cc:160 +#: src/openscad.cc:182 msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" msgstr "Camera setup requires either 7 numbers for Gimbal Camera\n" -#: src/openscad.cc:161 +#: src/openscad.cc:183 msgid "or 6 numbers for Vector Camera\n" msgstr "or 6 numbers for Vector Camera\n" -#: src/openscad.cc:177 +#: src/openscad.cc:199 msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" msgstr "projection needs to be 'o' or 'p' for ortho or perspective\n" -#: src/openscad.cc:188 +#: src/openscad.cc:210 msgid "Need 2 numbers for imgsize\n" msgstr "Need 2 numbers for imgsize\n" -#: src/openscad.cc:236 +#: src/openscad.cc:260 #, c-format msgid "Unknown suffix for output file %s\n" msgstr "Unknown suffix for output file %s\n" -#: src/openscad.cc:260 +#: src/openscad.cc:284 #, c-format msgid "Can't open input file '%s'!\n" msgstr "Can't open input file '%s'!\n" -#: src/openscad.cc:269 +#: src/openscad.cc:293 #, c-format msgid "Can't parse file '%s'!\n" msgstr "Can't parse file '%s'!\n" -#: src/openscad.cc:351 +#: src/openscad.cc:375 #, c-format msgid "Output file:%s\n" msgstr "Output file:%s\n" -#: src/openscad.cc:352 +#: src/openscad.cc:376 msgid "Sorry, don't know how to write deps for that file type. Exiting\n" msgstr "Sorry, don't know how to write deps for that file type. Exiting\n" -#: src/openscad.cc:357 +#: src/openscad.cc:381 msgid "error writing deps" msgstr "error writing deps" -#: src/openscad.cc:364 src/openscad.cc:383 +#: src/openscad.cc:388 src/openscad.cc:407 msgid "Current top level object is not a 3D object.\n" msgstr "Current top level object is not a 3D object.\n" -#: src/openscad.cc:368 src/openscad.cc:387 +#: src/openscad.cc:392 src/openscad.cc:411 msgid "Object isn't a valid 2-manifold! Modify your design.\n" msgstr "Object isn't a valid 2-manifold! Modify your design.\n" -#: src/openscad.cc:402 +#: src/openscad.cc:426 msgid "Current top level object is not a 2D object.\n" msgstr "Current top level object is not a 2D object.\n" -#: src/openscad.cc:584 +#: src/openscad.cc:591 msgid "Allowed options" msgstr "Allowed options" -#: src/openscad.cc:586 +#: src/openscad.cc:593 msgid "help message" msgstr "help message" -#: src/openscad.cc:587 +#: src/openscad.cc:594 msgid "print the version" msgstr "print the version" -#: src/openscad.cc:588 +#: src/openscad.cc:595 msgid "print information about the building process" msgstr "print information about the building process" -#: src/openscad.cc:589 +#: src/openscad.cc:596 msgid "if exporting a png image, do a full CGAL render" msgstr "if exporting a png image, do a full CGAL render" -#: src/openscad.cc:590 +#: src/openscad.cc:597 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" -#: src/openscad.cc:591 +#: src/openscad.cc:598 msgid "parameters for camera when exporting png" msgstr "parameters for camera when exporting png" -#: src/openscad.cc:592 +#: src/openscad.cc:599 msgid "=width,height for exporting png" msgstr "=width,height for exporting png" -#: src/openscad.cc:593 +#: src/openscad.cc:600 msgid "(o)rtho or (p)erspective when exporting png" msgstr "(o)rtho or (p)erspective when exporting png" -#: src/openscad.cc:594 +#: src/openscad.cc:601 msgid "out-file" msgstr "out-file" -#: src/openscad.cc:595 +#: src/openscad.cc:602 msgid "stl-file" msgstr "stl-file" -#: src/openscad.cc:596 +#: src/openscad.cc:603 msgid "dxf-file" msgstr "dxf-file" -#: src/openscad.cc:597 +#: src/openscad.cc:604 msgid "deps-file" msgstr "deps-file" -#: src/openscad.cc:598 +#: src/openscad.cc:605 msgid "makefile" msgstr "makefile" -#: src/openscad.cc:599 +#: src/openscad.cc:606 msgid "var=val" msgstr "var=val" -#: src/openscad.cc:600 +#: src/openscad.cc:607 msgid "enable experimental features" msgstr "enable experimental features" -#: src/openscad.cc:602 +#: src/openscad.cc:609 msgid "Hidden options" msgstr "Hidden options" -#: src/openscad.cc:604 +#: src/openscad.cc:611 msgid "input file" msgstr "input file" -#: src/openscad.cc:638 +#: src/openscad.cc:645 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "DEPRECATED: The -s option is deprecated. Use -o instead.\n" -#: src/openscad.cc:643 +#: src/openscad.cc:650 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "DEPRECATED: The -x option is deprecated. Use -o instead.\n" -#: src/openscad.cc:700 +#: src/openscad.cc:707 msgid "Requested GUI mode but can't open display!\n" msgstr "Requested GUI mode but can't open display!\n" +#: src/PlatformUtils.cc:16 +#, c-format +msgid "ERROR: Cannot create %s" +msgstr "ERROR: Cannot create %s" + #: src/PolySetCache.cc:24 #, c-format msgid "PolySets in cache: %d" @@ -2019,6 +2011,64 @@ msgstr "" msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" msgstr "ERROR: Unable to convert point at index %d to a vec2 of numbers" +#: src/QGLView.cc:105 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" +"\n" +"Using QGLWidget\n" +"\n" + +#: src/QGLView.cc:122 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" + +#: src/QGLView.cc:125 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" + +#: src/QGLView.cc:128 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" + +#: src/QGLView.cc:132 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" + +#: src/QGLView.cc:163 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" +"Ansicht: Verschiebung = [ %.2f %.2f %.2f ], Rotation = [ %.2f %.2f %.2f ], " +"Abstand = %.2f" + #: src/rotateextrude.cc:72 msgid "" "DEPRECATED: Support for reading files in rotate_extrude will be removed in " @@ -2044,3 +2094,44 @@ msgid "" msgstr "" "DEPRECATED: Using ranges of the form [begin:end] with begin value greater " "than the end value is deprecated." + +#~ msgid "GLEW Error: %s\n" +#~ msgstr "GLEW Error: %s\n" + +#~ msgid "" +#~ "GLEW version %s\n" +#~ "OpenGL version %s\n" +#~ "%s (%s)\n" +#~ "\n" +#~ "RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" +#~ "Extensions:\n" +#~ "%s\n" +#~ msgstr "" +#~ "GLEW version %s\n" +#~ "OpenGL version %s\n" +#~ "%s (%s)\n" +#~ "\n" +#~ "RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" +#~ "Extensions:\n" +#~ "%s\n" + +#~ msgid "" +#~ "OpenGL Program Linker Error:\n" +#~ "%.*s" +#~ msgstr "" +#~ "OpenGL Program Linker Error:\n" +#~ "%.*s" + +#~ msgid "" +#~ "OpenGL Program Link OK:\n" +#~ "%.*s" +#~ msgstr "" +#~ "OpenGL Program Link OK:\n" +#~ "%.*s" + +#~ msgid "" +#~ "OpenGL Program Validation results:\n" +#~ "%.*s" +#~ msgstr "" +#~ "OpenGL Program Validation results:\n" +#~ "%.*s" diff --git a/po/fr.po b/po/fr.po index 962a2e14..7663a6b4 100644 --- a/po/fr.po +++ b/po/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2013.02.07\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 21:19+0100\n" +"POT-Creation-Date: 2014-01-09 18:17+0100\n" "PO-Revision-Date: 2013-02-08 15:06-0600\n" "Last-Translator: don bright \n" "Language-Team: French\n" @@ -22,45 +22,6 @@ msgstr "" msgid "About OpenSCAD" msgstr "" -#: objects/ui_OpenCSGWarningDialog.h:86 -#, fuzzy -msgid "OpenGL Warning" -msgstr "Information OpenGL" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 -msgid "Close" -msgstr "Fermer" - -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "" - #: objects/ui_MainWindow.h:470 msgid "MainWindow" msgstr "" @@ -413,6 +374,10 @@ msgstr "" msgid "Export as DXF..." msgstr "" +#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "Fermer" + #: objects/ui_MainWindow.h:559 msgid "Ctrl+W" msgstr "" @@ -517,6 +482,33 @@ msgstr "&Vue" msgid "&Help" msgstr "&Aide" +#: objects/ui_OpenCSGWarningDialog.h:86 +#, fuzzy +msgid "OpenGL Warning" +msgstr "Information OpenGL" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + #: objects/ui_Preferences.h:515 #, fuzzy msgid "3D View" @@ -626,6 +618,53 @@ msgstr "" msgid "toolBar" msgstr "" +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: src/AboutDialog.h:16 +msgid "About OpenSCAD " +msgstr "" + +#: src/cache.h:181 +msgid "Trimming cache: %1% (%2% bytes)" +msgstr "" + +#: src/CGAL_Nef3_workaround.h:255 +msgid "ERROR: CGAL NefPolyhedron Triangulation failed" +msgstr "" + +#: src/CsgInfo.h:48 +msgid "Error: CSG generation failed! (no top level object found)" +msgstr "" + +#: src/CsgInfo.h:53 src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "" + +#: src/CsgInfo.h:60 src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "" + +#: src/CsgInfo.h:64 src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "" + +#: src/CsgInfo.h:69 +#, c-format +msgid "Compiling highlights (%i CSG Trees)..." +msgstr "" + +#: src/CsgInfo.h:79 +#, c-format +msgid "Compiling background (%i CSG Trees)..." +msgstr "" + #: src/cgaladv_minkowski2.cc:43 msgid " vertices:" msgstr "" @@ -748,7 +787,7 @@ msgstr "" msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." msgstr "" -#: src/CGAL_Nef_polyhedron.cc:114 +#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 #, c-format msgid "ERROR: %s" msgstr "" @@ -811,21 +850,21 @@ msgstr "" msgid "ModuleContext %p (%p) for %s inst (%p)" msgstr "" -#: src/context.cc:158 +#: src/context.cc:158 src/evalcontext.cc:40 #, c-format msgid "Context: %p (%p)" msgstr "" -#: src/context.cc:159 +#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 #, c-format msgid " document path: %s" msgstr "" -#: src/context.cc:163 +#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 msgid " module args:" msgstr "" -#: src/context.cc:170 +#: src/context.cc:170 src/modcontext.cc:159 msgid " vars:" msgstr "" @@ -866,7 +905,7 @@ msgstr "" msgid "WARNING: Bad range parameter for children: too many elements (%lu)." msgstr "" -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 #, c-format msgid "" "WARNING: Normalized tree is growing past %d elements. Aborting " @@ -947,6 +986,19 @@ msgstr "" msgid "GLU tesselation error %s" msgstr "" +#: src/evalcontext.cc:38 +#, c-format +msgid "EvalContext %p (%p) for %s inst (%p)" +msgstr "" + +#: src/evalcontext.cc:43 +msgid " eval args:" +msgstr "" + +#: src/evalcontext.cc:48 +msgid " children:" +msgstr "" + #: src/export.cc:48 msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" msgstr "" @@ -960,6 +1012,22 @@ msgstr "" msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" msgstr "" +#: src/feature.cc:21 +msgid "Enable the concat() function." +msgstr "" + +#: src/feature.cc:60 +#, c-format +msgid "WARNING: Ignoring request to enable unknown feature '%s'." +msgstr "" + +#: src/fileutils.cc:25 +#, c-format +msgid "" +"WARNING: Imported file (%s) found in document root instead of relative to " +"the importing module. This behavior is deprecated" +msgstr "" + #: src/func.cc:503 src/func.cc:536 #, c-format msgid " WARNING: search term not found: \"%s\"" @@ -987,79 +1055,6 @@ msgid "" "stack" msgstr "" -#: src/glview.cc:149 -#, c-format -msgid "GLEW Error: %s\n" -msgstr "" - -#: src/glview.cc:161 -#, c-format -msgid "" -"GLEW version %s\n" -"OpenGL version %s\n" -"%s (%s)\n" -"\n" -"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" -"Extensions:\n" -"%s\n" -msgstr "" - -#: src/glview.cc:304 -#, c-format -msgid "" -"OpenGL Program Linker Error:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:310 -#, c-format -msgid "" -"OpenGL Program Link OK:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:315 -#, c-format -msgid "" -"OpenGL Program Validation results:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:329 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" - -#: src/glview.cc:332 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" -msgstr "" - -#: src/glview.cc:335 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" -msgstr "" - -#: src/glview.cc:339 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" - -#: src/glview.cc:537 -#, c-format -msgid "" -"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " -"distance = %.2f" -msgstr "" - #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" @@ -1164,14 +1159,6 @@ msgstr "" msgid "CSG generation cancelled." msgstr "" -#: src/mainwin.cc:821 -msgid "Compiling design (CSG Products normalization)..." -msgstr "" - -#: src/mainwin.cc:833 -msgid "WARNING: CSG normalization resulted in an empty tree" -msgstr "" - #: src/mainwin.cc:839 #, c-format msgid "Compiling highlights (%d CSG Trees)..." @@ -1191,11 +1178,6 @@ msgstr "" msgid "WARNING: OpenCSG rendering has been disabled." msgstr "" -#: src/mainwin.cc:868 -#, c-format -msgid "Normalized CSG tree has %d elements" -msgstr "" - #: src/mainwin.cc:878 msgid "CSG generation finished." msgstr "" @@ -1450,9 +1432,9 @@ msgid "No filename specified. %s export aborted." msgstr "" #: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 -#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 -#: src/openscad.cc:418 +#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 +#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 +#: src/openscad.cc:442 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" @@ -1544,6 +1526,33 @@ msgid "" "Do you want to save your changes?" msgstr "" +#: src/modcontext.cc:100 +#, c-format +msgid "WARNING: Experimental builtin function '%s' is not enabled." +msgstr "" + +#: src/modcontext.cc:113 +#, c-format +msgid "WARNING: Experimental builtin module '%s' is not enabled." +msgstr "" + +#: src/modcontext.cc:118 +#, c-format +msgid "" +"DEPRECATED: The %s() module will be removed in future releases. Use %s() " +"instead." +msgstr "" + +#: src/modcontext.cc:145 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p) " +msgstr "" + +#: src/modcontext.cc:147 +#, c-format +msgid "ModuleContext: %p (%p)" +msgstr "" + #: src/ModuleCache.cc:70 #, c-format msgid "Recompiling cached library: %s (%s)" @@ -1597,147 +1606,152 @@ msgstr "" msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" msgstr "" -#: src/openscad.cc:160 +#: src/openscad.cc:182 msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" msgstr "" -#: src/openscad.cc:161 +#: src/openscad.cc:183 msgid "or 6 numbers for Vector Camera\n" msgstr "" -#: src/openscad.cc:177 +#: src/openscad.cc:199 msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" msgstr "" -#: src/openscad.cc:188 +#: src/openscad.cc:210 msgid "Need 2 numbers for imgsize\n" msgstr "" -#: src/openscad.cc:236 -#, c-format -msgid "Unknown suffix for output file %s\n" -msgstr "" - #: src/openscad.cc:260 #, c-format +msgid "Unknown suffix for output file %s\n" +msgstr "" + +#: src/openscad.cc:284 +#, c-format msgid "Can't open input file '%s'!\n" msgstr "" -#: src/openscad.cc:269 +#: src/openscad.cc:293 #, c-format msgid "Can't parse file '%s'!\n" msgstr "" -#: src/openscad.cc:351 +#: src/openscad.cc:375 #, c-format msgid "Output file:%s\n" msgstr "" -#: src/openscad.cc:352 +#: src/openscad.cc:376 msgid "Sorry, don't know how to write deps for that file type. Exiting\n" msgstr "" -#: src/openscad.cc:357 +#: src/openscad.cc:381 msgid "error writing deps" msgstr "" -#: src/openscad.cc:364 src/openscad.cc:383 +#: src/openscad.cc:388 src/openscad.cc:407 msgid "Current top level object is not a 3D object.\n" msgstr "" -#: src/openscad.cc:368 src/openscad.cc:387 +#: src/openscad.cc:392 src/openscad.cc:411 msgid "Object isn't a valid 2-manifold! Modify your design.\n" msgstr "" -#: src/openscad.cc:402 +#: src/openscad.cc:426 msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:584 +#: src/openscad.cc:591 msgid "Allowed options" msgstr "" -#: src/openscad.cc:586 +#: src/openscad.cc:593 msgid "help message" msgstr "" -#: src/openscad.cc:587 +#: src/openscad.cc:594 msgid "print the version" msgstr "" -#: src/openscad.cc:588 +#: src/openscad.cc:595 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:589 +#: src/openscad.cc:596 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:590 +#: src/openscad.cc:597 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:598 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:592 +#: src/openscad.cc:599 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:600 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:601 msgid "out-file" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:602 msgid "stl-file" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:603 msgid "dxf-file" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:604 msgid "deps-file" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:605 msgid "makefile" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:606 msgid "var=val" msgstr "" -#: src/openscad.cc:600 +#: src/openscad.cc:607 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:602 +#: src/openscad.cc:609 msgid "Hidden options" msgstr "" -#: src/openscad.cc:604 +#: src/openscad.cc:611 msgid "input file" msgstr "" -#: src/openscad.cc:638 +#: src/openscad.cc:645 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:643 +#: src/openscad.cc:650 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:700 +#: src/openscad.cc:707 msgid "Requested GUI mode but can't open display!\n" msgstr "" +#: src/PlatformUtils.cc:16 +#, c-format +msgid "ERROR: Cannot create %s" +msgstr "" + #: src/PolySetCache.cc:24 #, c-format msgid "PolySets in cache: %d" @@ -1892,6 +1906,48 @@ msgstr "" msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" msgstr "" +#: src/QGLView.cc:105 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" + +#: src/QGLView.cc:122 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:125 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:128 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/QGLView.cc:132 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/QGLView.cc:163 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + #: src/rotateextrude.cc:72 msgid "" "DEPRECATED: Support for reading files in rotate_extrude will be removed in " diff --git a/po/ru.po b/po/ru.po index 1f5054b3..7bab0d70 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-06 21:19+0100\n" +"POT-Creation-Date: 2014-01-09 18:17+0100\n" "PO-Revision-Date: 2013-02-24 17:50+0100\n" "Last-Translator: \n" "Language-Team: Russian\n" @@ -22,44 +22,6 @@ msgstr "" msgid "About OpenSCAD" msgstr "" -#: objects/ui_OpenCSGWarningDialog.h:86 -msgid "OpenGL Warning" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:94 objects/ui_MainWindow.h:558 -msgid "Close" -msgstr "" - -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "" - #: objects/ui_MainWindow.h:470 msgid "MainWindow" msgstr "" @@ -412,6 +374,10 @@ msgstr "" msgid "Export as DXF..." msgstr "" +#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "" + #: objects/ui_MainWindow.h:559 msgid "Ctrl+W" msgstr "" @@ -516,6 +482,32 @@ msgstr "" msgid "&Help" msgstr "&Справка" +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + #: objects/ui_Preferences.h:515 msgid "3D View" msgstr "" @@ -624,6 +616,53 @@ msgstr "" msgid "toolBar" msgstr "" +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: src/AboutDialog.h:16 +msgid "About OpenSCAD " +msgstr "" + +#: src/cache.h:181 +msgid "Trimming cache: %1% (%2% bytes)" +msgstr "" + +#: src/CGAL_Nef3_workaround.h:255 +msgid "ERROR: CGAL NefPolyhedron Triangulation failed" +msgstr "" + +#: src/CsgInfo.h:48 +msgid "Error: CSG generation failed! (no top level object found)" +msgstr "" + +#: src/CsgInfo.h:53 src/mainwin.cc:821 +msgid "Compiling design (CSG Products normalization)..." +msgstr "" + +#: src/CsgInfo.h:60 src/mainwin.cc:868 +#, c-format +msgid "Normalized CSG tree has %d elements" +msgstr "" + +#: src/CsgInfo.h:64 src/mainwin.cc:833 +msgid "WARNING: CSG normalization resulted in an empty tree" +msgstr "" + +#: src/CsgInfo.h:69 +#, c-format +msgid "Compiling highlights (%i CSG Trees)..." +msgstr "" + +#: src/CsgInfo.h:79 +#, c-format +msgid "Compiling background (%i CSG Trees)..." +msgstr "" + #: src/cgaladv_minkowski2.cc:43 msgid " vertices:" msgstr "" @@ -746,7 +785,7 @@ msgstr "" msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." msgstr "" -#: src/CGAL_Nef_polyhedron.cc:114 +#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 #, c-format msgid "ERROR: %s" msgstr "" @@ -809,21 +848,21 @@ msgstr "" msgid "ModuleContext %p (%p) for %s inst (%p)" msgstr "" -#: src/context.cc:158 +#: src/context.cc:158 src/evalcontext.cc:40 #, c-format msgid "Context: %p (%p)" msgstr "" -#: src/context.cc:159 +#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 #, c-format msgid " document path: %s" msgstr "" -#: src/context.cc:163 +#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 msgid " module args:" msgstr "" -#: src/context.cc:170 +#: src/context.cc:170 src/modcontext.cc:159 msgid " vars:" msgstr "" @@ -864,7 +903,7 @@ msgstr "" msgid "WARNING: Bad range parameter for children: too many elements (%lu)." msgstr "" -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:53 +#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 #, c-format msgid "" "WARNING: Normalized tree is growing past %d elements. Aborting " @@ -945,6 +984,19 @@ msgstr "" msgid "GLU tesselation error %s" msgstr "" +#: src/evalcontext.cc:38 +#, c-format +msgid "EvalContext %p (%p) for %s inst (%p)" +msgstr "" + +#: src/evalcontext.cc:43 +msgid " eval args:" +msgstr "" + +#: src/evalcontext.cc:48 +msgid " children:" +msgstr "" + #: src/export.cc:48 msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" msgstr "" @@ -958,6 +1010,22 @@ msgstr "" msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" msgstr "" +#: src/feature.cc:21 +msgid "Enable the concat() function." +msgstr "" + +#: src/feature.cc:60 +#, c-format +msgid "WARNING: Ignoring request to enable unknown feature '%s'." +msgstr "" + +#: src/fileutils.cc:25 +#, c-format +msgid "" +"WARNING: Imported file (%s) found in document root instead of relative to " +"the importing module. This behavior is deprecated" +msgstr "" + #: src/func.cc:503 src/func.cc:536 #, c-format msgid " WARNING: search term not found: \"%s\"" @@ -985,79 +1053,6 @@ msgid "" "stack" msgstr "" -#: src/glview.cc:149 -#, c-format -msgid "GLEW Error: %s\n" -msgstr "" - -#: src/glview.cc:161 -#, c-format -msgid "" -"GLEW version %s\n" -"OpenGL version %s\n" -"%s (%s)\n" -"\n" -"RGBA(%d%d%d%d), depth(%d), stencil(%d)\n" -"Extensions:\n" -"%s\n" -msgstr "" - -#: src/glview.cc:304 -#, c-format -msgid "" -"OpenGL Program Linker Error:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:310 -#, c-format -msgid "" -"OpenGL Program Link OK:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:315 -#, c-format -msgid "" -"OpenGL Program Validation results:\n" -"%.*s" -msgstr "" - -#: src/glview.cc:329 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" - -#: src/glview.cc:332 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" -msgstr "" - -#: src/glview.cc:335 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" -msgstr "" - -#: src/glview.cc:339 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" - -#: src/glview.cc:537 -#, c-format -msgid "" -"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " -"distance = %.2f" -msgstr "" - #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" @@ -1162,14 +1157,6 @@ msgstr "" msgid "CSG generation cancelled." msgstr "" -#: src/mainwin.cc:821 -msgid "Compiling design (CSG Products normalization)..." -msgstr "" - -#: src/mainwin.cc:833 -msgid "WARNING: CSG normalization resulted in an empty tree" -msgstr "" - #: src/mainwin.cc:839 #, c-format msgid "Compiling highlights (%d CSG Trees)..." @@ -1189,11 +1176,6 @@ msgstr "" msgid "WARNING: OpenCSG rendering has been disabled." msgstr "" -#: src/mainwin.cc:868 -#, c-format -msgid "Normalized CSG tree has %d elements" -msgstr "" - #: src/mainwin.cc:878 msgid "CSG generation finished." msgstr "" @@ -1448,9 +1430,9 @@ msgid "No filename specified. %s export aborted." msgstr "" #: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:292 src/openscad.cc:304 src/openscad.cc:322 -#: src/openscad.cc:373 src/openscad.cc:392 src/openscad.cc:407 -#: src/openscad.cc:418 +#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 +#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 +#: src/openscad.cc:442 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" @@ -1542,6 +1524,33 @@ msgid "" "Do you want to save your changes?" msgstr "" +#: src/modcontext.cc:100 +#, c-format +msgid "WARNING: Experimental builtin function '%s' is not enabled." +msgstr "" + +#: src/modcontext.cc:113 +#, c-format +msgid "WARNING: Experimental builtin module '%s' is not enabled." +msgstr "" + +#: src/modcontext.cc:118 +#, c-format +msgid "" +"DEPRECATED: The %s() module will be removed in future releases. Use %s() " +"instead." +msgstr "" + +#: src/modcontext.cc:145 +#, c-format +msgid "ModuleContext %p (%p) for %s inst (%p) " +msgstr "" + +#: src/modcontext.cc:147 +#, c-format +msgid "ModuleContext: %p (%p)" +msgstr "" + #: src/ModuleCache.cc:70 #, c-format msgid "Recompiling cached library: %s (%s)" @@ -1595,147 +1604,152 @@ msgstr "" msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" msgstr "" -#: src/openscad.cc:160 +#: src/openscad.cc:182 msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" msgstr "" -#: src/openscad.cc:161 +#: src/openscad.cc:183 msgid "or 6 numbers for Vector Camera\n" msgstr "" -#: src/openscad.cc:177 +#: src/openscad.cc:199 msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" msgstr "" -#: src/openscad.cc:188 +#: src/openscad.cc:210 msgid "Need 2 numbers for imgsize\n" msgstr "" -#: src/openscad.cc:236 -#, c-format -msgid "Unknown suffix for output file %s\n" -msgstr "" - #: src/openscad.cc:260 #, c-format +msgid "Unknown suffix for output file %s\n" +msgstr "" + +#: src/openscad.cc:284 +#, c-format msgid "Can't open input file '%s'!\n" msgstr "" -#: src/openscad.cc:269 +#: src/openscad.cc:293 #, c-format msgid "Can't parse file '%s'!\n" msgstr "" -#: src/openscad.cc:351 +#: src/openscad.cc:375 #, c-format msgid "Output file:%s\n" msgstr "" -#: src/openscad.cc:352 +#: src/openscad.cc:376 msgid "Sorry, don't know how to write deps for that file type. Exiting\n" msgstr "" -#: src/openscad.cc:357 +#: src/openscad.cc:381 msgid "error writing deps" msgstr "" -#: src/openscad.cc:364 src/openscad.cc:383 +#: src/openscad.cc:388 src/openscad.cc:407 msgid "Current top level object is not a 3D object.\n" msgstr "" -#: src/openscad.cc:368 src/openscad.cc:387 +#: src/openscad.cc:392 src/openscad.cc:411 msgid "Object isn't a valid 2-manifold! Modify your design.\n" msgstr "" -#: src/openscad.cc:402 +#: src/openscad.cc:426 msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:584 +#: src/openscad.cc:591 msgid "Allowed options" msgstr "" -#: src/openscad.cc:586 +#: src/openscad.cc:593 msgid "help message" msgstr "" -#: src/openscad.cc:587 +#: src/openscad.cc:594 msgid "print the version" msgstr "" -#: src/openscad.cc:588 +#: src/openscad.cc:595 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:589 +#: src/openscad.cc:596 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:590 +#: src/openscad.cc:597 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:598 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:592 +#: src/openscad.cc:599 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:600 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:601 msgid "out-file" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:602 msgid "stl-file" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:603 msgid "dxf-file" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:604 msgid "deps-file" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:605 msgid "makefile" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:606 msgid "var=val" msgstr "" -#: src/openscad.cc:600 +#: src/openscad.cc:607 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:602 +#: src/openscad.cc:609 msgid "Hidden options" msgstr "" -#: src/openscad.cc:604 +#: src/openscad.cc:611 msgid "input file" msgstr "" -#: src/openscad.cc:638 +#: src/openscad.cc:645 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:643 +#: src/openscad.cc:650 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:700 +#: src/openscad.cc:707 msgid "Requested GUI mode but can't open display!\n" msgstr "" +#: src/PlatformUtils.cc:16 +#, c-format +msgid "ERROR: Cannot create %s" +msgstr "" + #: src/PolySetCache.cc:24 #, c-format msgid "PolySets in cache: %d" @@ -1890,6 +1904,48 @@ msgstr "" msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" msgstr "" +#: src/QGLView.cc:105 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" + +#: src/QGLView.cc:122 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:125 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:128 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/QGLView.cc:132 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/QGLView.cc:163 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + #: src/rotateextrude.cc:72 msgid "" "DEPRECATED: Support for reading files in rotate_extrude will be removed in " From 4d17d80947042549cfaf7ab349cac3f835b0a4b5 Mon Sep 17 00:00:00 2001 From: benderamp Date: Sun, 12 Jan 2014 01:22:21 +0400 Subject: [PATCH 017/263] Add Russian translation for main window and preferences dialog --- po/ru.po | 185 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 93 insertions(+), 92 deletions(-) diff --git a/po/ru.po b/po/ru.po index 7bab0d70..7e03d171 100644 --- a/po/ru.po +++ b/po/ru.po @@ -20,7 +20,7 @@ msgstr "" #: objects/ui_AboutDialog.h:51 msgid "About OpenSCAD" -msgstr "" +msgstr "О программе OpenSCAD" #: objects/ui_MainWindow.h:470 msgid "MainWindow" @@ -60,7 +60,7 @@ msgstr "" #: objects/ui_MainWindow.h:479 msgid "&Reload" -msgstr "" +msgstr "&Обновить" #: objects/ui_MainWindow.h:480 msgid "Ctrl+R" @@ -84,7 +84,7 @@ msgstr "" #: objects/ui_MainWindow.h:485 msgid "&Redo" -msgstr "" +msgstr "&Повторить" #: objects/ui_MainWindow.h:486 msgid "Ctrl+Shift+Z" @@ -92,7 +92,7 @@ msgstr "" #: objects/ui_MainWindow.h:487 msgid "Cu&t" -msgstr "" +msgstr "Вы&резать" #: objects/ui_MainWindow.h:488 msgid "Ctrl+X" @@ -100,7 +100,7 @@ msgstr "" #: objects/ui_MainWindow.h:489 msgid "&Copy" -msgstr "" +msgstr "&Копировать" #: objects/ui_MainWindow.h:490 msgid "Ctrl+C" @@ -108,7 +108,7 @@ msgstr "" #: objects/ui_MainWindow.h:491 msgid "&Paste" -msgstr "" +msgstr "&Вставить" #: objects/ui_MainWindow.h:492 msgid "Ctrl+V" @@ -116,7 +116,7 @@ msgstr "" #: objects/ui_MainWindow.h:493 msgid "&Indent" -msgstr "" +msgstr "&Добавить отступ" #: objects/ui_MainWindow.h:494 msgid "Ctrl+I" @@ -124,7 +124,7 @@ msgstr "" #: objects/ui_MainWindow.h:495 msgid "U&nindent" -msgstr "" +msgstr "У&брать отступ" #: objects/ui_MainWindow.h:496 msgid "Ctrl+Shift+I" @@ -132,7 +132,7 @@ msgstr "" #: objects/ui_MainWindow.h:497 msgid "C&omment" -msgstr "" +msgstr "Зако&мментировать" #: objects/ui_MainWindow.h:498 msgid "Ctrl+D" @@ -140,7 +140,7 @@ msgstr "" #: objects/ui_MainWindow.h:499 msgid "Unco&mment" -msgstr "" +msgstr "Р&аскомментировать" #: objects/ui_MainWindow.h:500 msgid "Ctrl+Shift+D" @@ -148,7 +148,7 @@ msgstr "" #: objects/ui_MainWindow.h:501 msgid "Paste viewport translation" -msgstr "" +msgstr "Вставить смещение точки обзора" #: objects/ui_MainWindow.h:502 msgid "Ctrl+T" @@ -156,11 +156,11 @@ msgstr "" #: objects/ui_MainWindow.h:503 msgid "Paste viewport rotation" -msgstr "" +msgstr "Вставить поворот точки обзора" #: objects/ui_MainWindow.h:504 msgid "Zoom In" -msgstr "" +msgstr "Увеличить масштаб" #: objects/ui_MainWindow.h:505 msgid "Ctrl++" @@ -168,7 +168,7 @@ msgstr "" #: objects/ui_MainWindow.h:506 msgid "Zoom Out" -msgstr "" +msgstr "Уменьшить масштаб" #: objects/ui_MainWindow.h:507 msgid "Ctrl+-" @@ -176,11 +176,11 @@ msgstr "" #: objects/ui_MainWindow.h:508 msgid "Hide editor" -msgstr "" +msgstr "Скрыть редактор" #: objects/ui_MainWindow.h:509 msgid "&Reload and Compile" -msgstr "" +msgstr "&Обновить и компилировать" #: objects/ui_MainWindow.h:510 msgid "F4" @@ -188,7 +188,7 @@ msgstr "" #: objects/ui_MainWindow.h:511 msgid "&Compile" -msgstr "" +msgstr "&Компилировать" #: objects/ui_MainWindow.h:512 msgid "F5" @@ -196,7 +196,7 @@ msgstr "" #: objects/ui_MainWindow.h:513 msgid "Compile and &Render (CGAL)" -msgstr "" +msgstr "Компилировать и &отрисовать (CGAL)" #: objects/ui_MainWindow.h:514 msgid "F6" @@ -204,23 +204,23 @@ msgstr "" #: objects/ui_MainWindow.h:515 msgid "Display &AST..." -msgstr "" +msgstr "Показать &AST..." #: objects/ui_MainWindow.h:516 msgid "Display CSG &Tree..." -msgstr "" +msgstr "Показать &дерево CSG..." #: objects/ui_MainWindow.h:517 msgid "Display CSG &Products..." -msgstr "" +msgstr "Показать &результаты CSG..." #: objects/ui_MainWindow.h:518 msgid "Export as &STL..." -msgstr "" +msgstr "Экспортировать в &STL..." #: objects/ui_MainWindow.h:519 msgid "Export as &OFF..." -msgstr "" +msgstr "Экспортировать в &OFF..." #: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 msgid "OpenCSG" @@ -232,7 +232,7 @@ msgstr "" #: objects/ui_MainWindow.h:522 msgid "CGAL Surfaces" -msgstr "" +msgstr "Поверхности CGAL" #: objects/ui_MainWindow.h:523 msgid "F10" @@ -240,7 +240,7 @@ msgstr "" #: objects/ui_MainWindow.h:524 msgid "CGAL Grid Only" -msgstr "" +msgstr "Только сетка CGAL" #: objects/ui_MainWindow.h:525 msgid "F11" @@ -248,7 +248,7 @@ msgstr "" #: objects/ui_MainWindow.h:526 msgid "Thrown Together" -msgstr "" +msgstr "Всё вместе" #: objects/ui_MainWindow.h:527 msgid "F12" @@ -256,7 +256,7 @@ msgstr "" #: objects/ui_MainWindow.h:528 msgid "Show Edges" -msgstr "" +msgstr "Показывать рёбра" #: objects/ui_MainWindow.h:529 msgid "Ctrl+1" @@ -264,7 +264,7 @@ msgstr "" #: objects/ui_MainWindow.h:530 msgid "Show Axes" -msgstr "" +msgstr "Показывать оси" #: objects/ui_MainWindow.h:531 msgid "Ctrl+2" @@ -272,7 +272,7 @@ msgstr "" #: objects/ui_MainWindow.h:532 msgid "Show Crosshairs" -msgstr "" +msgstr "Показывать перекрестия" #: objects/ui_MainWindow.h:533 msgid "Ctrl+3" @@ -280,11 +280,11 @@ msgstr "" #: objects/ui_MainWindow.h:534 msgid "Animate" -msgstr "" +msgstr "Анимация" #: objects/ui_MainWindow.h:535 msgid "Top" -msgstr "" +msgstr "Сверху" #: objects/ui_MainWindow.h:536 msgid "Ctrl+4" @@ -292,7 +292,7 @@ msgstr "" #: objects/ui_MainWindow.h:537 msgid "Bottom" -msgstr "" +msgstr "Снизу" #: objects/ui_MainWindow.h:538 msgid "Ctrl+5" @@ -300,7 +300,7 @@ msgstr "" #: objects/ui_MainWindow.h:539 msgid "Left" -msgstr "" +msgstr "Слева" #: objects/ui_MainWindow.h:540 msgid "Ctrl+6" @@ -308,7 +308,7 @@ msgstr "" #: objects/ui_MainWindow.h:541 msgid "Right" -msgstr "" +msgstr "Справа" #: objects/ui_MainWindow.h:542 msgid "Ctrl+7" @@ -316,7 +316,7 @@ msgstr "" #: objects/ui_MainWindow.h:543 msgid "Front" -msgstr "" +msgstr "Спереди" #: objects/ui_MainWindow.h:544 msgid "Ctrl+8" @@ -324,7 +324,7 @@ msgstr "" #: objects/ui_MainWindow.h:545 msgid "Back" -msgstr "" +msgstr "Сзади" #: objects/ui_MainWindow.h:546 msgid "Ctrl+9" @@ -332,7 +332,7 @@ msgstr "" #: objects/ui_MainWindow.h:547 msgid "Diagonal" -msgstr "" +msgstr "Аксонометрический" #: objects/ui_MainWindow.h:548 msgid "Ctrl+0" @@ -340,7 +340,7 @@ msgstr "" #: objects/ui_MainWindow.h:549 msgid "Center" -msgstr "" +msgstr "По центру" #: objects/ui_MainWindow.h:550 msgid "Ctrl+P" @@ -348,35 +348,35 @@ msgstr "" #: objects/ui_MainWindow.h:551 msgid "Perspective" -msgstr "" +msgstr "Перспектива" #: objects/ui_MainWindow.h:552 msgid "Orthogonal" -msgstr "" +msgstr "Прямоугольная проекция" #: objects/ui_MainWindow.h:553 msgid "Hide console" -msgstr "" +msgstr "Скрыть консоль" #: objects/ui_MainWindow.h:554 msgid "About" -msgstr "" +msgstr "О программе" #: objects/ui_MainWindow.h:555 msgid "Documentation" -msgstr "" +msgstr "Документация" #: objects/ui_MainWindow.h:556 msgid "Clear Recent" -msgstr "" +msgstr "Очистить список" #: objects/ui_MainWindow.h:557 msgid "Export as DXF..." -msgstr "" +msgstr "Экспортировать в DXF..." #: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 msgid "Close" -msgstr "" +msgstr "Закрыть" #: objects/ui_MainWindow.h:559 msgid "Ctrl+W" @@ -384,47 +384,47 @@ msgstr "" #: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 msgid "Preferences" -msgstr "" +msgstr "Настройки" #: objects/ui_MainWindow.h:561 msgid "Flush Caches" -msgstr "" +msgstr "Очистить кэш" #: objects/ui_MainWindow.h:562 msgid "OpenSCAD Homepage" -msgstr "" +msgstr "Домашняя страница OpenSCAD" #: objects/ui_MainWindow.h:563 msgid "Automatic Reload and Compile" -msgstr "" +msgstr "Автоматически обновлять и комилировать" #: objects/ui_MainWindow.h:564 msgid "Export as Image..." -msgstr "" +msgstr "Экспортировать в растр..." #: objects/ui_MainWindow.h:565 msgid "Export as CSG..." -msgstr "" +msgstr "Экспортировать в CSG..." #: objects/ui_MainWindow.h:566 msgid "Library info" -msgstr "" +msgstr "Информация о библиотеках" #: objects/ui_MainWindow.h:567 msgid "Check for Update.." -msgstr "" +msgstr "Проверить обновления..." #: objects/ui_MainWindow.h:568 msgid "Show Library Folder..." -msgstr "" +msgstr "Открыть каталог библиотек..." #: objects/ui_MainWindow.h:569 msgid "Reset View" -msgstr "" +msgstr "Сбросить настройки вида" #: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 msgid "Editor" -msgstr "" +msgstr "Редактор" #: objects/ui_MainWindow.h:574 msgid "Editor for SCAD code" @@ -440,19 +440,19 @@ msgstr "" #: objects/ui_MainWindow.h:582 msgid "Time:" -msgstr "" +msgstr "Время:" #: objects/ui_MainWindow.h:583 msgid "FPS:" -msgstr "" +msgstr "Кадров в секунду:" #: objects/ui_MainWindow.h:584 msgid "Steps:" -msgstr "" +msgstr "Шагов:" #: objects/ui_MainWindow.h:585 msgid "Dump Pictures" -msgstr "" +msgstr "Сохранять кадры" #: objects/ui_MainWindow.h:586 msgid "&File" @@ -460,11 +460,11 @@ msgstr "&Файл" #: objects/ui_MainWindow.h:587 msgid "Open Recent" -msgstr "" +msgstr "Открыть недавние" #: objects/ui_MainWindow.h:588 msgid "Examples" -msgstr "" +msgstr "Примеры" #: objects/ui_MainWindow.h:589 msgid "&Edit" @@ -472,11 +472,11 @@ msgstr "&Правка" #: objects/ui_MainWindow.h:590 msgid "&Design" -msgstr "" +msgstr "&Модель" #: objects/ui_MainWindow.h:591 msgid "&View" -msgstr "" +msgstr "&Вид" #: objects/ui_MainWindow.h:592 msgid "&Help" @@ -510,19 +510,19 @@ msgstr "" #: objects/ui_Preferences.h:515 msgid "3D View" -msgstr "" +msgstr "3D Вид" #: objects/ui_Preferences.h:516 msgid "Advanced" -msgstr "" +msgstr "Дополнительные" #: objects/ui_Preferences.h:518 msgid "Update" -msgstr "" +msgstr "Обновления" #: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 msgid "Features" -msgstr "" +msgstr "Функции" #: objects/ui_Preferences.h:521 msgid "Enable/Disable experimental features" @@ -530,7 +530,7 @@ msgstr "" #: objects/ui_Preferences.h:523 msgid "Color scheme:" -msgstr "" +msgstr "Цветовая схема:" #: objects/ui_Preferences.h:528 msgid "Cornfield" @@ -546,71 +546,71 @@ msgstr "" #: objects/ui_Preferences.h:535 msgid "Font" -msgstr "" +msgstr "Шрифт" #: objects/ui_Preferences.h:536 msgid "Color syntax highlighting" -msgstr "" +msgstr "Подсветка синтаксиса" #: objects/ui_Preferences.h:539 msgid "For Light Background" -msgstr "" +msgstr "Для светлого фона" #: objects/ui_Preferences.h:540 msgid "For Dark Background" -msgstr "" +msgstr "Для тёмного фона" #: objects/ui_Preferences.h:541 msgid "Off" -msgstr "" +msgstr "Выключить" #: objects/ui_Preferences.h:543 msgid "Automatically check for updates" -msgstr "" +msgstr "Автоматически проверять обновления" #: objects/ui_Preferences.h:544 msgid "Include development snapshots" -msgstr "" +msgstr "Включая рабочие сборки" #: objects/ui_Preferences.h:545 msgid "Check Now" -msgstr "" +msgstr "Проверить сейчас" #: objects/ui_Preferences.h:546 msgid "Last checked: " -msgstr "" +msgstr "Последняя проверка: " #: objects/ui_Preferences.h:549 msgid "Show capability warning" -msgstr "" +msgstr "Показывать предупреждение о возможностях" #: objects/ui_Preferences.h:550 msgid "Enable for OpenGL 1.x" -msgstr "" +msgstr "Включить для OpenGL 1.x" #: objects/ui_Preferences.h:551 msgid "Turn off rendering at " -msgstr "" +msgstr "Отключать отрисовку на " #: objects/ui_Preferences.h:552 msgid "elements" -msgstr "" +msgstr "элементах" #: objects/ui_Preferences.h:553 msgid "Force Goldfeather" -msgstr "" +msgstr "Принудительно использовать алгоритм Goldfeather («Золотое перо»)" #: objects/ui_Preferences.h:554 msgid "CGAL Cache size" -msgstr "" +msgstr "Размер кэша CGAL" #: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 msgid "bytes" -msgstr "" +msgstr "байт" #: objects/ui_Preferences.h:556 msgid "PolySet Cache size" -msgstr "" +msgstr "Размер кэша PolySet" #: objects/ui_Preferences.h:558 msgid "toolBar" @@ -1191,7 +1191,7 @@ msgstr "Открыть файл" #: src/mainwin.cc:908 msgid "OpenSCAD Designs (*.scad *.csg)" -msgstr "" +msgstr "Модели OpenSCAD (*.scad *.csg)" #: src/mainwin.cc:1002 #, c-format @@ -1215,11 +1215,11 @@ msgstr "Сохранить файл" #: src/mainwin.cc:1021 msgid "Untitled.scad" -msgstr "" +msgstr "Безымянный.scad" #: src/mainwin.cc:1022 msgid "OpenSCAD Designs (*.scad)" -msgstr "" +msgstr "Модели OpenSCAD (*.scad)" #: src/mainwin.cc:1032 msgid "" @@ -1516,13 +1516,14 @@ msgstr "" #: src/mainwin.cc:1842 msgid "OpenSCAD Detailed Library and Build Information" -msgstr "" +msgstr "Подробная информация о библиотеках и сборке OpenSCAD" #: src/mainwin.cc:1858 msgid "" "The document has been modified.\n" "Do you want to save your changes?" -msgstr "" +msgstr "Документ был изменен.\n" +"Сохранить изменения?" #: src/modcontext.cc:100 #, c-format From 929d90994740842ebe5132476324d0717e0e338f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 31 Jan 2014 19:24:58 +0100 Subject: [PATCH 018/263] Set Qt text encoding to UTF-8. --- src/openscad.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openscad.cc b/src/openscad.cc index 12d20915..1fae5439 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -518,6 +518,7 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets) #include #include #include +#include Q_DECLARE_METATYPE(shared_ptr); @@ -567,6 +568,8 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha QCoreApplication::setApplicationVersion(TOSTRING(OPENSCAD_VERSION)); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) QGuiApplication::setApplicationDisplayName("OpenSCAD"); +#else + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); #endif // Other global settings From c8a24971b690f864af18813a65e62d16f79749cb Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 19:37:31 +0200 Subject: [PATCH 019/263] Add preferences option to enable/disable localization. --- src/Preferences.cc | 9 ++++++++- src/Preferences.h | 1 + src/Preferences.ui | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index 0e7e063c..493e06fb 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -104,7 +104,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->defaultmap["advanced/mdi"] = true; this->defaultmap["advanced/undockableWindows"] = false; this->defaultmap["launcher/showOnStartup"] = true; - this->defaultmap["advanced/localization"] = false; + this->defaultmap["advanced/localization"] = true; // Toolbar QActionGroup *group = new QActionGroup(this); @@ -367,6 +367,12 @@ void Preferences::on_opencsgLimitEdit_textChanged(const QString &text) // FIXME: Set this globally? } +void Preferences::on_localizationCheckBox_toggled(bool state) +{ + QSettings settings; + settings.setValue("advanced/localization", state); +} + void Preferences::on_forceGoldfeatherBox_toggled(bool state) { QSettings settings; @@ -466,6 +472,7 @@ void Preferences::updateGUI() this->cgalCacheSizeEdit->setText(getValue("advanced/cgalCacheSize").toString()); this->polysetCacheSizeEdit->setText(getValue("advanced/polysetCacheSize").toString()); this->opencsgLimitEdit->setText(getValue("advanced/openCSGLimit").toString()); + this->localizationCheckBox->setChecked(getValue("advanced/localization").toBool()); this->forceGoldfeatherBox->setChecked(getValue("advanced/forceGoldfeather").toBool()); this->mdiCheckBox->setChecked(getValue("advanced/mdi").toBool()); this->undockCheckBox->setChecked(getValue("advanced/undockableWindows").toBool()); diff --git a/src/Preferences.h b/src/Preferences.h index ec354b16..d4b8f452 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -31,6 +31,7 @@ public slots: void on_opencsgLimitEdit_textChanged(const QString &); void on_forceGoldfeatherBox_toggled(bool); void on_mouseWheelZoomBox_toggled(bool); + void on_localizationCheckBox_toggled(bool); void on_updateCheckBox_toggled(bool); void on_snapshotCheckBox_toggled(bool); void on_mdiCheckBox_toggled(bool); diff --git a/src/Preferences.ui b/src/Preferences.ui index 9828bc33..cb98c3ab 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -244,7 +244,7 @@ 0 - + 75 @@ -516,7 +516,7 @@ - + 75 @@ -699,6 +699,16 @@ + + + + Enable user interface localization (requires restart of OpenSCAD) + + + true + + + From 05c3c3e76cc738c3b7e2b2cac4ce1c709922bf9b Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 22:25:25 +0200 Subject: [PATCH 020/263] Add gettext to new dialogs. --- src/FontListDialog.cc | 1 + src/FontListDialog.h | 1 + src/LibraryInfoDialog.h | 2 ++ src/launchingscreen.h | 2 ++ src/openscad.cc | 9 ++------- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/FontListDialog.cc b/src/FontListDialog.cc index bfa3c8e5..0ee7ef59 100644 --- a/src/FontListDialog.cc +++ b/src/FontListDialog.cc @@ -27,6 +27,7 @@ #include #include +#include "qtgettext.h" #include "FontListDialog.h" #include "FontCache.h" diff --git a/src/FontListDialog.h b/src/FontListDialog.h index 10010995..9f9a2532 100644 --- a/src/FontListDialog.h +++ b/src/FontListDialog.h @@ -3,6 +3,7 @@ #include #include +#include "qtgettext.h" #include "ui_FontListDialog.h" #define STRINGIFY(x) #x diff --git a/src/LibraryInfoDialog.h b/src/LibraryInfoDialog.h index b0465ca6..a47e0879 100644 --- a/src/LibraryInfoDialog.h +++ b/src/LibraryInfoDialog.h @@ -2,6 +2,8 @@ #include #include + +#include "qtgettext.h" #include "ui_LibraryInfoDialog.h" class LibraryInfoDialog : public QDialog, public Ui::LibraryInfoDialog diff --git a/src/launchingscreen.h b/src/launchingscreen.h index bbf764bb..d28aae34 100644 --- a/src/launchingscreen.h +++ b/src/launchingscreen.h @@ -3,6 +3,8 @@ #include #include #include + +#include "qtgettext.h" #include "ui_launchingscreen.h" class LaunchingScreen : public QDialog, public Ui::LaunchingScreen diff --git a/src/openscad.cc b/src/openscad.cc index 1fae5439..b65ed057 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -168,7 +168,7 @@ void localization_init() { std::string locale_path(po_dir.string()); #endif if (fs::is_directory(locale_path)) { - setlocale(LC_ALL,""); + setlocale(LC_ALL, ""); bindtextdomain("openscad", locale_path.c_str()); bind_textdomain_codeset("openscad", "UTF-8"); textdomain("openscad"); @@ -581,7 +581,7 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha parser_init(PlatformUtils::applicationPath()); QSettings settings; - if (settings.value("advanced/localization", false).toBool()) { + if (settings.value("advanced/localization", true).toBool()) { localization_init(); } @@ -657,11 +657,6 @@ int main(int argc, char **argv) PlatformUtils::ensureStdIO(); #endif - setlocale(LC_ALL,""); - bindtextdomain("openscad","./po"); - bind_textdomain_codeset("openscad", "UTF-8"); - textdomain("openscad"); - #ifdef ENABLE_CGAL // Causes CGAL errors to abort directly instead of throwing exceptions // (which we don't catch). This gives us stack traces without rerunning in gdb. From 989675324b23ed79ade1e565c17915a508a7e20c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 18 Oct 2014 23:00:06 +0200 Subject: [PATCH 021/263] Make setting uic parameters work for both Qt4 and Qt5. --- openscad.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openscad.pro b/openscad.pro index c41e0aca..ce21d5dc 100644 --- a/openscad.pro +++ b/openscad.pro @@ -225,7 +225,10 @@ win* { RESOURCES = openscad.qrc -QMAKE_UIC += -tr _ +# Qt5 removed access to the QMAKE_UIC variable, the following +# way works for both Qt4 and Qt5 +load(uic) +uic.commands += -tr _ FORMS += src/MainWindow.ui \ src/Preferences.ui \ From 9e52f2fc1b4625e49afc6d49785b47ecf68cdb7d Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 19 Oct 2014 00:38:56 +0200 Subject: [PATCH 022/263] Add N_() to allow adding translation keys without direct gettext() call. --- scripts/translation-update.sh | 1 + src/qtgettext.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index 9c4c8d60..2f8c5c8a 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -14,6 +14,7 @@ updatepot() OPTS=$OPTS' --package-version='$VER OPTS=$OPTS' --default-domain=openscad' OPTS=$OPTS' --keyword=_' + OPTS=$OPTS' --keyword=N_' OPTS=$OPTS' --files-from=./po/POTFILES' cmd="${GETTEXT_PATH}xgettext "$OPTS' -o ./po/openscad.pot' echo $cmd diff --git a/src/qtgettext.h b/src/qtgettext.h index eac628a5..6e667163 100644 --- a/src/qtgettext.h +++ b/src/qtgettext.h @@ -14,6 +14,8 @@ #include #include "printutils.h" +#define N_(String) String + inline QString _( const char *msgid, int category ) { Q_UNUSED( category ); From baf49d107fff5dc7f1e71250d5d1b664411c68ce Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 19 Oct 2014 00:39:32 +0200 Subject: [PATCH 023/263] Add translations. --- src/UIUtils.cc | 3 ++- src/launchingscreen.cc | 2 +- src/mainwin.cc | 46 +++++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/UIUtils.cc b/src/UIUtils.cc index 9785629b..58241ef6 100644 --- a/src/UIUtils.cc +++ b/src/UIUtils.cc @@ -31,6 +31,7 @@ #include #include +#include "qtgettext.h" #include "UIUtils.h" #include "PlatformUtils.h" @@ -81,7 +82,7 @@ QStringList UIUtils::exampleCategories() { QStringList categories; //categories in File menu item - Examples - categories << "Basics" << "Shapes" << "Extrusion" << "Advanced"; + categories << N_("Basics") << N_("Shapes") << N_("Extrusion") << N_("Advanced"); return categories; } diff --git a/src/launchingscreen.cc b/src/launchingscreen.cc index 3e90a940..b75fcadb 100644 --- a/src/launchingscreen.cc +++ b/src/launchingscreen.cc @@ -39,7 +39,7 @@ LaunchingScreen::LaunchingScreen(QWidget *parent) : QDialog(parent) foreach(const QString &category, UIUtils::exampleCategories()) { QFileInfoList examples = UIUtils::exampleFiles(category); - QTreeWidgetItem *categoryItem = new QTreeWidgetItem(QStringList(category)); + QTreeWidgetItem *categoryItem = new QTreeWidgetItem(QStringList(gettext(category.toStdString().c_str()))); foreach(const QFileInfo &example, examples) { diff --git a/src/mainwin.cc b/src/mainwin.cc index 23651190..08f3909a 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -725,7 +725,7 @@ void MainWindow::setFileName(const QString &filename) { if (filename.isEmpty()) { this->fileName.clear(); - setWindowFilePath("untitled.scad"); + setWindowFilePath(_("Untitled.scad")); this->top_ctx.setDocumentPath(currentdir); } else { @@ -1163,7 +1163,7 @@ void MainWindow::show_examples() foreach (const QString &cat, UIUtils::exampleCategories()) { QFileInfoList examples = UIUtils::exampleFiles(cat); - QMenu *menu = this->menuExamples->addMenu(cat); + QMenu *menu = this->menuExamples->addMenu(gettext(cat.toStdString().c_str())); foreach(const QFileInfo &ex, examples) { QAction *openAct = new QAction(ex.fileName(), this); @@ -1265,9 +1265,9 @@ void MainWindow::actionSave() void MainWindow::actionSaveAs() { - QString new_filename = QFileDialog::getSaveFileName(this, "Save File", - this->fileName.isEmpty()?"Untitled.scad":this->fileName, - "OpenSCAD Designs (*.scad)"); + QString new_filename = QFileDialog::getSaveFileName(this, _("Save File"), + this->fileName.isEmpty()?_("Untitled.scad"):this->fileName, + _("OpenSCAD Designs (*.scad)")); if (!new_filename.isEmpty()) { if (QFileInfo(new_filename).suffix().isEmpty()) { new_filename.append(".scad"); @@ -1277,7 +1277,7 @@ void MainWindow::actionSaveAs() QFileInfo info(new_filename); if (info.exists()) { if (QMessageBox::warning(this, windowTitle(), - tr("%1 already exists.\nDo you want to replace it?").arg(info.fileName()), + QString(_("%1 already exists.\nDo you want to replace it?")).arg(info.fileName()), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) { return; } @@ -1605,9 +1605,9 @@ bool MainWindow::checkEditorModified() { if (editor->isContentModified()) { QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, "Application", - "The document has been modified.\n" - "Do you really want to reload the file?", + ret = QMessageBox::warning(this, _("Application"), + _("The document has been modified.\n" + "Do you really want to reload the file?"), QMessageBox::Yes | QMessageBox::No); if (ret != QMessageBox::Yes) { designActionAutoReload->setChecked(false); @@ -1904,9 +1904,9 @@ void MainWindow::actionExport(export_type_e, QString, QString) PRINT("Warning: Object may not be a valid 2-manifold and may need repair! See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export"); } - QString title = QString("Export %1 File").arg(type_name); - QString filter = QString("%1 Files (*%2)").arg(type_name, suffix); - QString filename = this->fileName.isEmpty() ? QString("Untitled") + suffix : QFileInfo(this->fileName).baseName() + suffix; + QString title = QString(_("Export %1 File")).arg(type_name); + QString filter = QString(_("%1 Files (*%2)")).arg(type_name, suffix); + QString filename = this->fileName.isEmpty() ? QString(_("Untitled")) + suffix : QFileInfo(this->fileName).baseName() + suffix; QString export_filename = QFileDialog::getSaveFileName(this, title, filename, filter); if (export_filename.isEmpty()) { PRINTB("No filename specified. %s export aborted.", type_name); @@ -1961,11 +1961,11 @@ QString MainWindow::get2dExportFilename(QString format, QString extension) { return QString(); } - QString caption = QString("Export %1 File").arg(format); + QString caption = QString(_("Export %1 File")).arg(format); QString suggestion = this->fileName.isEmpty() - ? QString("Untitled%1").arg(extension) + ? QString(_("Untitled%1")).arg(extension) : QFileInfo(this->fileName).baseName() + extension; - QString filter = QString("%1 Files (*%2)").arg(format, extension); + QString filter = QString(_("%1 Files (*%2)")).arg(format, extension); QString exportFilename = QFileDialog::getSaveFileName(this, caption, suggestion, filter); if (exportFilename.isEmpty()) { PRINT("No filename specified. DXF export aborted."); @@ -2014,9 +2014,9 @@ void MainWindow::actionExportCSG() return; } - QString csg_filename = QFileDialog::getSaveFileName(this, "Export CSG File", - this->fileName.isEmpty() ? "Untitled.csg" : QFileInfo(this->fileName).baseName()+".csg", - "CSG Files (*.csg)"); + QString csg_filename = QFileDialog::getSaveFileName(this, _("Export CSG File"), + this->fileName.isEmpty() ? _("Untitled.csg") : QFileInfo(this->fileName).baseName()+".csg", + _("CSG Files (*.csg)")); if (csg_filename.isEmpty()) { PRINT("No filename specified. CSG export aborted."); @@ -2042,7 +2042,7 @@ void MainWindow::actionExportImage() setCurrentOutput(); QString img_filename = QFileDialog::getSaveFileName(this, - "Export Image", "", "PNG Files (*.png)"); + _("Export Image"), "", _("PNG Files (*.png)")); if (img_filename.isEmpty()) { PRINT("No filename specified. Image export aborted."); } else { @@ -2289,12 +2289,12 @@ void MainWindow::on_consoleDock_visibilityChanged(bool visible) void MainWindow::editorTopLevelChanged(bool topLevel) { - setDockWidgetTitle(editorDock, QString("Editor"), topLevel); + setDockWidgetTitle(editorDock, QString(_("Editor")), topLevel); } void MainWindow::consoleTopLevelChanged(bool topLevel) { - setDockWidgetTitle(consoleDock, QString("Console"), topLevel); + setDockWidgetTitle(consoleDock, QString(_("Console")), topLevel); } void MainWindow::setDockWidgetTitle(QDockWidget *dockWidget, QString prefix, bool topLevel) @@ -2417,8 +2417,8 @@ bool MainWindow::maybeSave() if (editor->isContentModified()) { QMessageBox::StandardButton ret; QMessageBox box(this); - box.setText("The document has been modified."); - box.setInformativeText("Do you want to save your changes?"); + box.setText(_("The document has been modified.")); + box.setInformativeText(_("Do you want to save your changes?")); box.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); box.setDefaultButton(QMessageBox::Save); box.setIcon(QMessageBox::Warning); From e4071472adeed0e01b053d124b855a0786e627b1 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 19 Oct 2014 00:50:46 +0200 Subject: [PATCH 024/263] Rename for easier translation. --- src/MainWindow.ui | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 22b80e3d..7a2d90cb 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -142,6 +142,8 @@ 0 0 + 1397 + 33 @@ -150,7 +152,7 @@ - Open Recent + Recent Files From 6cd441e0f1996fc1e9b6c79bda02f5c77f32fd18 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 19 Oct 2014 01:19:53 +0200 Subject: [PATCH 025/263] Port translation code to use resource path from PlatformUtils. --- src/FontCache.cc | 4 ++-- src/PlatformUtils.cc | 18 +++++++++++++-- src/PlatformUtils.h | 5 ++++- src/UIUtils.cc | 4 ++-- src/openscad.cc | 6 ++--- src/parsersettings.cc | 47 ++-------------------------------------- src/parsersettings.h | 17 ++------------- tests/cgalcachetest.cc | 4 +++- tests/csgtexttest.cc | 4 +++- tests/modulecachetest.cc | 4 +++- 10 files changed, 40 insertions(+), 73 deletions(-) diff --git a/src/FontCache.cc b/src/FontCache.cc index 1d2546f8..29599e32 100644 --- a/src/FontCache.cc +++ b/src/FontCache.cc @@ -90,7 +90,7 @@ FontCache::FontCache() // If we've got a bundled fonts.conf, initialize fontconfig with our own config // by overriding the built-in fontconfig path. // For system installs and dev environments, we leave this alone - fs::path fontdir(fs::path(PlatformUtils::resourcesPath()) / "fonts"); + fs::path fontdir(PlatformUtils::resourcePath("fonts")); if (fs::is_regular_file(fontdir / "fonts.conf")) { PlatformUtils::setenv("FONTCONFIG_PATH", boosty::stringy(boosty::absolute(fontdir)).c_str(), 0); } @@ -103,7 +103,7 @@ FontCache::FontCache() } // Add the built-in fonts & config - fs::path builtinfontpath = fs::path(PlatformUtils::resourcesPath()) / "fonts"; + fs::path builtinfontpath(PlatformUtils::resourcePath("fonts")); if (fs::is_directory(builtinfontpath)) { FcConfigParseAndLoad(this->config, reinterpret_cast(boosty::stringy(builtinfontpath).c_str()), false); add_font_dir(boosty::stringy(boosty::canonical(builtinfontpath))); diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index a7f6c61a..97b237ab 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -1,7 +1,6 @@ #include #include "PlatformUtils.h" -#include "boosty.h" #include #ifdef USE_SCINTILLA_EDITOR #include @@ -97,7 +96,7 @@ bool PlatformUtils::createBackupPath() } // This is the built-in read-only resources path -std::string PlatformUtils::resourcesPath() +std::string PlatformUtils::resourceBasePath() { fs::path resourcedir(applicationPath()); fs::path tmpdir; @@ -130,6 +129,21 @@ std::string PlatformUtils::resourcesPath() return boosty::stringy(boosty::canonical(resourcedir)); } +fs::path PlatformUtils::resourcePath(const std::string &resource) +{ + fs::path base(resourceBasePath()); + if (!fs::is_directory(base)) { + return fs::path(); + } + + fs::path resource_dir = base / resource; + if (!fs::is_directory(resource_dir)) { + return fs::path(); + } + + return resource_dir; +} + int PlatformUtils::setenv(const char *name, const char *value, int overwrite) { #if defined(WIN32) diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index ca28134c..1dd7feac 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -2,13 +2,16 @@ #include +#include "boosty.h" + namespace PlatformUtils { void registerApplicationPath(const std::string &applicationpath); std::string applicationPath(); std::string documentsPath(); - std::string resourcesPath(); + std::string resourceBasePath(); + fs::path resourcePath(const std::string& resource); std::string userLibraryPath(); bool createUserLibraryPath(); std::string backupPath(); diff --git a/src/UIUtils.cc b/src/UIUtils.cc index 58241ef6..3e8c8c01 100644 --- a/src/UIUtils.cc +++ b/src/UIUtils.cc @@ -89,8 +89,8 @@ QStringList UIUtils::exampleCategories() QFileInfoList UIUtils::exampleFiles(const QString &category) { - QDir dir(QString::fromStdString(PlatformUtils::resourcesPath())); - if (!dir.cd("examples") || !dir.cd(category)) { + QDir dir(QString::fromStdString(PlatformUtils::resourcePath("examples").string())); + if (!dir.cd(category)) { return QFileInfoList(); } diff --git a/src/openscad.cc b/src/openscad.cc index b65ed057..b3515eaf 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -164,7 +164,7 @@ void localization_init() { #ifdef LOCALE_PREFIX std::string locale_path(LOCALE_PREFIX); #else - fs::path po_dir = get_resource_dir("locale"); + fs::path po_dir(PlatformUtils::resourcePath("locale")); std::string locale_path(po_dir.string()); #endif if (fs::is_directory(locale_path)) { @@ -279,7 +279,7 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c const std::string application_path = boosty::stringy(boosty::absolute(boost::filesystem::path(argv[0]).parent_path())); #endif PlatformUtils::registerApplicationPath(application_path); - parser_init(PlatformUtils::applicationPath()); + parser_init(); localization_init(); Tree tree; @@ -578,7 +578,7 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha const QString &app_path = app.applicationDirPath(); PlatformUtils::registerApplicationPath(app_path.toLocal8Bit().constData()); - parser_init(PlatformUtils::applicationPath()); + parser_init(); QSettings settings; if (settings.value("advanced/localization", true).toBool()) { diff --git a/src/parsersettings.cc b/src/parsersettings.cc index b47beccc..6e3f06bb 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -7,7 +7,6 @@ namespace fs = boost::filesystem; -static std::string applicationdir; std::vector librarypath; static void add_librarydir(const std::string &libdir) @@ -15,47 +14,6 @@ static void add_librarydir(const std::string &libdir) librarypath.push_back(libdir); } -fs::path get_resource_dir(const std::string &resource_folder) -{ - if (!fs::is_directory(applicationdir)) { - return fs::path(); - } - - fs::path basepath(applicationdir); - - fs::path paths[] = { -#if __APPLE__ - // Application layout when installed on MacOS - basepath.parent_path().parent_path() / "Contents" / "Resources", -#endif -#ifdef __unix__ - // Different unix installation layouts are possible, this - // tries to capture the most obvious cases. - basepath.parent_path() / "share" / "openscad", - basepath.parent_path().parent_path() / "share" / "openscad", - fs::path("..") / "..", -#endif -#ifdef OPENSCAD_TESTING - // Used when running the test cases from source code layout. - fs::path(".."), -#endif - // Try to fall back to path relative to the executable and - // relative to the current working directory. - basepath, - fs::path("."), - fs::path(), // end of list marker - }; - - for (int a = 0;!paths[a].empty();a++) { - fs::path resource_dir = paths[a] / resource_folder; - if (fs::is_directory(resource_dir)) { - return resource_dir; - } - } - - return fs::path(); -} - /*! Searces for the given file in library paths and returns the full path if found. Returns an empty path if file cannot be found or filename is a directory. @@ -131,9 +89,8 @@ fs::path find_valid_path(const fs::path &sourcepath, return fs::path(); } -void parser_init(const std::string &applicationpath) +void parser_init() { - applicationdir = applicationpath; // Add paths from OPENSCADPATH before adding built-in paths const char *openscadpaths = getenv("OPENSCADPATH"); if (openscadpaths) { @@ -149,5 +106,5 @@ void parser_init(const std::string &applicationpath) add_librarydir(PlatformUtils::userLibraryPath()); #endif - add_librarydir(boosty::absolute(fs::path(PlatformUtils::resourcesPath()) / "libraries").string()); + add_librarydir(boosty::absolute(PlatformUtils::resourcePath("libraries")).string()); } diff --git a/src/parsersettings.h b/src/parsersettings.h index 8ae7730b..1b8dd53b 100644 --- a/src/parsersettings.h +++ b/src/parsersettings.h @@ -8,22 +8,9 @@ namespace fs = boost::filesystem; extern int parser_error_pos; /** - * Initialize application an library path. - * - * @param applicationpath path of the application binary, this is usually - * derived from the Qt application object. If Qt is disabled, argv[0] is used. + * Initialize library path. */ -void parser_init(const std::string &applicationpath); - -/** - * Return a path to specific resources relative to the application binary. - * This is used to find resources bundled with the application, e.g. the - * translation files for the gettext library. - * - * @param folder subfolder for the resources (e.g. "po"). - * @return the resource path. - */ -fs::path get_resource_dir(const std::string &resource_folder); +void parser_init(); fs::path search_libs(const fs::path &localpath); fs::path find_valid_path(const fs::path &sourcepath, diff --git a/tests/cgalcachetest.cc b/tests/cgalcachetest.cc index 0d434cac..663dc48c 100644 --- a/tests/cgalcachetest.cc +++ b/tests/cgalcachetest.cc @@ -52,6 +52,7 @@ namespace fs = boost::filesystem; #include namespace po = boost::program_options; #include "boosty.h" +#include "PlatformUtils.h" std::string commandline_commands; std::string currentdir; @@ -116,7 +117,8 @@ int main(int argc, char **argv) currentdir = boosty::stringy(fs::current_path()); - parser_init(boosty::stringy(fs::path(argv[0]).branch_path())); + PlatformUtils::registerApplicationPath(boosty::stringy(fs::path(argv[0]).branch_path())); + parser_init(); ModuleContext top_ctx; top_ctx.registerBuiltin(); diff --git a/tests/csgtexttest.cc b/tests/csgtexttest.cc index 95912f63..0787088d 100644 --- a/tests/csgtexttest.cc +++ b/tests/csgtexttest.cc @@ -48,6 +48,7 @@ #include namespace fs = boost::filesystem; #include "boosty.h" +#include "PlatformUtils.h" std::string commandline_commands; std::string currentdir; @@ -77,7 +78,8 @@ int main(int argc, char **argv) currentdir = boosty::stringy( fs::current_path() ); - parser_init(boosty::stringy(fs::path(argv[0]).branch_path())); + PlatformUtils::registerApplicationPath(boosty::stringy(fs::path(argv[0]).branch_path())); + parser_init(); ModuleContext top_ctx; top_ctx.registerBuiltin(); diff --git a/tests/modulecachetest.cc b/tests/modulecachetest.cc index d996cd84..c5c46fc0 100644 --- a/tests/modulecachetest.cc +++ b/tests/modulecachetest.cc @@ -46,6 +46,7 @@ #include namespace fs = boost::filesystem; #include "boosty.h" +#include "PlatformUtils.h" std::string commandline_commands; std::string currentdir; @@ -73,7 +74,8 @@ int main(int argc, char **argv) currentdir = boosty::stringy( fs::current_path() ); - parser_init(boosty::stringy(fs::path(argv[0]).branch_path())); + PlatformUtils::registerApplicationPath(boosty::stringy(fs::path(argv[0]).branch_path())); + parser_init(); ModuleContext top_ctx; top_ctx.registerBuiltin(); From df0597c8bfaae852f3a7c3742e403f18894327aa Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 31 Jan 2014 21:26:46 +0100 Subject: [PATCH 026/263] Update translations. --- po/de.po | 3191 ++++++++++++++++++++++++----------------------- po/fr.po | 949 +++++++------- po/openscad.pot | 946 +++++++------- po/ru.po | 954 +++++++------- 4 files changed, 3002 insertions(+), 3038 deletions(-) diff --git a/po/de.po b/po/de.po index f8160a95..b6d3d9dc 100644 --- a/po/de.po +++ b/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-09 18:17+0100\n" -"PO-Revision-Date: 2014-01-09 19:37+0100\n" +"POT-Creation-Date: 2014-10-19 00:48+0200\n" +"PO-Revision-Date: 2014-10-19 00:48+0100\n" "Last-Translator: Torsten Paul \n" "Language-Team: German\n" "Language: de\n" @@ -22,466 +22,605 @@ msgstr "" msgid "About OpenSCAD" msgstr "Über OpenSCAD" -#: objects/ui_MainWindow.h:470 -msgid "MainWindow" -msgstr "MainWindow" +#: objects/ui_FontListDialog.h:102 +msgid "OpenSCAD Font List" +msgstr "OpenSCAD Font Liste" -#: objects/ui_MainWindow.h:471 +#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 +msgid "&OK" +msgstr "OK" + +#: objects/ui_FontListDialog.h:105 +msgid "Paste font selector to Editor Window" +msgstr "Font Auswahl in Editor kopieren" + +#: objects/ui_FontListDialog.h:107 +msgid "Copy to Clipboard" +msgstr "Kopieren" + +#: objects/ui_FontListDialog.h:108 +msgid "Filter:" +msgstr "Filter:" + +#: objects/ui_FontListDialog.h:109 +msgid "" +"

This list shows the fonts currently registered with " +"OpenSCAD.

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" +msgstr "" +"

This list shows the fonts currently registered with " +"OpenSCAD.

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" + +#: objects/ui_LibraryInfoDialog.h:75 +msgid "Lib & Build Info" +msgstr "Lib & Build Info" + +#: objects/ui_LibraryInfoDialog.h:76 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "OpenSCAD Detailed Library and Build Information" + +#: objects/ui_MainWindow.h:732 msgid "&New" msgstr "&Neu" -#: objects/ui_MainWindow.h:472 +#: objects/ui_MainWindow.h:733 msgid "Ctrl+N" msgstr "Ctrl+N" -#: objects/ui_MainWindow.h:473 +#: objects/ui_MainWindow.h:734 msgid "&Open..." msgstr "Ö&ffnen" -#: objects/ui_MainWindow.h:474 +#: objects/ui_MainWindow.h:735 msgid "Ctrl+O" msgstr "Ctrl+O" -#: objects/ui_MainWindow.h:475 +#: objects/ui_MainWindow.h:736 msgid "&Save" msgstr "&Speichern" -#: objects/ui_MainWindow.h:476 +#: objects/ui_MainWindow.h:737 msgid "Ctrl+S" msgstr "Ctrl+S" -#: objects/ui_MainWindow.h:477 +#: objects/ui_MainWindow.h:738 msgid "Save &As..." msgstr "Speichern &Unter..." -#: objects/ui_MainWindow.h:478 +#: objects/ui_MainWindow.h:739 msgid "Ctrl+Shift+S" msgstr "Ctrl+Shift+S" -#: objects/ui_MainWindow.h:479 +#: objects/ui_MainWindow.h:740 msgid "&Reload" msgstr "Neu &laden" -#: objects/ui_MainWindow.h:480 +#: objects/ui_MainWindow.h:741 msgid "Ctrl+R" msgstr "Ctrl+R" -#: objects/ui_MainWindow.h:481 +#: objects/ui_MainWindow.h:742 msgid "&Quit" msgstr "&Beenden" -#: objects/ui_MainWindow.h:482 +#: objects/ui_MainWindow.h:743 msgid "Ctrl+Q" msgstr "Ctrl+Q" -#: objects/ui_MainWindow.h:483 +#: objects/ui_MainWindow.h:744 msgid "&Undo" msgstr "&Rückgängig" -#: objects/ui_MainWindow.h:484 +#: objects/ui_MainWindow.h:745 msgid "Ctrl+Z" msgstr "Ctrl+Z" -#: objects/ui_MainWindow.h:485 +#: objects/ui_MainWindow.h:746 msgid "&Redo" msgstr "&Wiederholen" -#: objects/ui_MainWindow.h:486 +#: objects/ui_MainWindow.h:747 msgid "Ctrl+Shift+Z" msgstr "Ctrl+Shift+Z" -#: objects/ui_MainWindow.h:487 +#: objects/ui_MainWindow.h:748 msgid "Cu&t" msgstr "Ausschneiden" -#: objects/ui_MainWindow.h:488 +#: objects/ui_MainWindow.h:749 msgid "Ctrl+X" msgstr "Ctrl+X" -#: objects/ui_MainWindow.h:489 +#: objects/ui_MainWindow.h:750 msgid "&Copy" msgstr "Kopieren" -#: objects/ui_MainWindow.h:490 +#: objects/ui_MainWindow.h:751 msgid "Ctrl+C" msgstr "Ctrl+C" -#: objects/ui_MainWindow.h:491 +#: objects/ui_MainWindow.h:752 msgid "&Paste" msgstr "Einfügen" -#: objects/ui_MainWindow.h:492 +#: objects/ui_MainWindow.h:753 msgid "Ctrl+V" msgstr "Ctrl+V" -#: objects/ui_MainWindow.h:493 +#: objects/ui_MainWindow.h:754 msgid "&Indent" msgstr "Einzug erhöhen" -#: objects/ui_MainWindow.h:494 +#: objects/ui_MainWindow.h:755 msgid "Ctrl+I" msgstr "Ctrl+I" -#: objects/ui_MainWindow.h:495 +#: objects/ui_MainWindow.h:756 msgid "U&nindent" msgstr "Einzug vermindern" -#: objects/ui_MainWindow.h:496 +#: objects/ui_MainWindow.h:757 msgid "Ctrl+Shift+I" msgstr "Ctrl+Shift+I" -#: objects/ui_MainWindow.h:497 +#: objects/ui_MainWindow.h:758 msgid "C&omment" msgstr "K&ommentieren" -#: objects/ui_MainWindow.h:498 +#: objects/ui_MainWindow.h:759 msgid "Ctrl+D" msgstr "Ctrl+D" -#: objects/ui_MainWindow.h:499 +#: objects/ui_MainWindow.h:760 msgid "Unco&mment" msgstr "Kommentar entfernen" -#: objects/ui_MainWindow.h:500 +#: objects/ui_MainWindow.h:761 msgid "Ctrl+Shift+D" msgstr "Ctrl+Shift+D" -#: objects/ui_MainWindow.h:501 +#: objects/ui_MainWindow.h:762 msgid "Paste viewport translation" msgstr "Aktuelle Verschiebung einfügen" -#: objects/ui_MainWindow.h:502 +#: objects/ui_MainWindow.h:763 msgid "Ctrl+T" msgstr "Ctrl+T" -#: objects/ui_MainWindow.h:503 +#: objects/ui_MainWindow.h:764 msgid "Paste viewport rotation" msgstr "Aktuelle Rotation einfügen" -#: objects/ui_MainWindow.h:504 +#: objects/ui_MainWindow.h:765 objects/ui_MainWindow.h:844 msgid "Zoom In" msgstr "Vergrößern" -#: objects/ui_MainWindow.h:505 +#: objects/ui_MainWindow.h:766 msgid "Ctrl++" msgstr "Ctrl++" -#: objects/ui_MainWindow.h:506 +#: objects/ui_MainWindow.h:767 objects/ui_MainWindow.h:846 msgid "Zoom Out" msgstr "Verkleinern" -#: objects/ui_MainWindow.h:507 +#: objects/ui_MainWindow.h:768 msgid "Ctrl+-" msgstr "Ctrl+-" -#: objects/ui_MainWindow.h:508 +#: objects/ui_MainWindow.h:769 msgid "Hide editor" msgstr "Editor verstecken" -#: objects/ui_MainWindow.h:509 -msgid "&Reload and Compile" +#: objects/ui_MainWindow.h:770 +msgid "&Reload and Preview" msgstr "Neu laden und übersetzen" -#: objects/ui_MainWindow.h:510 +#: objects/ui_MainWindow.h:771 msgid "F4" msgstr "F4" -#: objects/ui_MainWindow.h:511 -msgid "&Compile" -msgstr "Übersetzen" +#: objects/ui_MainWindow.h:772 +msgid "&Preview" +msgstr "Vorschau" -#: objects/ui_MainWindow.h:512 +#: objects/ui_MainWindow.h:773 msgid "F5" msgstr "F5" -#: objects/ui_MainWindow.h:513 -msgid "Compile and &Render (CGAL)" -msgstr "Übersetzen und Rendern (CGAL)" +#: objects/ui_MainWindow.h:774 +msgid "&Render" +msgstr "Rendern" -#: objects/ui_MainWindow.h:514 +#: objects/ui_MainWindow.h:775 msgid "F6" msgstr "F6" -#: objects/ui_MainWindow.h:515 +#: objects/ui_MainWindow.h:776 +msgid "Check Validity" +msgstr "Design überprüfen" + +#: objects/ui_MainWindow.h:777 msgid "Display &AST..." msgstr "&AST Baum anzeigen..." -#: objects/ui_MainWindow.h:516 +#: objects/ui_MainWindow.h:778 msgid "Display CSG &Tree..." msgstr "CSG Baum anzeigen..." -#: objects/ui_MainWindow.h:517 +#: objects/ui_MainWindow.h:779 msgid "Display CSG &Products..." msgstr "CSG Gleichungen anzeigen..." -#: objects/ui_MainWindow.h:518 +#: objects/ui_MainWindow.h:780 msgid "Export as &STL..." msgstr "&STL exportieren..." -#: objects/ui_MainWindow.h:519 +#: objects/ui_MainWindow.h:781 msgid "Export as &OFF..." msgstr "&OFF exportieren..." -#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 -msgid "OpenCSG" -msgstr "OpenCSG" +#: objects/ui_MainWindow.h:782 +msgid "Preview" +msgstr "Vorschau" -#: objects/ui_MainWindow.h:521 +#: objects/ui_MainWindow.h:783 msgid "F9" msgstr "F9" -#: objects/ui_MainWindow.h:522 -msgid "CGAL Surfaces" -msgstr "CGAL Flächen anzeigen" +#: objects/ui_MainWindow.h:784 +msgid "Surfaces" +msgstr "Flächen anzeigen" -#: objects/ui_MainWindow.h:523 +#: objects/ui_MainWindow.h:785 msgid "F10" msgstr "F10" -#: objects/ui_MainWindow.h:524 -msgid "CGAL Grid Only" -msgstr "CGAL Gitter anzeigen" +#: objects/ui_MainWindow.h:786 +msgid "Wireframe" +msgstr "Gittermodell" -#: objects/ui_MainWindow.h:525 +#: objects/ui_MainWindow.h:787 msgid "F11" msgstr "F11" -#: objects/ui_MainWindow.h:526 +#: objects/ui_MainWindow.h:788 msgid "Thrown Together" msgstr "Kombinierte Anzeige" -#: objects/ui_MainWindow.h:527 +#: objects/ui_MainWindow.h:789 msgid "F12" msgstr "F12" -#: objects/ui_MainWindow.h:528 +#: objects/ui_MainWindow.h:790 msgid "Show Edges" msgstr "Kanten anzeigen" -#: objects/ui_MainWindow.h:529 +#: objects/ui_MainWindow.h:791 msgid "Ctrl+1" msgstr "Ctrl+1" -#: objects/ui_MainWindow.h:530 +#: objects/ui_MainWindow.h:792 msgid "Show Axes" msgstr "Koordinatenachsen anzeigen" -#: objects/ui_MainWindow.h:531 +#: objects/ui_MainWindow.h:793 msgid "Ctrl+2" msgstr "Ctrl+2" -#: objects/ui_MainWindow.h:532 +#: objects/ui_MainWindow.h:794 msgid "Show Crosshairs" msgstr "Diagonalen anzeigen" -#: objects/ui_MainWindow.h:533 +#: objects/ui_MainWindow.h:795 msgid "Ctrl+3" msgstr "Ctrl+3" -#: objects/ui_MainWindow.h:534 +#: objects/ui_MainWindow.h:796 msgid "Animate" msgstr "Animation" -#: objects/ui_MainWindow.h:535 +#: objects/ui_MainWindow.h:797 msgid "Top" msgstr "Oben" -#: objects/ui_MainWindow.h:536 +#: objects/ui_MainWindow.h:798 msgid "Ctrl+4" msgstr "Ctrl+4" -#: objects/ui_MainWindow.h:537 +#: objects/ui_MainWindow.h:799 msgid "Bottom" msgstr "Unten" -#: objects/ui_MainWindow.h:538 +#: objects/ui_MainWindow.h:800 msgid "Ctrl+5" msgstr "Ctrl+5" -#: objects/ui_MainWindow.h:539 +#: objects/ui_MainWindow.h:801 msgid "Left" msgstr "Links" -#: objects/ui_MainWindow.h:540 +#: objects/ui_MainWindow.h:802 msgid "Ctrl+6" msgstr "Ctrl+6" -#: objects/ui_MainWindow.h:541 +#: objects/ui_MainWindow.h:803 msgid "Right" msgstr "Rechts" -#: objects/ui_MainWindow.h:542 +#: objects/ui_MainWindow.h:804 msgid "Ctrl+7" msgstr "Ctrl+7" -#: objects/ui_MainWindow.h:543 +#: objects/ui_MainWindow.h:805 msgid "Front" msgstr "Vorn" -#: objects/ui_MainWindow.h:544 +#: objects/ui_MainWindow.h:806 msgid "Ctrl+8" msgstr "Ctrl+8" -#: objects/ui_MainWindow.h:545 +#: objects/ui_MainWindow.h:807 msgid "Back" msgstr "Hinten" -#: objects/ui_MainWindow.h:546 +#: objects/ui_MainWindow.h:808 msgid "Ctrl+9" msgstr "Ctrl+9" -#: objects/ui_MainWindow.h:547 +#: objects/ui_MainWindow.h:809 msgid "Diagonal" msgstr "Diagonal" -#: objects/ui_MainWindow.h:548 +#: objects/ui_MainWindow.h:810 msgid "Ctrl+0" msgstr "Ctrl+0" -#: objects/ui_MainWindow.h:549 +#: objects/ui_MainWindow.h:811 msgid "Center" msgstr "Zentriert" -#: objects/ui_MainWindow.h:550 -msgid "Ctrl+P" -msgstr "Ctrl+P" - -#: objects/ui_MainWindow.h:551 +#: objects/ui_MainWindow.h:812 msgid "Perspective" msgstr "Perspektivisch" -#: objects/ui_MainWindow.h:552 +#: objects/ui_MainWindow.h:813 msgid "Orthogonal" msgstr "Orthogonal" -#: objects/ui_MainWindow.h:553 +#: objects/ui_MainWindow.h:814 msgid "Hide console" msgstr "Konsole verstecken" -#: objects/ui_MainWindow.h:554 +#: objects/ui_MainWindow.h:815 msgid "About" msgstr "Über OpenSCAD" -#: objects/ui_MainWindow.h:555 +#: objects/ui_MainWindow.h:816 msgid "Documentation" msgstr "Dokumentation" -#: objects/ui_MainWindow.h:556 +#: objects/ui_MainWindow.h:817 msgid "Clear Recent" msgstr "Clear Recent" -#: objects/ui_MainWindow.h:557 +#: objects/ui_MainWindow.h:818 msgid "Export as DXF..." msgstr "DXF exportieren..." -#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:819 objects/ui_OpenCSGWarningDialog.h:94 msgid "Close" msgstr "Schließen" -#: objects/ui_MainWindow.h:559 +#: objects/ui_MainWindow.h:820 msgid "Ctrl+W" msgstr "Ctrl+W" -#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +#: objects/ui_MainWindow.h:821 objects/ui_Preferences.h:609 msgid "Preferences" msgstr "Einstellungen" -#: objects/ui_MainWindow.h:561 +#: objects/ui_MainWindow.h:822 +msgid "Find..." +msgstr "Suchen..." + +#: objects/ui_MainWindow.h:823 +msgid "Ctrl+F" +msgstr "Ctrl+F" + +#: objects/ui_MainWindow.h:824 +msgid "Find and Replace..." +msgstr "Suchen und Ersetzen..." + +#: objects/ui_MainWindow.h:825 +msgid "Ctrl+Alt+F" +msgstr "Ctrl+Alt+F" + +#: objects/ui_MainWindow.h:826 +msgid "Find Next" +msgstr "Weiter suchen" + +#: objects/ui_MainWindow.h:827 +msgid "Ctrl+G" +msgstr "Ctrl+G" + +#: objects/ui_MainWindow.h:828 +msgid "Find Previous" +msgstr "Rückwärts suchen" + +#: objects/ui_MainWindow.h:829 +msgid "Ctrl+Shift+G" +msgstr "Ctrl+Shift+G" + +#: objects/ui_MainWindow.h:830 +msgid "Use Selection for Find" +msgstr "Auswahl suchen" + +#: objects/ui_MainWindow.h:831 +msgid "Ctrl+E" +msgstr "Ctrl+E" + +#: objects/ui_MainWindow.h:832 msgid "Flush Caches" msgstr "Cache leeren" -#: objects/ui_MainWindow.h:562 +#: objects/ui_MainWindow.h:833 msgid "OpenSCAD Homepage" msgstr "OpenSCAD Homepage" -#: objects/ui_MainWindow.h:563 -msgid "Automatic Reload and Compile" +#: objects/ui_MainWindow.h:834 +msgid "Automatic Reload and Preview" msgstr "Automatisch neu Laden und Übersetzen" -#: objects/ui_MainWindow.h:564 +#: objects/ui_MainWindow.h:835 msgid "Export as Image..." msgstr "Image exportieren..." -#: objects/ui_MainWindow.h:565 +#: objects/ui_MainWindow.h:836 msgid "Export as CSG..." msgstr "CSG exportieren..." -#: objects/ui_MainWindow.h:566 +#: objects/ui_MainWindow.h:837 msgid "Library info" msgstr "System Informationen" -#: objects/ui_MainWindow.h:567 +#: objects/ui_MainWindow.h:838 msgid "Check for Update.." msgstr "Neue Version suchen..." -#: objects/ui_MainWindow.h:568 +#: objects/ui_MainWindow.h:839 msgid "Show Library Folder..." msgstr "Bibliotheken anzeigen..." -#: objects/ui_MainWindow.h:569 +#: objects/ui_MainWindow.h:840 msgid "Reset View" msgstr "Ansicht zurücksetzen" -#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 -msgid "Editor" -msgstr "Editor" +#: objects/ui_MainWindow.h:841 +msgid "Font List" +msgstr "Font Liste" -#: objects/ui_MainWindow.h:574 -msgid "Editor for SCAD code" -msgstr "Editor for SCAD code" +#: objects/ui_MainWindow.h:842 +msgid "Export as SVG..." +msgstr "SVG exportieren..." -#: objects/ui_MainWindow.h:577 -msgid "Console" -msgstr "Console" +#: objects/ui_MainWindow.h:843 +msgid "Export as AMF..." +msgstr "AMF exportieren..." -#: objects/ui_MainWindow.h:580 -msgid "Console messages" -msgstr "Console messages" +#: objects/ui_MainWindow.h:845 +msgid "Ctrl+]" +msgstr "Ctrl+]" -#: objects/ui_MainWindow.h:582 +#: objects/ui_MainWindow.h:847 +msgid "Ctrl+[" +msgstr "Ctrl+[" + +#: objects/ui_MainWindow.h:848 +msgid "View All" +msgstr "Alles anzeigen" + +#: objects/ui_MainWindow.h:849 +msgid "Convert Tabs to Spaces" +msgstr "Tabs in Leerzeichen konvertieren" + +#: objects/ui_MainWindow.h:850 +msgid "Hide toolbars" +msgstr "Symbolleisten verstecken" + +#: objects/ui_MainWindow.h:851 msgid "Time:" msgstr "Zeit:" -#: objects/ui_MainWindow.h:583 +#: objects/ui_MainWindow.h:852 msgid "FPS:" msgstr "FPS:" -#: objects/ui_MainWindow.h:584 +#: objects/ui_MainWindow.h:853 msgid "Steps:" msgstr "Schritte:" -#: objects/ui_MainWindow.h:585 +#: objects/ui_MainWindow.h:854 msgid "Dump Pictures" msgstr "Bilder ausgeben" -#: objects/ui_MainWindow.h:586 +#: objects/ui_MainWindow.h:855 msgid "&File" msgstr "&Datei" -#: objects/ui_MainWindow.h:587 -msgid "Open Recent" +#: objects/ui_MainWindow.h:856 +msgid "Recent Files" msgstr "Zuletzt benutze Dateien" -#: objects/ui_MainWindow.h:588 +#: objects/ui_MainWindow.h:857 objects/ui_launchingscreen.h:282 +#: objects/ui_launchingscreen.h:284 msgid "Examples" msgstr "Beispiele" -#: objects/ui_MainWindow.h:589 +#: objects/ui_MainWindow.h:858 +msgid "Export" +msgstr "Exportieren" + +#: objects/ui_MainWindow.h:859 msgid "&Edit" msgstr "&Bearbeiten" -#: objects/ui_MainWindow.h:590 +#: objects/ui_MainWindow.h:860 msgid "&Design" msgstr "&Design" -#: objects/ui_MainWindow.h:591 +#: objects/ui_MainWindow.h:861 msgid "&View" msgstr "&Ansicht" -#: objects/ui_MainWindow.h:592 +#: objects/ui_MainWindow.h:862 msgid "&Help" msgstr "&Hilfe" +#: objects/ui_MainWindow.h:865 +msgid "Find" +msgstr "Suchen" + +#: objects/ui_MainWindow.h:866 objects/ui_MainWindow.h:873 +msgid "Replace" +msgstr "Ersetzen" + +#: objects/ui_MainWindow.h:868 +msgid "Search string" +msgstr "Suchtext" + +#: objects/ui_MainWindow.h:869 +msgid "<" +msgstr "<" + +#: objects/ui_MainWindow.h:870 +msgid ">" +msgstr ">" + +#: objects/ui_MainWindow.h:871 +msgid "Done" +msgstr "Fertig" + +#: objects/ui_MainWindow.h:872 +msgid "Replacement string" +msgstr "Ersetzen mit" + +#: objects/ui_MainWindow.h:874 +msgid "All" +msgstr "Alles" + #: objects/ui_OpenCSGWarningDialog.h:86 msgid "OpenGL Warning" msgstr "OpenGL Warning" @@ -518,111 +657,179 @@ msgstr "Enable OpenCSG" msgid "Show this message again" msgstr "Show this message again" -#: objects/ui_Preferences.h:515 +#: objects/ui_Preferences.h:610 msgid "3D View" msgstr "3D Ansicht" -#: objects/ui_Preferences.h:516 +#: objects/ui_Preferences.h:611 src/UIUtils.cc:85 msgid "Advanced" msgstr "Erweitert" -#: objects/ui_Preferences.h:518 +#: objects/ui_Preferences.h:612 src/mainwin.cc:2292 +msgid "Editor" +msgstr "Editor" + +#: objects/ui_Preferences.h:613 msgid "Update" msgstr "Aktualisieren" -#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +#: objects/ui_Preferences.h:614 objects/ui_Preferences.h:661 msgid "Features" msgstr "Funktionen" -#: objects/ui_Preferences.h:521 +#: objects/ui_Preferences.h:616 msgid "Enable/Disable experimental features" msgstr "Enable/Disable experimental features" -#: objects/ui_Preferences.h:523 +#: objects/ui_Preferences.h:618 msgid "Color scheme:" msgstr "Farbschema:" -#: objects/ui_Preferences.h:528 +#: objects/ui_Preferences.h:623 msgid "Cornfield" msgstr "Cornfield" -#: objects/ui_Preferences.h:530 +#: objects/ui_Preferences.h:625 msgid "Metallic" msgstr "Metallic" -#: objects/ui_Preferences.h:532 +#: objects/ui_Preferences.h:627 msgid "Sunset" msgstr "Sunset" -#: objects/ui_Preferences.h:535 +#: objects/ui_Preferences.h:629 +msgid "Starnight" +msgstr "Starnight" + +#: objects/ui_Preferences.h:631 +msgid "BeforeDawn" +msgstr "BeforeDawn" + +#: objects/ui_Preferences.h:633 +msgid "Nature" +msgstr "Nature" + +#: objects/ui_Preferences.h:635 +msgid "DeepOcean" +msgstr "DeepOcean" + +#: objects/ui_Preferences.h:638 +msgid "Editor Type" +msgstr "Editor" + +#: objects/ui_Preferences.h:641 +msgid "Simple Editor" +msgstr "Einfacher Editor" + +#: objects/ui_Preferences.h:642 +msgid "QScintilla Editor" +msgstr "QScintilla Editor" + +#: objects/ui_Preferences.h:644 +msgid "(requires restart)" +msgstr "(Neustart erforderlich)" + +#: objects/ui_Preferences.h:645 msgid "Font" msgstr "Font" -#: objects/ui_Preferences.h:536 +#: objects/ui_Preferences.h:646 msgid "Color syntax highlighting" msgstr "Color syntax highlighting" -#: objects/ui_Preferences.h:539 +#: objects/ui_Preferences.h:649 msgid "For Light Background" msgstr "Für hellen Hintergrund" -#: objects/ui_Preferences.h:540 +#: objects/ui_Preferences.h:650 msgid "For Dark Background" msgstr "Für dunklen Hintergrund" -#: objects/ui_Preferences.h:541 +#: objects/ui_Preferences.h:651 +msgid "Monokai" +msgstr "Monokai" + +#: objects/ui_Preferences.h:652 +msgid "Solarized" +msgstr "Solarized" + +#: objects/ui_Preferences.h:653 msgid "Off" msgstr "Aus" -#: objects/ui_Preferences.h:543 +#: objects/ui_Preferences.h:655 +msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" +msgstr "Ctrl/Cmd+Mausrad zum Vergrößern des Textes benutzen" + +#: objects/ui_Preferences.h:657 msgid "Automatically check for updates" msgstr "Automatisch nach Aktualisierungen suchen" -#: objects/ui_Preferences.h:544 +#: objects/ui_Preferences.h:658 msgid "Include development snapshots" msgstr "Entwickler-Versionen einschließen" -#: objects/ui_Preferences.h:545 +#: objects/ui_Preferences.h:659 msgid "Check Now" msgstr "Jetzt suchen" -#: objects/ui_Preferences.h:546 +#: objects/ui_Preferences.h:660 msgid "Last checked: " msgstr "Zuletzt gesucht: " -#: objects/ui_Preferences.h:549 +#: objects/ui_Preferences.h:662 +msgid "OpenCSG" +msgstr "OpenCSG" + +#: objects/ui_Preferences.h:663 msgid "Show capability warning" msgstr "Kompatibilitätswarnung anzeigen" -#: objects/ui_Preferences.h:550 +#: objects/ui_Preferences.h:664 msgid "Enable for OpenGL 1.x" msgstr "Aktivieren bei OpenGL 1.x" -#: objects/ui_Preferences.h:551 +#: objects/ui_Preferences.h:665 msgid "Turn off rendering at " msgstr "Rendern abbrechen ab " -#: objects/ui_Preferences.h:552 +#: objects/ui_Preferences.h:666 msgid "elements" msgstr "Elementen" -#: objects/ui_Preferences.h:553 +#: objects/ui_Preferences.h:667 msgid "Force Goldfeather" msgstr "Goldfeather Algorithmus erzwingen" -#: objects/ui_Preferences.h:554 +#: objects/ui_Preferences.h:668 msgid "CGAL Cache size" msgstr "CGAL Cache Größe" -#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 +#: objects/ui_Preferences.h:669 objects/ui_Preferences.h:671 msgid "bytes" msgstr "Byte" -#: objects/ui_Preferences.h:556 +#: objects/ui_Preferences.h:670 msgid "PolySet Cache size" msgstr "PolySet Cache Größe" -#: objects/ui_Preferences.h:558 +#: objects/ui_Preferences.h:672 +msgid "Allow to open multiple documents" +msgstr "Öffnen von mehreren Dokumenten erlauben" + +#: objects/ui_Preferences.h:673 +msgid "Enable undocking of Editor and Console" +msgstr "Separate Editor und Konsole Fenster erlauben" + +#: objects/ui_Preferences.h:674 +msgid "Show Welcome Screen" +msgstr "Startbildschirm anzeigen" + +#: objects/ui_Preferences.h:675 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "Lokalisierung der GUI einschalten (benötigt Neustart von OpenSCAD)" + +#: objects/ui_Preferences.h:676 msgid "toolBar" msgstr "toolBar" @@ -634,1384 +841,67 @@ msgstr "Form" msgid "%v / %m" msgstr "%v / %m" -#: src/AboutDialog.h:16 +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "Willkommen zu OpenSCAD" + +#: objects/ui_launchingscreen.h:277 +msgid "New" +msgstr "Neu" + +#: objects/ui_launchingscreen.h:278 +msgid "Open" +msgstr "Öffnen" + +#: objects/ui_launchingscreen.h:279 +msgid "Help" +msgstr "Hilfe" + +#: objects/ui_launchingscreen.h:280 +msgid "Recents" +msgstr "Zuletzt benutze Dateien" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "Öffnen" + +#: objects/ui_launchingscreen.h:285 +msgid "Open Example" +msgstr "Beispiel öffnen" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "Dialog nicht wieder anzeigen" + +#: src/AboutDialog.h:15 msgid "About OpenSCAD " msgstr "Über OpenSCAD" -#: src/cache.h:181 -msgid "Trimming cache: %1% (%2% bytes)" -msgstr "Trimming cache: %1% (%2% bytes)" - -#: src/CGAL_Nef3_workaround.h:255 -msgid "ERROR: CGAL NefPolyhedron Triangulation failed" -msgstr "ERROR: CGAL NefPolyhedron Triangulation failed" - -#: src/CsgInfo.h:48 -msgid "Error: CSG generation failed! (no top level object found)" -msgstr "Error: CSG generation failed! (no top level object found)" - -#: src/CsgInfo.h:53 src/mainwin.cc:821 -msgid "Compiling design (CSG Products normalization)..." -msgstr "Compiling design (CSG Products normalization)..." - -#: src/CsgInfo.h:60 src/mainwin.cc:868 -#, c-format -msgid "Normalized CSG tree has %d elements" -msgstr "Normalized CSG tree has %d elements" - -#: src/CsgInfo.h:64 src/mainwin.cc:833 -msgid "WARNING: CSG normalization resulted in an empty tree" -msgstr "WARNING: CSG normalization resulted in an empty tree" - -#: src/CsgInfo.h:69 -#, c-format -msgid "Compiling highlights (%i CSG Trees)..." -msgstr "Compiling highlights (%i CSG Trees)..." - -#: src/CsgInfo.h:79 -#, c-format -msgid "Compiling background (%i CSG Trees)..." -msgstr "Compiling background (%i CSG Trees)..." - -#: src/cgaladv_minkowski2.cc:43 -msgid " vertices:" -msgstr " vertices:" - -#: src/cgaladv_minkowski2.cc:55 -msgid "{ Outer boundary = " -msgstr "{ Outer boundary = " - -#: src/cgaladv_minkowski2.cc:58 -msgid "{ Unbounded polygon." -msgstr "{ Unbounded polygon." - -#: src/cgaladv_minkowski2.cc:63 -msgid " holes:" -msgstr " holes:" - -#: src/cgaladv_minkowski2.cc:65 -msgid " Hole #" -msgstr " Hole #" - -#: src/cgaladv_minkowski2.cc:90 -msgid "" -"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" -msgstr "" -"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" - -#: src/cgaladv_minkowski2.cc:123 -msgid "WARNING: minkowski() could not get any points from object 1!" -msgstr "WARNING: minkowski() could not get any points from object 1!" - -#: src/cgaladv_minkowski2.cc:126 -msgid "WARNING: minkowski() could not get any points from object 2!" -msgstr "WARNING: minkowski() could not get any points from object 2!" - -#: src/CGALCache.cc:15 -#, c-format -msgid "CGAL Cache hit: %s (%d bytes)" -msgstr "CGAL Cache hit: %s (%d bytes)" - -#: src/CGALCache.cc:24 -#, c-format -msgid "CGAL Cache insert: %s (%d bytes)" -msgstr "CGAL Cache insert: %s (%d bytes)" - -#: src/CGALCache.cc:25 -#, c-format -msgid "CGAL Cache insert failed: %s (%d bytes)" -msgstr "CGAL Cache insert failed: %s (%d bytes)" - -#: src/CGALCache.cc:47 -#, c-format -msgid "CGAL Polyhedrons in cache: %d" -msgstr "CGAL Polyhedrons im Cache: %d" - -#: src/CGALCache.cc:48 -#, c-format -msgid "CGAL cache size in bytes: %d" -msgstr "CGAL Cache Größe in Bytes: %d" - -#: src/CGALEvaluator.cc:89 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" -msgstr "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" - -#: src/CGALEvaluator.cc:141 -msgid "WARNING: hull() does not support mixing 2D and 3D objects." -msgstr "WARNING: hull() does not support mixing 2D and 3D objects." - -#: src/CGALEvaluator.cc:159 -msgid "" -"Hull() currently requires a valid 2-manifold. Please modify your design. See " -"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" -msgstr "" -"Hull() currently requires a valid 2-manifold. Please modify your design. See " -"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" - -#: src/CGALEvaluator.cc:172 -#, c-format -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" -msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" - -#: src/CGALEvaluator.cc:207 -msgid "WARNING: Cannot resize to sizes less than 0." -msgstr "WARNING: Cannot resize to sizes less than 0." - -#: src/CGALEvaluator.cc:234 -msgid "WARNING: Resize in direction normal to flat object is not implemented" -msgstr "WARNING: Resize in direction normal to flat object is not implemented" - -#: src/CGALEvaluator.cc:336 -msgid "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." -msgstr "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." - -#: src/CGALEvaluator.cc:384 -msgid "WARNING: glide() is not implemented yet!" -msgstr "WARNING: glide() is not implemented yet!" - -#: src/CGALEvaluator.cc:388 -msgid "WARNING: subdiv() is not implemented yet!" -msgstr "WARNING: subdiv() is not implemented yet!" - -#: src/CGALEvaluator.cc:422 -msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" -msgstr "WARNING: CGAL Evaluator: Root node didn't fit into cache" - -#: src/CGALEvaluator.cc:693 -msgid "PolySet has nonplanar faces. Attempting alternate construction" -msgstr "PolySet has nonplanar faces. Attempting alternate construction" - -#: src/CGALEvaluator.cc:697 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "CGAL error in CGAL_Nef_polyhedron3(): %s" - -#: src/CGALEvaluator.cc:708 -#, c-format -msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "" -"Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" - -#: src/CGAL_Nef_polyhedron.cc:113 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." -msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." - -#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 -#, c-format -msgid "ERROR: %s" -msgstr "ERROR: %s" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:107 -msgid "Warning: Scaling a 2D object with 0 - removing object" -msgstr "Warning: Scaling a 2D object with 0 - removing object" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:137 -msgid "Warning: Scaling a 3D object with 0 - removing object" -msgstr "Warning: Scaling a 3D object with 0 - removing object" - -#: src/cgalutils.cc:138 -#, c-format -msgid "CGAL error in CGAL_Build_PolySet: %s" -msgstr "CGAL error in CGAL_Build_PolySet: %s" - -#: src/cgalworker.cc:36 -msgid "Rendering cancelled." -msgstr "Rendering cancelled." - -#: src/color.cc:69 -#, c-format -msgid "" -"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " -"large." -msgstr "" -"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " -"large." - -#: src/color.cc:81 -#, c-format -msgid "WARNING: Color name \"%s\" unknown. Please see" -msgstr "WARNING: Color name \"%s\" unknown. Please see" - -#: src/color.cc:82 -msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" -msgstr "WARNING: http://en.wikipedia.org/wiki/Web_colors" - -#: src/context.cc:97 -#, c-format -msgid "WARNING: Attempt to modify constant '%s'." -msgstr "WARNING: Attempt to modify constant '%s'." - -#: src/context.cc:121 -#, c-format -msgid "WARNING: Ignoring unknown variable '%s'." -msgstr "WARNING: Ignoring unknown variable '%s'." - -#: src/context.cc:128 -#, c-format -msgid "WARNING: Ignoring unknown function '%s'." -msgstr "WARNING: Ignoring unknown function '%s'." - -#: src/context.cc:135 -#, c-format -msgid "WARNING: Ignoring unknown module '%s'." -msgstr "WARNING: Ignoring unknown module '%s'." - -#: src/context.cc:156 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p)" -msgstr "ModuleContext %p (%p) for %s inst (%p)" - -#: src/context.cc:158 src/evalcontext.cc:40 -#, c-format -msgid "Context: %p (%p)" -msgstr "Context: %p (%p)" - -#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 -#, c-format -msgid " document path: %s" -msgstr " document path: %s" - -#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 -msgid " module args:" -msgstr " module args:" - -#: src/context.cc:170 src/modcontext.cc:159 -msgid " vars:" -msgstr " vars:" - -#: src/control.cc:83 -#, c-format -msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." -msgstr "" -"WARNING: Bad range parameter in for statement: too many elements (%lu)." - -#: src/control.cc:133 src/control.cc:138 src/control.cc:247 -#, c-format -msgid "" -"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " -"vector, range." -msgstr "" -"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " -"vector, range." - -#: src/control.cc:144 -#, c-format -msgid "WARNING: Negative children index (%d) not allowed" -msgstr "WARNING: Negative children index (%d) not allowed" - -#: src/control.cc:150 -#, c-format -msgid "WARNING: Children index (%d) out of bounds (%d children)" -msgstr "WARNING: Children index (%d) out of bounds (%d children)" - -#: src/control.cc:170 -#, c-format -msgid "WARNING: Negative child index (%d) not allowed" -msgstr "WARNING: Negative child index (%d) not allowed" - -#: src/control.cc:189 -#, c-format -msgid "WARNING: Child index (%d) out of bounds (%d children)" -msgstr "WARNING: Child index (%d) out of bounds (%d children)" - -#: src/control.cc:234 -#, c-format -msgid "WARNING: Bad range parameter for children: too many elements (%lu)." -msgstr "WARNING: Bad range parameter for children: too many elements (%lu)." - -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 -#, c-format -msgid "" -"WARNING: Normalized tree is growing past %d elements. Aborting " -"normalization.\n" -msgstr "" -"WARNING: Normalized tree is growing past %d elements. Aborting " -"normalization.\n" - -#: src/dxfdata.cc:83 -#, c-format -msgid "WARNING: Can't open DXF file '%s'." -msgstr "WARNING: Can't open DXF file '%s'." - -#: src/dxfdata.cc:147 -#, c-format -msgid "WARNING: Illegal ID '%s' in `%s'" -msgstr "WARNING: Illegal ID '%s' in `%s'" - -#: src/dxfdata.cc:386 -#, c-format -msgid "WARNING: Illegal value %s in '%s'" -msgstr "WARNING: Illegal value %s in '%s'" - -#: src/dxfdata.cc:392 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." -msgstr "WARNING: Unsupported DXF Entity '%s' (%x) in %s." - -#: src/dxfdata.cc:395 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." -msgstr "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." - -#: src/dxfdim.cc:131 -#, c-format -msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" -msgstr "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" - -#: src/dxfdim.cc:136 -#, c-format -msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" -msgstr "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" - -#: src/dxfdim.cc:211 -#, c-format -msgid "WARNING: Can't find cross in '%s', layer '%s'!" -msgstr "WARNING: Can't find cross in '%s', layer '%s'!" - -#: src/dxftess-cgal.cc:170 -msgid "" -"WARNING: Duplicate vertices and/or intersecting lines found during DXF " -"Tessellation." -msgstr "" -"WARNING: Duplicate vertices and/or intersecting lines found during DXF " -"Tessellation." - -#: src/dxftess-cgal.cc:171 -msgid "" -"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." -msgstr "" -"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." - -#: src/dxftess-cgal.cc:176 -#, c-format -msgid "CGAL error in dxf_tesselate(): %s" -msgstr "CGAL error in dxf_tesselate(): %s" - -#: src/dxftess-cgal.cc:475 -#, c-format -msgid "CGAL error in dxftess triangulate_polygon: %s" -msgstr "CGAL error in dxftess triangulate_polygon: %s" - -#: src/dxftess-cgal.cc:491 -msgid "WARNING: PolySet has polygon with <3 points" -msgstr "WARNING: PolySet has polygon with <3 points" - -#: src/dxftess-cgal.cc:496 -msgid "WARNING: PolySet has degenerate polygon" -msgstr "WARNING: PolySet has degenerate polygon" - -#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 -#, c-format -msgid "GLU tesselation error %s" -msgstr "GLU tesselation error %s" - -#: src/evalcontext.cc:38 -#, c-format -msgid "EvalContext %p (%p) for %s inst (%p)" -msgstr "EvalContext %p (%p) for %s inst (%p)" - -#: src/evalcontext.cc:43 -msgid " eval args:" -msgstr " eval args:" - -#: src/evalcontext.cc:48 -msgid " children:" -msgstr " children:" - -#: src/export.cc:48 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" -msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" - -#: src/export.cc:120 src/export.cc:137 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" -msgstr "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" - -#: src/export.cc:123 -msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" -msgstr "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" - -#: src/feature.cc:21 -msgid "Enable the concat() function." -msgstr "Funktion concat() aktivieren." - -#: src/feature.cc:60 -#, c-format -msgid "WARNING: Ignoring request to enable unknown feature '%s'." -msgstr "WARNING: Ignoring request to enable unknown feature '%s'." - -#: src/fileutils.cc:25 -#, c-format -msgid "" -"WARNING: Imported file (%s) found in document root instead of relative to " -"the importing module. This behavior is deprecated" -msgstr "" -"WARNING: Imported file (%s) found in document root instead of relative to " -"the importing module. This behavior is deprecated" - -#: src/func.cc:503 src/func.cc:536 -#, c-format -msgid " WARNING: search term not found: \"%s\"" -msgstr " WARNING: search term not found: \"%s\"" - -#: src/func.cc:533 -#, c-format -msgid " WARNING: search term not found: %s" -msgstr " WARNING: search term not found: %s" - -#: src/func.cc:545 -#, c-format -msgid " WARNING: search: none performed on input %s" -msgstr " WARNING: search: none performed on input %s" - -#: src/func.cc:591 -#, c-format -msgid "WARNING: Negative parent module index (%d) not allowed" -msgstr "WARNING: Negative parent module index (%d) not allowed" - -#: src/func.cc:595 -#, c-format -msgid "" -"WARNING: Parent module index (%d) greater than the number of modules on the " -"stack" -msgstr "" -"WARNING: Parent module index (%d) greater than the number of modules on the " -"stack" - -#: src/handle_dep.cc:36 -#, c-format -msgid "Can't open dependencies file `%s' for writing!\n" -msgstr "Can't open dependencies file `%s' for writing!\n" - -#: src/import.cc:98 -msgid "DEPRECATED: filename= is deprecated. Please use file=" -msgstr "DEPRECATED: filename= is deprecated. Please use file=" - -#: src/import.cc:122 -msgid "DEPRECATED: layername= is deprecated. Please use layer=" -msgstr "DEPRECATED: layername= is deprecated. Please use layer=" - -#: src/import.cc:195 src/import.cc:281 -#, c-format -msgid "WARNING: Can't open import file '%s'." -msgstr "WARNING: Can't open import file '%s'." - -#: src/import.cc:247 -#, c-format -msgid "WARNING: Can't parse vertex line '%s'." -msgstr "WARNING: Can't parse vertex line '%s'." - -#: src/import.cc:292 -msgid "WARNING: OFF import requires CGAL." -msgstr "WARNING: OFF import requires CGAL." - -#: src/import.cc:306 -#, c-format -msgid "ERROR: Unsupported file format while trying to import file '%s'" -msgstr "ERROR: Unsupported file format while trying to import file '%s'" - -#: src/linearextrude.cc:77 -msgid "" -"DEPRECATED: Support for reading files in linear_extrude will be removed in " -"future releases. Use a child import() instead." -msgstr "" -"DEPRECATED: Support for reading files in linear_extrude will be removed in " -"future releases. Use a child import() instead." - -#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 -#, c-format -msgid "WARNING: No suitable PolySetEvaluator found for %s module!" -msgstr "WARNING: No suitable PolySetEvaluator found for %s module!" - -#: src/mainwin.cc:119 -msgid "" -"Copyright (C) 2009-2013 The OpenSCAD Developers\n" -"\n" -"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." -msgstr "" -"Copyright (C) 2009-2013 The OpenSCAD Developers\n" -"\n" -"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." - -#: src/mainwin.cc:525 -msgid "OpenSCAD - New Document[*]" -msgstr "OpenSCAD - Neue Datei[*]" - -#: src/mainwin.cc:529 -msgid "OpenSCAD - " -msgstr "OpenSCAD - " - -#: src/mainwin.cc:529 -msgid "[*]" -msgstr "[*]" - -#: src/mainwin.cc:603 -#, c-format -msgid "Failed to open file %s: %s" -msgstr "Failed to open file %s: %s" - -#: src/mainwin.cc:610 -#, c-format -msgid "Loaded design '%s'." -msgstr "Loaded design '%s'." - -#: src/mainwin.cc:657 -#, c-format -msgid "Module cache size: %d modules" -msgstr "Module cache size: %d modules" - -#: src/mainwin.cc:741 -msgid "Compiling design (CSG Tree generation)..." -msgstr "Compiling design (CSG Tree generation)..." - -#: src/mainwin.cc:767 -msgid "ERROR: Compilation failed! (no top level object found)" -msgstr "ERROR: Compilation failed! (no top level object found)" - -#: src/mainwin.cc:769 -msgid "ERROR: Compilation failed!" -msgstr "ERROR: Compilation failed!" - -#: src/mainwin.cc:782 -msgid "Compiling design (CSG Products generation)..." -msgstr "Compiling design (CSG Products generation)..." - -#: src/mainwin.cc:804 -msgid "ERROR: CSG generation failed! (no top level object found)" -msgstr "ERROR: CSG generation failed! (no top level object found)" - -#: src/mainwin.cc:813 -msgid "CSG generation cancelled." -msgstr "CSG generation cancelled." - -#: src/mainwin.cc:839 -#, c-format -msgid "Compiling highlights (%d CSG Trees)..." -msgstr "Compiling highlights (%d CSG Trees)..." - -#: src/mainwin.cc:851 -#, c-format -msgid "Compiling background (%d CSG Trees)..." -msgstr "Compiling background (%d CSG Trees)..." - -#: src/mainwin.cc:864 -#, c-format -msgid "WARNING: Normalized tree has %d elements!" -msgstr "WARNING: Normalized tree has %d elements!" - -#: src/mainwin.cc:865 -msgid "WARNING: OpenCSG rendering has been disabled." -msgstr "WARNING: OpenCSG rendering has been disabled." - -#: src/mainwin.cc:878 -msgid "CSG generation finished." -msgstr "CSG generation finished." - -#: src/mainwin.cc:880 src/mainwin.cc:1346 -#, c-format -msgid "Total rendering time: %d hours, %d minutes, %d seconds" -msgstr "Total rendering time: %d hours, %d minutes, %d seconds" - -#: src/mainwin.cc:907 -msgid "Open File" -msgstr "Open File" - -#: src/mainwin.cc:908 -msgid "OpenSCAD Designs (*.scad *.csg)" -msgstr "OpenSCAD Designs (*.scad *.csg)" - -#: src/mainwin.cc:1002 -#, c-format -msgid "Failed to open file for writing: %s (%s)" -msgstr "Failed to open file for writing: %s (%s)" - -#: src/mainwin.cc:1003 -msgid "" -"Failed to open file for writing:\n" -" %1 (%2)" -msgstr "" -"Failed to open file for writing:\n" -" %1 (%2)" - -#: src/mainwin.cc:1010 -#, c-format -msgid "Saved design '%s'." -msgstr "Saved design '%s'." - -#: src/mainwin.cc:1020 -msgid "Save File" -msgstr "Save File" - -#: src/mainwin.cc:1021 -msgid "Untitled.scad" -msgstr "Untitled.scad" - -#: src/mainwin.cc:1022 -msgid "OpenSCAD Designs (*.scad)" -msgstr "OpenSCAD Designs (*.scad)" - -#: src/mainwin.cc:1032 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" -"%1 existiert bereits.\n" -"Mochten Sie die Datei ersetzen?" - -#: src/mainwin.cc:1047 -#, c-format -msgid "WARNING: Library path %s doesn't exist. Creating" -msgstr "WARNING: Library path %s doesn't exist. Creating" - -#: src/mainwin.cc:1049 -#, c-format -msgid "ERROR: Cannot create library path: %s" -msgstr "ERROR: Cannot create library path: %s" - -#: src/mainwin.cc:1184 src/mainwin.cc:1857 -msgid "Application" -msgstr "Application" - -#: src/mainwin.cc:1185 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" -"The document has been modified.\n" -"Do you really want to reload the file?" - -#: src/mainwin.cc:1235 src/mainwin.cc:1279 -msgid "Parsing design (AST generation)..." -msgstr "Parsing design (AST generation)..." - -#: src/mainwin.cc:1263 -#, c-format -msgid "frame%05d.png" -msgstr "frame%05d.png" - -#: src/mainwin.cc:1300 -msgid "Rendering Polygon Mesh using CGAL..." -msgstr "Rendering Polygon Mesh using CGAL..." - -#: src/mainwin.cc:1321 -msgid " Top level object is a 2D object:" -msgstr " Top level object is a 2D object:" - -#: src/mainwin.cc:1322 -#, c-format -msgid " Empty: %6s" -msgstr " Empty: %6s" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "yes" -msgstr "yes" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "no" -msgstr "no" - -#: src/mainwin.cc:1323 -#, c-format -msgid " Plane: %6s" -msgstr " Plane: %6s" - -#: src/mainwin.cc:1324 src/mainwin.cc:1336 -#, c-format -msgid " Vertices: %6d" -msgstr " Vertices: %6d" - -#: src/mainwin.cc:1325 src/mainwin.cc:1337 -#, c-format -msgid " Halfedges: %6d" -msgstr " Halfedges: %6d" - -#: src/mainwin.cc:1326 src/mainwin.cc:1338 -#, c-format -msgid " Edges: %6d" -msgstr " Edges: %6d" - -#: src/mainwin.cc:1327 -#, c-format -msgid " Faces: %6d" -msgstr " Faces: %6d" - -#: src/mainwin.cc:1328 -#, c-format -msgid " FaceCycles: %6d" -msgstr " FaceCycles: %6d" - -#: src/mainwin.cc:1329 -#, c-format -msgid " ConnComp: %6d" -msgstr " ConnComp: %6d" - -#: src/mainwin.cc:1333 -msgid " Top level object is a 3D object:" -msgstr " Top level object is a 3D object:" - -#: src/mainwin.cc:1334 -#, c-format -msgid " Simple: %6s" -msgstr " Simple: %6s" - -#: src/mainwin.cc:1335 -#, c-format -msgid " Valid: %6s" -msgstr " Valid: %6s" - -#: src/mainwin.cc:1339 -#, c-format -msgid " Halffacets: %6d" -msgstr " Halffacets: %6d" - -#: src/mainwin.cc:1340 -#, c-format -msgid " Facets: %6d" -msgstr " Facets: %6d" - -#: src/mainwin.cc:1341 -#, c-format -msgid " Volumes: %6d" -msgstr " Volumes: %6d" - -#: src/mainwin.cc:1359 -msgid "Rendering finished." -msgstr "Rendering finished." - -#: src/mainwin.cc:1362 -msgid "WARNING: No top level geometry to render" -msgstr "WARNING: No top level geometry to render" - -#: src/mainwin.cc:1380 -msgid "AST Dump" -msgstr "AST Dump" - -#: src/mainwin.cc:1385 -msgid "No AST to dump. Please try compiling first..." -msgstr "No AST to dump. Please try compiling first..." - -#: src/mainwin.cc:1398 -msgid "CSG Tree Dump" -msgstr "CSG Tree Dump" - -#: src/mainwin.cc:1403 -msgid "No CSG to dump. Please try compiling first..." -msgstr "No CSG to dump. Please try compiling first..." - -#: src/mainwin.cc:1416 -msgid "CSG Products Dump" -msgstr "CSG Products Dump" - -#: src/mainwin.cc:1418 -msgid "" -"\n" -"CSG before normalization:\n" -"%1\n" -"\n" -"\n" -"CSG after normalization:\n" -"%2\n" -"\n" -"\n" -"CSG rendering chain:\n" -"%3\n" -"\n" -"\n" -"Highlights CSG rendering chain:\n" -"%4\n" -"\n" -"\n" -"Background CSG rendering chain:\n" -"%5\n" -msgstr "" -"\n" -"CSG before normalization:\n" -"%1\n" -"\n" -"\n" -"CSG after normalization:\n" -"%2\n" -"\n" -"\n" -"CSG rendering chain:\n" -"%3\n" -"\n" -"\n" -"Highlights CSG rendering chain:\n" -"%4\n" -"\n" -"\n" -"Background CSG rendering chain:\n" -"%5\n" - -#: src/mainwin.cc:1441 src/mainwin.cc:1501 -msgid "Nothing to export! Try building first (press F6)." -msgstr "Nothing to export! Try building first (press F6)." - -#: src/mainwin.cc:1447 -msgid "Current top level object is not a 3D object." -msgstr "Current top level object is not a 3D object." - -#: src/mainwin.cc:1453 -msgid "" -"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." -"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" -msgstr "" -"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." -"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" - -#: src/mainwin.cc:1460 -msgid "Export STL File" -msgstr "Export STL File" - -#: src/mainwin.cc:1460 -msgid "Export OFF File" -msgstr "Export OFF File" - -#: src/mainwin.cc:1462 -msgid "STL Files (*.stl)" -msgstr "STL Files (*.stl)" - -#: src/mainwin.cc:1462 -msgid "OFF Files (*.off)" -msgstr "OFF Files (*.off)" - -#: src/mainwin.cc:1464 -#, c-format -msgid "No filename specified. %s export aborted." -msgstr "No filename specified. %s export aborted." - -#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 -#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 -#: src/openscad.cc:442 -#, c-format -msgid "Can't open file \"%s\" for export" -msgstr "Can't open file \"%s\" for export" - -#: src/mainwin.cc:1478 -#, c-format -msgid "%s export finished." -msgstr "%s export finished." - -#: src/mainwin.cc:1507 -msgid "Current top level object is not a 2D object." -msgstr "Current top level object is not a 2D object." - -#: src/mainwin.cc:1513 -msgid "Export DXF File" -msgstr "Export DXF File" - -#: src/mainwin.cc:1514 -msgid "Untitled.dxf" -msgstr "Untitled.dxf" - -#: src/mainwin.cc:1515 -msgid "DXF Files (*.dxf)" -msgstr "DXF Files (*.dxf)" - -#: src/mainwin.cc:1517 -msgid "No filename specified. DXF export aborted." -msgstr "No filename specified. DXF export aborted." - -#: src/mainwin.cc:1529 -msgid "DXF export finished." -msgstr "DXF export finished." - -#: src/mainwin.cc:1541 -msgid "Nothing to export. Please try compiling first..." -msgstr "Nothing to export. Please try compiling first..." - -#: src/mainwin.cc:1546 -msgid "Export CSG File" -msgstr "Export CSG File" - -#: src/mainwin.cc:1547 -msgid "Untitled.csg" -msgstr "Untitled.csg" - -#: src/mainwin.cc:1548 -msgid "CSG Files (*.csg)" -msgstr "CSG Files (*.csg)" - -#: src/mainwin.cc:1550 -msgid "No filename specified. CSG export aborted." -msgstr "No filename specified. CSG export aborted." - -#: src/mainwin.cc:1562 -msgid "CSG export finished." -msgstr "CSG export finished." - -#: src/mainwin.cc:1573 -msgid "Export Image" -msgstr "Bild exportieren" - -#: src/mainwin.cc:1573 -msgid "PNG Files (*.png)" -msgstr "PNG Files (*.png)" - -#: src/mainwin.cc:1575 -msgid "No filename specified. Image export aborted." -msgstr "No filename specified. Image export aborted." - -#: src/mainwin.cc:1827 -msgid "http://openscad.org/" -msgstr "http://openscad.org/" - -#: src/mainwin.cc:1833 -msgid "http://www.openscad.org/documentation.html" -msgstr "http://www.openscad.org/documentation.html" - -#: src/mainwin.cc:1842 -msgid "OpenGL Info" -msgstr "OpenGL Info" - -#: src/mainwin.cc:1842 -msgid "OpenSCAD Detailed Library and Build Information" -msgstr "OpenSCAD Detailed Library and Build Information" - -#: src/mainwin.cc:1858 -msgid "" -"The document has been modified.\n" -"Do you want to save your changes?" -msgstr "" -"The document has been modified.\n" -"Do you want to save your changes?" - -#: src/modcontext.cc:100 -#, c-format -msgid "WARNING: Experimental builtin function '%s' is not enabled." -msgstr "WARNING: Experimental builtin function '%s' is not enabled." - -#: src/modcontext.cc:113 -#, c-format -msgid "WARNING: Experimental builtin module '%s' is not enabled." -msgstr "WARNING: Experimental builtin module '%s' is not enabled." - -#: src/modcontext.cc:118 -#, c-format -msgid "" -"DEPRECATED: The %s() module will be removed in future releases. Use %s() " -"instead." -msgstr "" -"DEPRECATED: The %s() module will be removed in future releases. Use %s() " -"instead." - -#: src/modcontext.cc:145 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p) " -msgstr "ModuleContext %p (%p) for %s inst (%p) " - -#: src/modcontext.cc:147 -#, c-format -msgid "ModuleContext: %p (%p)" -msgstr "ModuleContext: %p (%p)" - -#: src/ModuleCache.cc:70 -#, c-format -msgid "Recompiling cached library: %s (%s)" -msgstr "Recompiling cached library: %s (%s)" - -#: src/ModuleCache.cc:73 -#, c-format -msgid "Compiling library '%s'." -msgstr "Compiling library '%s'." - -#: src/ModuleCache.cc:81 -#, c-format -msgid "WARNING: Can't open library file '%s'\n" -msgstr "WARNING: Can't open library file '%s'\n" - -#: src/ModuleCache.cc:99 -#, c-format -msgid " compiled module: %p" -msgstr " compiled module: %p" - -#: src/module.cc:180 -#, c-format -msgid "ERROR: Recursion detected calling module '%s'" -msgstr "ERROR: Recursion detected calling module '%s'" - -#: src/module.cc:298 -#, c-format -msgid "WARNING: Failed to compile library '%s'." -msgstr "WARNING: Failed to compile library '%s'." - -#: src/openscad.cc:109 -msgid "" -"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" -"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" -"%2%[ --version ] [ --info ] \\\n" -"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" -"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" -"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" -"%2%[ --render | --preview[=throwntogether] ] \\\n" -"%2%[ --enable= ] \\\n" -"%2%filename\n" -msgstr "" -"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" -"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" -"%2%[ --version ] [ --info ] \\\n" -"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" -"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" -"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" -"%2%[ --render | --preview[=throwntogether] ] \\\n" -"%2%[ --enable= ] \\\n" -"%2%filename\n" - -#: src/openscad.cc:126 -#, c-format -msgid "OpenSCAD version %s\n" -msgstr "OpenSCAD version %s\n" - -#: src/openscad.cc:138 -#, c-format -msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" -msgstr "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" - -#: src/openscad.cc:182 -msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" -msgstr "Camera setup requires either 7 numbers for Gimbal Camera\n" - -#: src/openscad.cc:183 -msgid "or 6 numbers for Vector Camera\n" -msgstr "or 6 numbers for Vector Camera\n" - -#: src/openscad.cc:199 -msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" -msgstr "projection needs to be 'o' or 'p' for ortho or perspective\n" - -#: src/openscad.cc:210 -msgid "Need 2 numbers for imgsize\n" -msgstr "Need 2 numbers for imgsize\n" - -#: src/openscad.cc:260 -#, c-format -msgid "Unknown suffix for output file %s\n" -msgstr "Unknown suffix for output file %s\n" - -#: src/openscad.cc:284 -#, c-format -msgid "Can't open input file '%s'!\n" -msgstr "Can't open input file '%s'!\n" - -#: src/openscad.cc:293 -#, c-format -msgid "Can't parse file '%s'!\n" -msgstr "Can't parse file '%s'!\n" - -#: src/openscad.cc:375 -#, c-format -msgid "Output file:%s\n" -msgstr "Output file:%s\n" - -#: src/openscad.cc:376 -msgid "Sorry, don't know how to write deps for that file type. Exiting\n" -msgstr "Sorry, don't know how to write deps for that file type. Exiting\n" - -#: src/openscad.cc:381 -msgid "error writing deps" -msgstr "error writing deps" - -#: src/openscad.cc:388 src/openscad.cc:407 -msgid "Current top level object is not a 3D object.\n" -msgstr "Current top level object is not a 3D object.\n" - -#: src/openscad.cc:392 src/openscad.cc:411 -msgid "Object isn't a valid 2-manifold! Modify your design.\n" -msgstr "Object isn't a valid 2-manifold! Modify your design.\n" - -#: src/openscad.cc:426 -msgid "Current top level object is not a 2D object.\n" -msgstr "Current top level object is not a 2D object.\n" - -#: src/openscad.cc:591 -msgid "Allowed options" -msgstr "Allowed options" - -#: src/openscad.cc:593 -msgid "help message" -msgstr "help message" - -#: src/openscad.cc:594 -msgid "print the version" -msgstr "print the version" - -#: src/openscad.cc:595 -msgid "print information about the building process" -msgstr "print information about the building process" - -#: src/openscad.cc:596 -msgid "if exporting a png image, do a full CGAL render" -msgstr "if exporting a png image, do a full CGAL render" - -#: src/openscad.cc:597 -msgid "" -"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" -msgstr "" -"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" - -#: src/openscad.cc:598 -msgid "parameters for camera when exporting png" -msgstr "parameters for camera when exporting png" - -#: src/openscad.cc:599 -msgid "=width,height for exporting png" -msgstr "=width,height for exporting png" - -#: src/openscad.cc:600 -msgid "(o)rtho or (p)erspective when exporting png" -msgstr "(o)rtho or (p)erspective when exporting png" - -#: src/openscad.cc:601 -msgid "out-file" -msgstr "out-file" - -#: src/openscad.cc:602 -msgid "stl-file" -msgstr "stl-file" - -#: src/openscad.cc:603 -msgid "dxf-file" -msgstr "dxf-file" - -#: src/openscad.cc:604 -msgid "deps-file" -msgstr "deps-file" - -#: src/openscad.cc:605 -msgid "makefile" -msgstr "makefile" - -#: src/openscad.cc:606 -msgid "var=val" -msgstr "var=val" - -#: src/openscad.cc:607 -msgid "enable experimental features" -msgstr "enable experimental features" - -#: src/openscad.cc:609 -msgid "Hidden options" -msgstr "Hidden options" - -#: src/openscad.cc:611 -msgid "input file" -msgstr "input file" - -#: src/openscad.cc:645 -msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" -msgstr "DEPRECATED: The -s option is deprecated. Use -o instead.\n" - -#: src/openscad.cc:650 -msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" -msgstr "DEPRECATED: The -x option is deprecated. Use -o instead.\n" - -#: src/openscad.cc:707 -msgid "Requested GUI mode but can't open display!\n" -msgstr "Requested GUI mode but can't open display!\n" - -#: src/PlatformUtils.cc:16 -#, c-format -msgid "ERROR: Cannot create %s" -msgstr "ERROR: Cannot create %s" - -#: src/PolySetCache.cc:24 -#, c-format -msgid "PolySets in cache: %d" -msgstr "PolySets in cache: %d" - -#: src/PolySetCache.cc:25 -#, c-format -msgid "PolySet cache size in bytes: %d" -msgstr "PolySet cache size in bytes: %d" - -#: src/polyset.cc:55 -msgid "PolySet:" -msgstr "PolySet:" - -#: src/polyset.cc:56 -msgid "" -"\n" -" dimensions:" -msgstr "" -"\n" -" dimensions:" - -#: src/polyset.cc:57 -msgid "" -"\n" -" convexity:" -msgstr "" -"\n" -" convexity:" - -#: src/polyset.cc:58 -msgid "" -"\n" -" num polygons: " -msgstr "" -"\n" -" num polygons: " - -#: src/polyset.cc:59 -msgid "" -"\n" -" num borders: " -msgstr "" -"\n" -" num borders: " - -#: src/polyset.cc:60 -msgid "" -"\n" -" polygons data:" -msgstr "" -"\n" -" polygons data:" - -#: src/polyset.cc:62 -msgid "" -"\n" -" polygon begin:" -msgstr "" -"\n" -" polygon begin:" - -#: src/polyset.cc:66 src/polyset.cc:75 -msgid "" -"\n" -" vertex:" -msgstr "" -"\n" -" vertex:" - -#: src/polyset.cc:69 -msgid "" -"\n" -" borders data:" -msgstr "" -"\n" -" borders data:" - -#: src/polyset.cc:71 -msgid "" -"\n" -" border polygon begin:" -msgstr "" -"\n" -" border polygon begin:" - -#: src/polyset.cc:78 -msgid "" -"\n" -"PolySet end" -msgstr "" -"\n" -"PolySet end" - -#: src/PolySetCGALEvaluator.cc:46 -msgid "" -"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " -"design.." -msgstr "" -"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " -"design.." - -#: src/PolySetCGALEvaluator.cc:63 -#, c-format -msgid "CGAL error in projection node during plane intersection: %s" -msgstr "CGAL error in projection node during plane intersection: %s" - -#: src/PolySetCGALEvaluator.cc:65 -msgid "Trying alternative intersection using very large thin box: " -msgstr "Trying alternative intersection using very large thin box: " - -#: src/PolySetCGALEvaluator.cc:80 -#, c-format -msgid "CGAL error in projection node during bigbox intersection: %s" -msgstr "CGAL error in projection node during bigbox intersection: %s" - -#: src/PolySetCGALEvaluator.cc:87 -msgid "WARNING: projection() failed." -msgstr "WARNING: projection() failed." - -#: src/PolySetCGALEvaluator.cc:109 -#, c-format -msgid "CGAL error in projection node while flattening: %s" -msgstr "CGAL error in projection node while flattening: %s" - -#: src/PolySetCGALEvaluator.cc:303 -msgid "ERROR: linear_extrude() is not defined for 3D child objects!" -msgstr "ERROR: linear_extrude() is not defined for 3D child objects!" - -#: src/PolySetCGALEvaluator.cc:343 -#, c-format -msgid "" -"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" -msgstr "" -"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" - -#: src/PolySetCGALEvaluator.cc:403 -msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" -msgstr "ERROR: rotate_extrude() is not defined for 3D child objects!" - -#: src/PolySetCGALEvaluator.cc:441 -msgid "WARNING: Body of render() isn't valid 2-manifold!" -msgstr "WARNING: Body of render() isn't valid 2-manifold!" - -#: src/PolySetCGALEvaluator.cc:466 -#, c-format -msgid "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" -msgstr "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" - -#: src/primitives.cc:130 -#, c-format -msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." -msgstr "" -"WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." - -#: src/primitives.cc:183 -#, c-format -msgid "WARNING: $fs too small - clamping to %f" -msgstr "WARNING: $fs too small - clamping to %f" - -#: src/primitives.cc:187 -#, c-format -msgid "WARNING: $fa too small - clamping to %f" -msgstr "WARNING: $fa too small - clamping to %f" - -#: src/primitives.cc:244 -msgid "" -"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " -"polyhedron(faces=[]) instead." -msgstr "" -"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " -"polyhedron(faces=[]) instead." - -#: src/primitives.cc:536 -#, c-format -msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" -msgstr "ERROR: Unable to convert point at index %d to a vec2 of numbers" - -#: src/QGLView.cc:105 +#: src/QGLView.cc:114 msgid "" "\n" "Using QGLWidget\n" @@ -2021,7 +911,7 @@ msgstr "" "Using QGLWidget\n" "\n" -#: src/QGLView.cc:122 +#: src/QGLView.cc:131 msgid "" "Warning: You may experience OpenCSG rendering errors.\n" "\n" @@ -2029,7 +919,7 @@ msgstr "" "Warning: You may experience OpenCSG rendering errors.\n" "\n" -#: src/QGLView.cc:125 +#: src/QGLView.cc:134 msgid "" "Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " "disabled.\n" @@ -2039,7 +929,7 @@ msgstr "" "disabled.\n" "\n" -#: src/QGLView.cc:128 +#: src/QGLView.cc:137 msgid "" "It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " "later.\n" @@ -2049,7 +939,7 @@ msgstr "" "later.\n" "Your renderer information is as follows:\n" -#: src/QGLView.cc:132 +#: src/QGLView.cc:141 #, c-format msgid "" "GLEW version %s\n" @@ -2060,7 +950,7 @@ msgstr "" "%s (%s)\n" "OpenGL version %s\n" -#: src/QGLView.cc:163 +#: src/QGLView.cc:171 #, c-format msgid "" "Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " @@ -2069,31 +959,1194 @@ msgstr "" "Ansicht: Verschiebung = [ %.2f %.2f %.2f ], Rotation = [ %.2f %.2f %.2f ], " "Abstand = %.2f" -#: src/rotateextrude.cc:72 +#: src/UIUtils.cc:85 +msgid "Basics" +msgstr "Grundlagen" + +#: src/UIUtils.cc:85 +msgid "Shapes" +msgstr "Formen" + +#: src/UIUtils.cc:85 +msgid "Extrusion" +msgstr "Extrusion" + +#: src/mainwin.cc:728 src/mainwin.cc:1269 +msgid "Untitled.scad" +msgstr "Untitled.scad" + +#: src/mainwin.cc:1268 +msgid "Save File" +msgstr "Save File" + +#: src/mainwin.cc:1270 +msgid "OpenSCAD Designs (*.scad)" +msgstr "OpenSCAD Designs (*.scad)" + +#: src/mainwin.cc:1280 msgid "" -"DEPRECATED: Support for reading files in rotate_extrude will be removed in " -"future releases. Use a child import() instead." +"%1 already exists.\n" +"Do you want to replace it?" msgstr "" -"DEPRECATED: Support for reading files in rotate_extrude will be removed in " -"future releases. Use a child import() instead." +"%1 existiert bereits.\n" +"Mochten Sie die Datei ersetzen?" -#: src/surface.cc:107 -#, c-format -msgid "WARNING: Can't open DAT file '%s'." -msgstr "WARNING: Can't open DAT file '%s'." +#: src/mainwin.cc:1608 +msgid "Application" +msgstr "Application" -#: src/surface.cc:139 -#, c-format -msgid "WARNING: Illegal value in '%s': %s" -msgstr "WARNING: Illegal value in '%s': %s" - -#: src/value.cc:640 +#: src/mainwin.cc:1609 msgid "" -"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " -"than the end value is deprecated." +"The document has been modified.\n" +"Do you really want to reload the file?" msgstr "" -"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " -"than the end value is deprecated." +"The document has been modified.\n" +"Do you really want to reload the file?" + +#: src/mainwin.cc:1907 src/mainwin.cc:1964 +#, fuzzy +msgid "Export %1 File" +msgstr "Export STL File" + +#: src/mainwin.cc:1908 src/mainwin.cc:1968 +#, fuzzy +msgid "%1 Files (*%2)" +msgstr "STL Files (*.stl)" + +#: src/mainwin.cc:1909 +#, fuzzy +msgid "Untitled" +msgstr "Untitled.dxf" + +#: src/mainwin.cc:1966 +#, fuzzy +msgid "Untitled%1" +msgstr "Untitled.dxf" + +#: src/mainwin.cc:2017 +msgid "Export CSG File" +msgstr "Export CSG File" + +#: src/mainwin.cc:2018 +msgid "Untitled.csg" +msgstr "Untitled.csg" + +#: src/mainwin.cc:2019 +msgid "CSG Files (*.csg)" +msgstr "CSG Files (*.csg)" + +#: src/mainwin.cc:2045 +#, fuzzy +msgid "Export Image" +msgstr "Image exportieren..." + +#: src/mainwin.cc:2045 +msgid "PNG Files (*.png)" +msgstr "PNG Files (*.png)" + +#: src/mainwin.cc:2297 +msgid "Console" +msgstr "Konsole" + +#: src/mainwin.cc:2420 +#, fuzzy +msgid "The document has been modified." +msgstr "" +"The document has been modified.\n" +"Do you want to save your changes?" + +#: src/mainwin.cc:2421 +#, fuzzy +msgid "Do you want to save your changes?" +msgstr "" +"The document has been modified.\n" +"Do you want to save your changes?" + +#~ msgid "MainWindow" +#~ msgstr "MainWindow" + +#~ msgid "Ctrl+P" +#~ msgstr "Ctrl+P" + +#~ msgid "Editor for SCAD code" +#~ msgstr "Editor for SCAD code" + +#~ msgid "Console messages" +#~ msgstr "Console messages" + +#~ msgid "Trimming cache: %1% (%2% bytes)" +#~ msgstr "Trimming cache: %1% (%2% bytes)" + +#~ msgid "WARNING: CGAL NefPolyhedron Triangulation failed: %s" +#~ msgstr "WARNING: CGAL NefPolyhedron Triangulation failed: %s" + +#~ msgid "Error: CSG generation failed! (no top level object found)" +#~ msgstr "Error: CSG generation failed! (no top level object found)" + +#~ msgid "Compiling design (CSG Products normalization)..." +#~ msgstr "Compiling design (CSG Products normalization)..." + +#~ msgid "Normalized CSG tree has %d elements" +#~ msgstr "Normalized CSG tree has %d elements" + +#~ msgid "WARNING: CSG normalization resulted in an empty tree" +#~ msgstr "WARNING: CSG normalization resulted in an empty tree" + +#~ msgid "Compiling highlights (%i CSG Trees)..." +#~ msgstr "Compiling highlights (%i CSG Trees)..." + +#~ msgid "Compiling background (%i CSG Trees)..." +#~ msgstr "Compiling background (%i CSG Trees)..." + +#~ msgid "CGAL Cache hit: %s (%d bytes)" +#~ msgstr "CGAL Cache hit: %s (%d bytes)" + +#~ msgid "CGAL Cache insert: %s (%d bytes)" +#~ msgstr "CGAL Cache insert: %s (%d bytes)" + +#~ msgid "CGAL Cache insert failed: %s (%d bytes)" +#~ msgstr "CGAL Cache insert failed: %s (%d bytes)" + +#~ msgid "CGAL Polyhedrons in cache: %d" +#~ msgstr "CGAL Polyhedrons im Cache: %d" + +#~ msgid "CGAL cache size in bytes: %d" +#~ msgstr "CGAL Cache Größe in Bytes: %d" + +#~ msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +#~ msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." + +#~ msgid "ERROR: %s" +#~ msgstr "ERROR: %s" + +#~ msgid "Warning: Scaling a 3D object with 0 - removing object" +#~ msgstr "Warning: Scaling a 3D object with 0 - removing object" + +#~ msgid "" +#~ "Hull() currently requires a valid 2-manifold. Please modify your design. " +#~ "See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/" +#~ "STL_Import_and_Export" +#~ msgstr "" +#~ "Hull() currently requires a valid 2-manifold. Please modify your design. " +#~ "See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/" +#~ "STL_Import_and_Export" + +#~ msgid "ERROR: Unsupported CGAL operator: %d" +#~ msgstr "ERROR: Unsupported CGAL operator: %d" + +#~ msgid "CGAL error in CGALUtils::applyBinaryOperator %s: %s" +#~ msgstr "CGAL error in CGALUtils::applyBinaryOperator %s: %s" + +#~ msgid "CGALUtils::project during plane intersection: %s" +#~ msgstr "CGALUtils::project during plane intersection: %s" + +#~ msgid "Trying alternative intersection using very large thin box: " +#~ msgstr "Trying alternative intersection using very large thin box: " + +#~ msgid "CGAL error in CGALUtils::project during bigbox intersection: %s" +#~ msgstr "CGAL error in CGALUtils::project during bigbox intersection: %s" + +#~ msgid "WARNING: projection() failed." +#~ msgstr "WARNING: projection() failed." + +#~ msgid "CGAL error in CGALUtils::project while flattening: %s" +#~ msgstr "CGAL error in CGALUtils::project while flattening: %s" + +#~ msgid "ERROR: deproject failure" +#~ msgstr "ERROR: deproject failure" + +#~ msgid "ERROR: failed to find projection" +#~ msgstr "ERROR: failed to find projection" + +#~ msgid "input polygon has 3 points. shortcut tessellation." +#~ msgstr "input polygon has 3 points. shortcut tessellation." + +#~ msgid "finding good projection" +#~ msgstr "finding good projection" + +#~ msgid "plane %s" +#~ msgstr "plane %s" + +#~ msgid "proj: %i %i" +#~ msgstr "proj: %i %i" + +#~ msgid "Inserting points and edges into Constrained Delaunay Triangulation" +#~ msgstr "Inserting points and edges into Constrained Delaunay Triangulation" + +#~ msgid "WARNING: Constraint insertion failure %s" +#~ msgstr "WARNING: Constraint insertion failure %s" + +#~ msgid "seeding %i holes" +#~ msgstr "seeding %i holes" + +#~ msgid "seed %f,%f" +#~ msgstr "seed %f,%f" + +#~ msgid "seeding done" +#~ msgstr "seeding done" + +#~ msgid "meshing" +#~ msgstr "meshing" + +#~ msgid "meshing done" +#~ msgstr "meshing done" + +#~ msgid "WARNING: 2d->3d deprojection failure" +#~ msgstr "WARNING: 2d->3d deprojection failure" + +#~ msgid "built %i triangles\n" +#~ msgstr "built %i triangles\n" + +#~ msgid "WARNING: triangle doesn't have 3 points. skipping" +#~ msgstr "WARNING: triangle doesn't have 3 points. skipping" + +#~ msgid "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" +#~ msgstr "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" + +#~ msgid "PolySet has nonplanar faces. Attempting alternate construction" +#~ msgstr "PolySet has nonplanar faces. Attempting alternate construction" + +#~ msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" +#~ msgstr "CGAL error in CGAL_Nef_polyhedron3(): %s" + +#~ msgid "" +#~ "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" +#~ msgstr "" +#~ "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" + +#~ msgid "Rendering cancelled." +#~ msgstr "Rendering cancelled." + +#~ msgid "" +#~ "WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is " +#~ "too large." +#~ msgstr "" +#~ "WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is " +#~ "too large." + +#~ msgid "WARNING: Color name \"%s\" unknown. Please see" +#~ msgstr "WARNING: Color name \"%s\" unknown. Please see" + +#~ msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" +#~ msgstr "WARNING: http://en.wikipedia.org/wiki/Web_colors" + +#~ msgid "WARNING: Attempt to modify constant '%s'." +#~ msgstr "WARNING: Attempt to modify constant '%s'." + +#~ msgid "WARNING: Ignoring unknown variable '%s'." +#~ msgstr "WARNING: Ignoring unknown variable '%s'." + +#~ msgid "WARNING: Ignoring unknown function '%s'." +#~ msgstr "WARNING: Ignoring unknown function '%s'." + +#~ msgid "WARNING: Ignoring unknown module '%s'." +#~ msgstr "WARNING: Ignoring unknown module '%s'." + +#~ msgid "ModuleContext %p (%p) for %s inst (%p)" +#~ msgstr "ModuleContext %p (%p) for %s inst (%p)" + +#~ msgid "Context: %p (%p)" +#~ msgstr "Context: %p (%p)" + +#~ msgid " document path: %s" +#~ msgstr " document path: %s" + +#~ msgid " module args:" +#~ msgstr " module args:" + +#~ msgid " vars:" +#~ msgstr " vars:" + +#~ msgid "" +#~ "WARNING: Bad range parameter in for statement: too many elements (%lu)." +#~ msgstr "" +#~ "WARNING: Bad range parameter in for statement: too many elements (%lu)." + +#~ msgid "" +#~ "WARNING: Bad parameter type (%s) for children, only accept: empty, " +#~ "number, vector, range." +#~ msgstr "" +#~ "WARNING: Bad parameter type (%s) for children, only accept: empty, " +#~ "number, vector, range." + +#~ msgid "WARNING: Negative children index (%d) not allowed" +#~ msgstr "WARNING: Negative children index (%d) not allowed" + +#~ msgid "WARNING: Children index (%d) out of bounds (%d children)" +#~ msgstr "WARNING: Children index (%d) out of bounds (%d children)" + +#~ msgid "WARNING: Negative child index (%d) not allowed" +#~ msgstr "WARNING: Negative child index (%d) not allowed" + +#~ msgid "WARNING: Child index (%d) out of bounds (%d children)" +#~ msgstr "WARNING: Child index (%d) out of bounds (%d children)" + +#~ msgid "WARNING: Bad range parameter for children: too many elements (%lu)." +#~ msgstr "WARNING: Bad range parameter for children: too many elements (%lu)." + +#~ msgid "" +#~ "WARNING: Normalized tree is growing past %d elements. Aborting " +#~ "normalization.\n" +#~ msgstr "" +#~ "WARNING: Normalized tree is growing past %d elements. Aborting " +#~ "normalization.\n" + +#~ msgid "WARNING: Can't open DXF file '%s'." +#~ msgstr "WARNING: Can't open DXF file '%s'." + +#~ msgid "WARNING: Illegal ID '%s' in `%s'" +#~ msgstr "WARNING: Illegal ID '%s' in `%s'" + +#~ msgid "WARNING: Illegal value %s in '%s'" +#~ msgstr "WARNING: Illegal value %s in '%s'" + +#~ msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." +#~ msgstr "WARNING: Unsupported DXF Entity '%s' (%x) in %s." + +#~ msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." +#~ msgstr "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." + +#~ msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" +#~ msgstr "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" + +#~ msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" +#~ msgstr "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" + +#~ msgid "WARNING: Can't find cross in '%s', layer '%s'!" +#~ msgstr "WARNING: Can't find cross in '%s', layer '%s'!" + +#~ msgid "EvalContext %p (%p) for %s inst (%p)" +#~ msgstr "EvalContext %p (%p) for %s inst (%p)" + +#~ msgid " eval args:" +#~ msgstr " eval args:" + +#~ msgid " children:" +#~ msgstr " children:" + +#~ msgid "Object isn't a valid 2-manifold! Modify your design.\n" +#~ msgstr "Object isn't a valid 2-manifold! Modify your design.\n" + +#~ msgid "ERROR: Nef->PolySet failed" +#~ msgstr "ERROR: Nef->PolySet failed" + +#~ msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" +#~ msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" + +#~ msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" +#~ msgstr "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" + +#~ msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" +#~ msgstr "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" + +#~ msgid "ERROR: Recursion detected calling function '%s'" +#~ msgstr "ERROR: Recursion detected calling function '%s'" + +#~ msgid "Enable the concat() function." +#~ msgstr "Funktion concat() aktivieren." + +#~ msgid "WARNING: Ignoring request to enable unknown feature '%s'." +#~ msgstr "WARNING: Ignoring request to enable unknown feature '%s'." + +#~ msgid "" +#~ "WARNING: Imported file (%s) found in document root instead of relative to " +#~ "the importing module. This behavior is deprecated" +#~ msgstr "" +#~ "WARNING: Imported file (%s) found in document root instead of relative to " +#~ "the importing module. This behavior is deprecated" + +#~ msgid " WARNING: search term not found: \"%s\"" +#~ msgstr " WARNING: search term not found: \"%s\"" + +#~ msgid " WARNING: search term not found: %s" +#~ msgstr " WARNING: search term not found: %s" + +#~ msgid " WARNING: search: none performed on input %s" +#~ msgstr " WARNING: search: none performed on input %s" + +#~ msgid "WARNING: Negative parent module index (%d) not allowed" +#~ msgstr "WARNING: Negative parent module index (%d) not allowed" + +#~ msgid "" +#~ "WARNING: Parent module index (%d) greater than the number of modules on " +#~ "the stack" +#~ msgstr "" +#~ "WARNING: Parent module index (%d) greater than the number of modules on " +#~ "the stack" + +#~ msgid "Geometry Cache hit: %s (%d bytes)" +#~ msgstr "Geometry Cache hit: %s (%d bytes)" + +#~ msgid "Geometry Cache insert: %s (%d bytes)" +#~ msgstr "Geometry Cache insert: %s (%d bytes)" + +#~ msgid "Geometry Cache insert failed: %s (%d bytes)" +#~ msgstr "Geometry Cache insert failed: %s (%d bytes)" + +#~ msgid "Geometries in cache: %d" +#~ msgstr "Geometries in cache: %d" + +#~ msgid "Geometry cache size in bytes: %d" +#~ msgstr "Geometry cache size in bytes: %d" + +#~ msgid "WARNING: Mixing 2D and 3D objects is not supported." +#~ msgstr "WARNING: Mixing 2D and 3D objects is not supported." + +#~ msgid "" +#~ "WARNING: Resize in direction normal to flat object is not implemented" +#~ msgstr "" +#~ "WARNING: Resize in direction normal to flat object is not implemented" + +#~ msgid "WARNING: Ignoring 3D child object for 2D operation" +#~ msgstr "WARNING: Ignoring 3D child object for 2D operation" + +#~ msgid "WARNING: GeometryEvaluator: Node didn't fit into cache" +#~ msgstr "WARNING: GeometryEvaluator: Node didn't fit into cache" + +#~ msgid "WARNING: Ignoring 2D child object for 3D operation" +#~ msgstr "WARNING: Ignoring 2D child object for 3D operation" + +#~ msgid "Error: Unknown boolean operation %d" +#~ msgstr "Error: Unknown boolean operation %d" + +#~ msgid "" +#~ "Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +#~ "removing object." +#~ msgstr "" +#~ "Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +#~ "removing object." + +#~ msgid "" +#~ "ERROR: all points for rotate_extrude() must have the same X coordinate " +#~ "sign (range is %.2f -> %.2f)" +#~ msgstr "" +#~ "ERROR: all points for rotate_extrude() must have the same X coordinate " +#~ "sign (range is %.2f -> %.2f)" + +#~ msgid "Can't open dependencies file `%s' for writing!\n" +#~ msgstr "Can't open dependencies file `%s' for writing!\n" + +#~ msgid "DEPRECATED: filename= is deprecated. Please use file=" +#~ msgstr "DEPRECATED: filename= is deprecated. Please use file=" + +#~ msgid "DEPRECATED: layername= is deprecated. Please use layer=" +#~ msgstr "DEPRECATED: layername= is deprecated. Please use layer=" + +#~ msgid "WARNING: Can't open import file '%s'." +#~ msgstr "WARNING: Can't open import file '%s'." + +#~ msgid "WARNING: Can't parse vertex line '%s'." +#~ msgstr "WARNING: Can't parse vertex line '%s'." + +#~ msgid "WARNING: OFF import requires CGAL." +#~ msgstr "WARNING: OFF import requires CGAL." + +#~ msgid "ERROR: Unsupported file format while trying to import file '%s'" +#~ msgstr "ERROR: Unsupported file format while trying to import file '%s'" + +#~ msgid "" +#~ "DEPRECATED: Support for reading files in linear_extrude will be removed " +#~ "in future releases. Use a child import() instead." +#~ msgstr "" +#~ "DEPRECATED: Support for reading files in linear_extrude will be removed " +#~ "in future releases. Use a child import() instead." + +#~ msgid "" +#~ "Copyright (C) 2009-2013 The OpenSCAD Developers\n" +#~ "\n" +#~ "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." +#~ msgstr "" +#~ "Copyright (C) 2009-2013 The OpenSCAD Developers\n" +#~ "\n" +#~ "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." + +#~ msgid "OpenSCAD - New Document[*]" +#~ msgstr "OpenSCAD - Neue Datei[*]" + +#~ msgid "[*]" +#~ msgstr "[*]" + +#~ msgid "Failed to open file %s: %s" +#~ msgstr "Failed to open file %s: %s" + +#~ msgid "Loaded design '%s'." +#~ msgstr "Loaded design '%s'." + +#~ msgid "Module cache size: %d modules" +#~ msgstr "Module cache size: %d modules" + +#~ msgid "Compiling design (CSG Tree generation)..." +#~ msgstr "Compiling design (CSG Tree generation)..." + +#~ msgid "ERROR: Compilation failed! (no top level object found)" +#~ msgstr "ERROR: Compilation failed! (no top level object found)" + +#~ msgid "ERROR: Compilation failed!" +#~ msgstr "ERROR: Compilation failed!" + +#~ msgid "Compiling design (CSG Products generation)..." +#~ msgstr "Compiling design (CSG Products generation)..." + +#~ msgid "ERROR: CSG generation failed! (no top level object found)" +#~ msgstr "ERROR: CSG generation failed! (no top level object found)" + +#~ msgid "CSG generation cancelled." +#~ msgstr "CSG generation cancelled." + +#~ msgid "Compiling highlights (%d CSG Trees)..." +#~ msgstr "Compiling highlights (%d CSG Trees)..." + +#~ msgid "Compiling background (%d CSG Trees)..." +#~ msgstr "Compiling background (%d CSG Trees)..." + +#~ msgid "WARNING: Normalized tree has %d elements!" +#~ msgstr "WARNING: Normalized tree has %d elements!" + +#~ msgid "WARNING: OpenCSG rendering has been disabled." +#~ msgstr "WARNING: OpenCSG rendering has been disabled." + +#~ msgid "CSG generation finished." +#~ msgstr "CSG generation finished." + +#~ msgid "Total rendering time: %d hours, %d minutes, %d seconds" +#~ msgstr "Total rendering time: %d hours, %d minutes, %d seconds" + +#~ msgid "Open File" +#~ msgstr "Open File" + +#~ msgid "OpenSCAD Designs (*.scad *.csg)" +#~ msgstr "OpenSCAD Designs (*.scad *.csg)" + +#~ msgid "Failed to open file for writing: %s (%s)" +#~ msgstr "Failed to open file for writing: %s (%s)" + +#~ msgid "" +#~ "Failed to open file for writing:\n" +#~ " %1 (%2)" +#~ msgstr "" +#~ "Failed to open file for writing:\n" +#~ " %1 (%2)" + +#~ msgid "Saved design '%s'." +#~ msgstr "Saved design '%s'." + +#~ msgid "WARNING: Library path %s doesn't exist. Creating" +#~ msgstr "WARNING: Library path %s doesn't exist. Creating" + +#~ msgid "ERROR: Cannot create library path: %s" +#~ msgstr "ERROR: Cannot create library path: %s" + +#~ msgid "Parsing design (AST generation)..." +#~ msgstr "Parsing design (AST generation)..." + +#~ msgid "frame%05d.png" +#~ msgstr "frame%05d.png" + +#~ msgid "Rendering Polygon Mesh using CGAL..." +#~ msgstr "Rendering Polygon Mesh using CGAL..." + +#~ msgid " Top level object is a 3D object:" +#~ msgstr " Top level object is a 3D object:" + +#~ msgid " Simple: %6s" +#~ msgstr " Simple: %6s" + +#~ msgid "yes" +#~ msgstr "yes" + +#~ msgid "no" +#~ msgstr "no" + +#~ msgid " Valid: %6s" +#~ msgstr " Valid: %6s" + +#~ msgid " Vertices: %6d" +#~ msgstr " Vertices: %6d" + +#~ msgid " Halfedges: %6d" +#~ msgstr " Halfedges: %6d" + +#~ msgid " Edges: %6d" +#~ msgstr " Edges: %6d" + +#~ msgid " Halffacets: %6d" +#~ msgstr " Halffacets: %6d" + +#~ msgid " Facets: %6d" +#~ msgstr " Facets: %6d" + +#~ msgid " Volumes: %6d" +#~ msgstr " Volumes: %6d" + +#~ msgid " Top level object is a 2D object:" +#~ msgstr " Top level object is a 2D object:" + +#~ msgid " Contours: %6d" +#~ msgstr " Contours: %6d" + +#~ msgid "Unknown geometry type" +#~ msgstr "Unknown geometry type" + +#~ msgid "Rendering finished." +#~ msgstr "Rendering finished." + +#~ msgid "WARNING: No top level geometry to render" +#~ msgstr "WARNING: No top level geometry to render" + +#~ msgid "AST Dump" +#~ msgstr "AST Dump" + +#~ msgid "No AST to dump. Please try compiling first..." +#~ msgstr "No AST to dump. Please try compiling first..." + +#~ msgid "CSG Tree Dump" +#~ msgstr "CSG Tree Dump" + +#~ msgid "No CSG to dump. Please try compiling first..." +#~ msgstr "No CSG to dump. Please try compiling first..." + +#~ msgid "CSG Products Dump" +#~ msgstr "CSG Products Dump" + +#~ msgid "" +#~ "\n" +#~ "CSG before normalization:\n" +#~ "%1\n" +#~ "\n" +#~ "\n" +#~ "CSG after normalization:\n" +#~ "%2\n" +#~ "\n" +#~ "\n" +#~ "CSG rendering chain:\n" +#~ "%3\n" +#~ "\n" +#~ "\n" +#~ "Highlights CSG rendering chain:\n" +#~ "%4\n" +#~ "\n" +#~ "\n" +#~ "Background CSG rendering chain:\n" +#~ "%5\n" +#~ msgstr "" +#~ "\n" +#~ "CSG before normalization:\n" +#~ "%1\n" +#~ "\n" +#~ "\n" +#~ "CSG after normalization:\n" +#~ "%2\n" +#~ "\n" +#~ "\n" +#~ "CSG rendering chain:\n" +#~ "%3\n" +#~ "\n" +#~ "\n" +#~ "Highlights CSG rendering chain:\n" +#~ "%4\n" +#~ "\n" +#~ "\n" +#~ "Background CSG rendering chain:\n" +#~ "%5\n" + +#~ msgid "Nothing to export! Try building first (press F6)." +#~ msgstr "Nothing to export! Try building first (press F6)." + +#~ msgid "Current top level object is not a 3D object." +#~ msgstr "Current top level object is not a 3D object." + +#~ msgid "" +#~ "Object isn't a valid 2-manifold! Modify your design. See http://en." +#~ "wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" +#~ msgstr "" +#~ "Object isn't a valid 2-manifold! Modify your design. See http://en." +#~ "wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" + +#~ msgid "Export OFF File" +#~ msgstr "Export OFF File" + +#~ msgid "OFF Files (*.off)" +#~ msgstr "OFF Files (*.off)" + +#~ msgid "No filename specified. %s export aborted." +#~ msgstr "No filename specified. %s export aborted." + +#~ msgid "Can't open file \"%s\" for export" +#~ msgstr "Can't open file \"%s\" for export" + +#~ msgid "%s export finished." +#~ msgstr "%s export finished." + +#~ msgid "Current top level object is not a 2D object." +#~ msgstr "Current top level object is not a 2D object." + +#~ msgid "Export DXF File" +#~ msgstr "Export DXF File" + +#~ msgid "DXF Files (*.dxf)" +#~ msgstr "DXF Files (*.dxf)" + +#~ msgid "No filename specified. DXF export aborted." +#~ msgstr "No filename specified. DXF export aborted." + +#~ msgid "DXF export finished." +#~ msgstr "DXF export finished." + +#~ msgid "Nothing to export. Please try compiling first..." +#~ msgstr "Nothing to export. Please try compiling first..." + +#~ msgid "No filename specified. CSG export aborted." +#~ msgstr "No filename specified. CSG export aborted." + +#~ msgid "CSG export finished." +#~ msgstr "CSG export finished." + +#~ msgid "No filename specified. Image export aborted." +#~ msgstr "No filename specified. Image export aborted." + +#~ msgid "http://openscad.org/" +#~ msgstr "http://openscad.org/" + +#~ msgid "http://www.openscad.org/documentation.html" +#~ msgstr "http://www.openscad.org/documentation.html" + +#~ msgid "OpenGL Info" +#~ msgstr "OpenGL Info" + +#~ msgid "WARNING: Experimental builtin function '%s' is not enabled." +#~ msgstr "WARNING: Experimental builtin function '%s' is not enabled." + +#~ msgid "WARNING: Experimental builtin module '%s' is not enabled." +#~ msgstr "WARNING: Experimental builtin module '%s' is not enabled." + +#~ msgid "" +#~ "DEPRECATED: The %s() module will be removed in future releases. Use %s() " +#~ "instead." +#~ msgstr "" +#~ "DEPRECATED: The %s() module will be removed in future releases. Use %s() " +#~ "instead." + +#~ msgid "ModuleContext %p (%p) for %s inst (%p) " +#~ msgstr "ModuleContext %p (%p) for %s inst (%p) " + +#~ msgid "ModuleContext: %p (%p)" +#~ msgstr "ModuleContext: %p (%p)" + +#~ msgid "New lib Context for %s func:" +#~ msgstr "New lib Context for %s func:" + +#~ msgid "New file Context:" +#~ msgstr "New file Context:" + +#~ msgid "Recompiling cached library: %s (%s)" +#~ msgstr "Recompiling cached library: %s (%s)" + +#~ msgid "Compiling library '%s'." +#~ msgstr "Compiling library '%s'." + +#~ msgid "WARNING: Can't open library file '%s'\n" +#~ msgstr "WARNING: Can't open library file '%s'\n" + +#~ msgid " compiled module: %p" +#~ msgstr " compiled module: %p" + +#~ msgid "New eval ctx:" +#~ msgstr "New eval ctx:" + +#~ msgid "ERROR: Recursion detected calling module '%s'" +#~ msgstr "ERROR: Recursion detected calling module '%s'" + +#~ msgid "WARNING: Failed to compile library '%s'." +#~ msgstr "WARNING: Failed to compile library '%s'." + +#~ msgid "OpenSCAD recommended OpenGL version is 2.0." +#~ msgstr "Die empfohlene OpenGL version für OpenSCAD ist 2.0." + +#~ msgid "" +#~ "Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" +#~ "%2%[ -m make_command ] [ -D var=val [..] ] \\\n" +#~ "%2%[ --version ] [ --info ] \\\n" +#~ "%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" +#~ "%2% --camera=eyex,y,z,centerx,y,z ] \\\n" +#~ "%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" +#~ "%2%[ --render | --preview[=throwntogether] ] \\\n" +#~ "%2%[ --enable= ] \\\n" +#~ "%2%filename\n" +#~ msgstr "" +#~ "Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" +#~ "%2%[ -m make_command ] [ -D var=val [..] ] \\\n" +#~ "%2%[ --version ] [ --info ] \\\n" +#~ "%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" +#~ "%2% --camera=eyex,y,z,centerx,y,z ] \\\n" +#~ "%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" +#~ "%2%[ --render | --preview[=throwntogether] ] \\\n" +#~ "%2%[ --enable= ] \\\n" +#~ "%2%filename\n" + +#~ msgid "OpenSCAD version %s\n" +#~ msgstr "OpenSCAD version %s\n" + +#~ msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" +#~ msgstr "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" + +#~ msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" +#~ msgstr "Camera setup requires either 7 numbers for Gimbal Camera\n" + +#~ msgid "or 6 numbers for Vector Camera\n" +#~ msgstr "or 6 numbers for Vector Camera\n" + +#~ msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" +#~ msgstr "projection needs to be 'o' or 'p' for ortho or perspective\n" + +#~ msgid "Need 2 numbers for imgsize\n" +#~ msgstr "Need 2 numbers for imgsize\n" + +#~ msgid "Unknown suffix for output file %s\n" +#~ msgstr "Unknown suffix for output file %s\n" + +#~ msgid "Can't open input file '%s'!\n" +#~ msgstr "Can't open input file '%s'!\n" + +#~ msgid "Can't parse file '%s'!\n" +#~ msgstr "Can't parse file '%s'!\n" + +#~ msgid "Output file:%s\n" +#~ msgstr "Output file:%s\n" + +#~ msgid "Sorry, don't know how to write deps for that file type. Exiting\n" +#~ msgstr "Sorry, don't know how to write deps for that file type. Exiting\n" + +#~ msgid "error writing deps" +#~ msgstr "error writing deps" + +#~ msgid "Current top level object is not a 3D object.\n" +#~ msgstr "Current top level object is not a 3D object.\n" + +#~ msgid "Current top level object is not a 2D object.\n" +#~ msgstr "Current top level object is not a 2D object.\n" + +#~ msgid "Allowed options" +#~ msgstr "Allowed options" + +#~ msgid "help message" +#~ msgstr "help message" + +#~ msgid "print the version" +#~ msgstr "print the version" + +#~ msgid "print information about the building process" +#~ msgstr "print information about the building process" + +#~ msgid "if exporting a png image, do a full CGAL render" +#~ msgstr "if exporting a png image, do a full CGAL render" + +#~ msgid "" +#~ "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" +#~ msgstr "" +#~ "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" + +#~ msgid "parameters for camera when exporting png" +#~ msgstr "parameters for camera when exporting png" + +#~ msgid "=width,height for exporting png" +#~ msgstr "=width,height for exporting png" + +#~ msgid "(o)rtho or (p)erspective when exporting png" +#~ msgstr "(o)rtho or (p)erspective when exporting png" + +#~ msgid "out-file" +#~ msgstr "out-file" + +#~ msgid "stl-file" +#~ msgstr "stl-file" + +#~ msgid "dxf-file" +#~ msgstr "dxf-file" + +#~ msgid "deps-file" +#~ msgstr "deps-file" + +#~ msgid "makefile" +#~ msgstr "makefile" + +#~ msgid "var=val" +#~ msgstr "var=val" + +#~ msgid "enable experimental features" +#~ msgstr "enable experimental features" + +#~ msgid "Hidden options" +#~ msgstr "Hidden options" + +#~ msgid "input file" +#~ msgstr "input file" + +#~ msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" +#~ msgstr "DEPRECATED: The -s option is deprecated. Use -o instead.\n" + +#~ msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" +#~ msgstr "DEPRECATED: The -x option is deprecated. Use -o instead.\n" + +#~ msgid "Requested GUI mode but can't open display!\n" +#~ msgstr "Requested GUI mode but can't open display!\n" + +#~ msgid "ERROR: Cannot create %s" +#~ msgstr "ERROR: Cannot create %s" + +#~ msgid "PolySet:" +#~ msgstr "PolySet:" + +#~ msgid "" +#~ "\n" +#~ " dimensions:" +#~ msgstr "" +#~ "\n" +#~ " dimensions:" + +#~ msgid "" +#~ "\n" +#~ " convexity:" +#~ msgstr "" +#~ "\n" +#~ " convexity:" + +#~ msgid "" +#~ "\n" +#~ " num polygons: " +#~ msgstr "" +#~ "\n" +#~ " num polygons: " + +#~ msgid "" +#~ "\n" +#~ " num outlines: " +#~ msgstr "" +#~ "\n" +#~ " num outlines: " + +#~ msgid "" +#~ "\n" +#~ " polygons data:" +#~ msgstr "" +#~ "\n" +#~ " polygons data:" + +#~ msgid "" +#~ "\n" +#~ " polygon begin:" +#~ msgstr "" +#~ "\n" +#~ " polygon begin:" + +#~ msgid "" +#~ "\n" +#~ " vertex:" +#~ msgstr "" +#~ "\n" +#~ " vertex:" + +#~ msgid "" +#~ "\n" +#~ " outlines data:" +#~ msgstr "" +#~ "\n" +#~ " outlines data:" + +#~ msgid "" +#~ "\n" +#~ "PolySet end" +#~ msgstr "" +#~ "\n" +#~ "PolySet end" + +#~ msgid "" +#~ "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." +#~ msgstr "" +#~ "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." + +#~ msgid "WARNING: $fs too small - clamping to %f" +#~ msgstr "WARNING: $fs too small - clamping to %f" + +#~ msgid "WARNING: $fa too small - clamping to %f" +#~ msgstr "WARNING: $fa too small - clamping to %f" + +#~ msgid "" +#~ "DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. " +#~ "Use polyhedron(faces=[]) instead." +#~ msgstr "" +#~ "DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. " +#~ "Use polyhedron(faces=[]) instead." + +#~ msgid "ERROR: Unable to convert point at index %d to a vec3 of numbers" +#~ msgstr "ERROR: Unable to convert point at index %d to a vec3 of numbers" + +#~ msgid "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" +#~ msgstr "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" + +#~ msgid "" +#~ "DEPRECATED: Support for reading files in rotate_extrude will be removed " +#~ "in future releases. Use a child import() instead." +#~ msgstr "" +#~ "DEPRECATED: Support for reading files in rotate_extrude will be removed " +#~ "in future releases. Use a child import() instead." + +#~ msgid "WARNING: Can't open DAT file '%s'." +#~ msgstr "WARNING: Can't open DAT file '%s'." + +#~ msgid "WARNING: Illegal value in '%s': %s" +#~ msgstr "WARNING: Illegal value in '%s': %s" + +#~ msgid "" +#~ "DEPRECATED: Using ranges of the form [begin:end] with begin value greater " +#~ "than the end value is deprecated." +#~ msgstr "" +#~ "DEPRECATED: Using ranges of the form [begin:end] with begin value greater " +#~ "than the end value is deprecated." + +#~ msgid "&Compile" +#~ msgstr "Übersetzen" + +#~ msgid "Compile and &Render (CGAL)" +#~ msgstr "Übersetzen und Rendern (CGAL)" + +#~ msgid "CGAL Grid Only" +#~ msgstr "CGAL Gitter anzeigen" + +#~ msgid " vertices:" +#~ msgstr " vertices:" + +#~ msgid "{ Outer boundary = " +#~ msgstr "{ Outer boundary = " + +#~ msgid "{ Unbounded polygon." +#~ msgstr "{ Unbounded polygon." + +#~ msgid " holes:" +#~ msgstr " holes:" + +#~ msgid " Hole #" +#~ msgstr " Hole #" + +#~ msgid "" +#~ "WARNING: minkowski() and hull() is not implemented for 2d objects with " +#~ "holes!" +#~ msgstr "" +#~ "WARNING: minkowski() and hull() is not implemented for 2d objects with " +#~ "holes!" + +#~ msgid "WARNING: minkowski() could not get any points from object 1!" +#~ msgstr "WARNING: minkowski() could not get any points from object 1!" + +#~ msgid "WARNING: minkowski() could not get any points from object 2!" +#~ msgstr "WARNING: minkowski() could not get any points from object 2!" + +#~ msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +#~ msgstr "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" + +#~ msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +#~ msgstr "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" + +#~ msgid "WARNING: Cannot resize to sizes less than 0." +#~ msgstr "WARNING: Cannot resize to sizes less than 0." + +#~ msgid "WARNING: glide() is not implemented yet!" +#~ msgstr "WARNING: glide() is not implemented yet!" + +#~ msgid "WARNING: subdiv() is not implemented yet!" +#~ msgstr "WARNING: subdiv() is not implemented yet!" + +#~ msgid "Warning: Scaling a 2D object with 0 - removing object" +#~ msgstr "Warning: Scaling a 2D object with 0 - removing object" + +#~ msgid "" +#~ "WARNING: Duplicate vertices and/or intersecting lines found during DXF " +#~ "Tessellation." +#~ msgstr "" +#~ "WARNING: Duplicate vertices and/or intersecting lines found during DXF " +#~ "Tessellation." + +#~ msgid "" +#~ "WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." +#~ msgstr "" +#~ "WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." + +#~ msgid "CGAL error in dxf_tesselate(): %s" +#~ msgstr "CGAL error in dxf_tesselate(): %s" + +#~ msgid "CGAL error in dxftess triangulate_polygon: %s" +#~ msgstr "CGAL error in dxftess triangulate_polygon: %s" + +#~ msgid "WARNING: PolySet has polygon with <3 points" +#~ msgstr "WARNING: PolySet has polygon with <3 points" + +#~ msgid "WARNING: PolySet has degenerate polygon" +#~ msgstr "WARNING: PolySet has degenerate polygon" + +#~ msgid "GLU tesselation error %s" +#~ msgstr "GLU tesselation error %s" + +#~ msgid "WARNING: No suitable PolySetEvaluator found for %s module!" +#~ msgstr "WARNING: No suitable PolySetEvaluator found for %s module!" + +#~ msgid " Empty: %6s" +#~ msgstr " Empty: %6s" + +#~ msgid " Plane: %6s" +#~ msgstr " Plane: %6s" + +#~ msgid " Faces: %6d" +#~ msgstr " Faces: %6d" + +#~ msgid " FaceCycles: %6d" +#~ msgstr " FaceCycles: %6d" + +#~ msgid "" +#~ "\n" +#~ " num borders: " +#~ msgstr "" +#~ "\n" +#~ " num borders: " + +#~ msgid "" +#~ "\n" +#~ " borders data:" +#~ msgstr "" +#~ "\n" +#~ " borders data:" + +#~ msgid "" +#~ "\n" +#~ " border polygon begin:" +#~ msgstr "" +#~ "\n" +#~ " border polygon begin:" + +#~ msgid "" +#~ "WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify " +#~ "your design.." +#~ msgstr "" +#~ "WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify " +#~ "your design.." + +#~ msgid "ERROR: linear_extrude() is not defined for 3D child objects!" +#~ msgstr "ERROR: linear_extrude() is not defined for 3D child objects!" + +#~ msgid "" +#~ "WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" +#~ msgstr "" +#~ "WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" + +#~ msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" +#~ msgstr "ERROR: rotate_extrude() is not defined for 3D child objects!" + +#~ msgid "WARNING: Body of render() isn't valid 2-manifold!" +#~ msgstr "WARNING: Body of render() isn't valid 2-manifold!" #~ msgid "GLEW Error: %s\n" #~ msgstr "GLEW Error: %s\n" diff --git a/po/fr.po b/po/fr.po index 7663a6b4..b1958f6a 100644 --- a/po/fr.po +++ b/po/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2013.02.07\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-09 18:17+0100\n" +"POT-Creation-Date: 2014-01-31 21:18+0100\n" "PO-Revision-Date: 2013-02-08 15:06-0600\n" "Last-Translator: don bright \n" "Language-Team: French\n" @@ -18,10 +18,6 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Poedit-SourceCharset: utf-8\n" -#: objects/ui_AboutDialog.h:51 -msgid "About OpenSCAD" -msgstr "" - #: objects/ui_MainWindow.h:470 msgid "MainWindow" msgstr "" @@ -179,7 +175,7 @@ msgid "Hide editor" msgstr "" #: objects/ui_MainWindow.h:509 -msgid "&Reload and Compile" +msgid "&Reload and Preview" msgstr "" #: objects/ui_MainWindow.h:510 @@ -187,7 +183,7 @@ msgid "F4" msgstr "" #: objects/ui_MainWindow.h:511 -msgid "&Compile" +msgid "&Preview" msgstr "" #: objects/ui_MainWindow.h:512 @@ -195,7 +191,7 @@ msgid "F5" msgstr "" #: objects/ui_MainWindow.h:513 -msgid "Compile and &Render (CGAL)" +msgid "&Render" msgstr "" #: objects/ui_MainWindow.h:514 @@ -222,8 +218,8 @@ msgstr "" msgid "Export as &OFF..." msgstr "" -#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 -msgid "OpenCSG" +#: objects/ui_MainWindow.h:520 +msgid "Preview" msgstr "" #: objects/ui_MainWindow.h:521 @@ -231,7 +227,7 @@ msgid "F9" msgstr "" #: objects/ui_MainWindow.h:522 -msgid "CGAL Surfaces" +msgid "Surfaces" msgstr "" #: objects/ui_MainWindow.h:523 @@ -239,7 +235,7 @@ msgid "F10" msgstr "" #: objects/ui_MainWindow.h:524 -msgid "CGAL Grid Only" +msgid "Wireframe" msgstr "" #: objects/ui_MainWindow.h:525 @@ -374,7 +370,7 @@ msgstr "" msgid "Export as DXF..." msgstr "" -#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:558 msgid "Close" msgstr "Fermer" @@ -382,7 +378,7 @@ msgstr "Fermer" msgid "Ctrl+W" msgstr "" -#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:517 msgid "Preferences" msgstr "Préférences" @@ -395,7 +391,7 @@ msgid "OpenSCAD Homepage" msgstr "" #: objects/ui_MainWindow.h:563 -msgid "Automatic Reload and Compile" +msgid "Automatic Reload and Preview" msgstr "" #: objects/ui_MainWindow.h:564 @@ -422,7 +418,7 @@ msgstr "" msgid "Reset View" msgstr "" -#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 +#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:520 msgid "Editor" msgstr "" @@ -482,150 +478,123 @@ msgstr "&Vue" msgid "&Help" msgstr "&Aide" -#: objects/ui_OpenCSGWarningDialog.h:86 -#, fuzzy -msgid "OpenGL Warning" -msgstr "Information OpenGL" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "" - -#: objects/ui_Preferences.h:515 +#: objects/ui_Preferences.h:518 #, fuzzy msgid "3D View" msgstr "&Vue" -#: objects/ui_Preferences.h:516 +#: objects/ui_Preferences.h:519 msgid "Advanced" msgstr "" -#: objects/ui_Preferences.h:518 +#: objects/ui_Preferences.h:521 msgid "Update" msgstr "" -#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +#: objects/ui_Preferences.h:522 objects/ui_Preferences.h:550 msgid "Features" msgstr "" -#: objects/ui_Preferences.h:521 +#: objects/ui_Preferences.h:524 msgid "Enable/Disable experimental features" msgstr "" -#: objects/ui_Preferences.h:523 +#: objects/ui_Preferences.h:526 msgid "Color scheme:" msgstr "" -#: objects/ui_Preferences.h:528 +#: objects/ui_Preferences.h:531 msgid "Cornfield" msgstr "" -#: objects/ui_Preferences.h:530 +#: objects/ui_Preferences.h:533 msgid "Metallic" msgstr "" -#: objects/ui_Preferences.h:532 +#: objects/ui_Preferences.h:535 msgid "Sunset" msgstr "" -#: objects/ui_Preferences.h:535 +#: objects/ui_Preferences.h:538 msgid "Font" msgstr "" -#: objects/ui_Preferences.h:536 +#: objects/ui_Preferences.h:539 msgid "Color syntax highlighting" msgstr "" -#: objects/ui_Preferences.h:539 -msgid "For Light Background" -msgstr "" - -#: objects/ui_Preferences.h:540 -msgid "For Dark Background" -msgstr "" - -#: objects/ui_Preferences.h:541 +#: objects/ui_Preferences.h:542 msgid "Off" msgstr "" #: objects/ui_Preferences.h:543 -msgid "Automatically check for updates" +msgid "For Light Background" msgstr "" #: objects/ui_Preferences.h:544 -msgid "Include development snapshots" -msgstr "" - -#: objects/ui_Preferences.h:545 -msgid "Check Now" +msgid "For Dark Background" msgstr "" #: objects/ui_Preferences.h:546 -msgid "Last checked: " +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:547 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:548 +msgid "Check Now" msgstr "" #: objects/ui_Preferences.h:549 -msgid "Show capability warning" -msgstr "" - -#: objects/ui_Preferences.h:550 -msgid "Enable for OpenGL 1.x" +msgid "Last checked: " msgstr "" #: objects/ui_Preferences.h:551 -msgid "Turn off rendering at " +msgid "OpenCSG" msgstr "" #: objects/ui_Preferences.h:552 -msgid "elements" +msgid "Show capability warning" msgstr "" #: objects/ui_Preferences.h:553 -msgid "Force Goldfeather" +msgid "Enable for OpenGL 1.x" msgstr "" #: objects/ui_Preferences.h:554 -msgid "CGAL Cache size" +msgid "Turn off rendering at " msgstr "" -#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 -msgid "bytes" +#: objects/ui_Preferences.h:555 +msgid "elements" msgstr "" #: objects/ui_Preferences.h:556 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:557 +msgid "CGAL Cache size" +msgstr "" + +#: objects/ui_Preferences.h:558 objects/ui_Preferences.h:560 +msgid "bytes" +msgstr "" + +#: objects/ui_Preferences.h:559 msgid "PolySet Cache size" msgstr "" -#: objects/ui_Preferences.h:558 +#: objects/ui_Preferences.h:561 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" + +#: objects/ui_Preferences.h:562 msgid "toolBar" msgstr "" -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "" - #: src/AboutDialog.h:16 msgid "About OpenSCAD " msgstr "" @@ -634,24 +603,25 @@ msgstr "" msgid "Trimming cache: %1% (%2% bytes)" msgstr "" -#: src/CGAL_Nef3_workaround.h:255 -msgid "ERROR: CGAL NefPolyhedron Triangulation failed" +#: src/CGAL_Nef3_workaround.h:256 +#, c-format +msgid "WARNING: CGAL NefPolyhedron Triangulation failed: %s" msgstr "" #: src/CsgInfo.h:48 msgid "Error: CSG generation failed! (no top level object found)" msgstr "" -#: src/CsgInfo.h:53 src/mainwin.cc:821 +#: src/CsgInfo.h:53 src/mainwin.cc:818 msgid "Compiling design (CSG Products normalization)..." msgstr "" -#: src/CsgInfo.h:60 src/mainwin.cc:868 +#: src/CsgInfo.h:60 src/mainwin.cc:865 #, c-format msgid "Normalized CSG tree has %d elements" msgstr "" -#: src/CsgInfo.h:64 src/mainwin.cc:833 +#: src/CsgInfo.h:64 src/mainwin.cc:830 msgid "WARNING: CSG normalization resulted in an empty tree" msgstr "" @@ -665,39 +635,6 @@ msgstr "" msgid "Compiling background (%i CSG Trees)..." msgstr "" -#: src/cgaladv_minkowski2.cc:43 -msgid " vertices:" -msgstr "" - -#: src/cgaladv_minkowski2.cc:55 -msgid "{ Outer boundary = " -msgstr "" - -#: src/cgaladv_minkowski2.cc:58 -msgid "{ Unbounded polygon." -msgstr "" - -#: src/cgaladv_minkowski2.cc:63 -msgid " holes:" -msgstr "" - -#: src/cgaladv_minkowski2.cc:65 -msgid " Hole #" -msgstr "" - -#: src/cgaladv_minkowski2.cc:90 -msgid "" -"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" -msgstr "" - -#: src/cgaladv_minkowski2.cc:123 -msgid "WARNING: minkowski() could not get any points from object 1!" -msgstr "" - -#: src/cgaladv_minkowski2.cc:126 -msgid "WARNING: minkowski() could not get any points from object 2!" -msgstr "" - #: src/CGALCache.cc:15 #, c-format msgid "CGAL Cache hit: %s (%d bytes)" @@ -723,88 +660,147 @@ msgstr "" msgid "CGAL cache size in bytes: %d" msgstr "" -#: src/CGALEvaluator.cc:89 +#: src/CGAL_Nef_polyhedron.cc:74 src/cgalutils.cc:44 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +msgstr "" + +#: src/CGAL_Nef_polyhedron.cc:75 src/cgalutils.cc:45 src/PlatformUtils.cc:19 #, c-format -msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +msgid "ERROR: %s" msgstr "" -#: src/CGALEvaluator.cc:141 -msgid "WARNING: hull() does not support mixing 2D and 3D objects." +#: src/CGAL_Nef_polyhedron_DxfData.cc:49 +msgid "Warning: Scaling a 3D object with 0 - removing object" msgstr "" -#: src/CGALEvaluator.cc:159 +#: src/cgalutils.cc:30 msgid "" "Hull() currently requires a valid 2-manifold. Please modify your design. See " "http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" -#: src/CGALEvaluator.cc:172 +#: src/cgalutils.cc:107 #, c-format -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +msgid "ERROR: Unsupported CGAL operator: %d" msgstr "" -#: src/CGALEvaluator.cc:207 -msgid "WARNING: Cannot resize to sizes less than 0." +#: src/cgalutils.cc:113 +#, c-format +msgid "CGAL error in CGALUtils::applyBinaryOperator %s: %s" msgstr "" -#: src/CGALEvaluator.cc:234 -msgid "WARNING: Resize in direction normal to flat object is not implemented" +#: src/cgalutils.cc:159 +#, c-format +msgid "CGALUtils::project during plane intersection: %s" msgstr "" -#: src/CGALEvaluator.cc:336 -msgid "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." +#: src/cgalutils.cc:161 +msgid "Trying alternative intersection using very large thin box: " msgstr "" -#: src/CGALEvaluator.cc:384 -msgid "WARNING: glide() is not implemented yet!" +#: src/cgalutils.cc:176 +#, c-format +msgid "CGAL error in CGALUtils::project during bigbox intersection: %s" msgstr "" -#: src/CGALEvaluator.cc:388 -msgid "WARNING: subdiv() is not implemented yet!" +#: src/cgalutils.cc:182 +msgid "WARNING: projection() failed." msgstr "" -#: src/CGALEvaluator.cc:422 -msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" +#: src/cgalutils.cc:204 +#, c-format +msgid "CGAL error in CGALUtils::project while flattening: %s" msgstr "" -#: src/CGALEvaluator.cc:693 +#: src/cgalutils.cc:496 +msgid "ERROR: deproject failure" +msgstr "" + +#: src/cgalutils.cc:582 +msgid "ERROR: failed to find projection" +msgstr "" + +#: src/cgalutils.cc:593 +msgid "input polygon has 3 points. shortcut tessellation." +msgstr "" + +#: src/cgalutils.cc:605 +msgid "finding good projection" +msgstr "" + +#: src/cgalutils.cc:608 +#, c-format +msgid "plane %s" +msgstr "" + +#: src/cgalutils.cc:609 +#, c-format +msgid "proj: %i %i" +msgstr "" + +#: src/cgalutils.cc:610 +msgid "Inserting points and edges into Constrained Delaunay Triangulation" +msgstr "" + +#: src/cgalutils.cc:632 +#, c-format +msgid "WARNING: Constraint insertion failure %s" +msgstr "" + +#: src/cgalutils.cc:639 +#, c-format +msgid "seeding %i holes" +msgstr "" + +#: src/cgalutils.cc:660 +#, c-format +msgid "seed %f,%f" +msgstr "" + +#: src/cgalutils.cc:662 +msgid "seeding done" +msgstr "" + +#: src/cgalutils.cc:664 +msgid "meshing" +msgstr "" + +#: src/cgalutils.cc:669 +msgid "meshing done" +msgstr "" + +#: src/cgalutils.cc:690 +msgid "WARNING: 2d->3d deprojection failure" +msgstr "" + +#: src/cgalutils.cc:698 +#, c-format +msgid "built %i triangles\n" +msgstr "" + +#: src/cgalutils.cc:741 +msgid "WARNING: triangle doesn't have 3 points. skipping" +msgstr "" + +#: src/cgalutils.cc:941 +#, c-format +msgid "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" +msgstr "" + +#: src/cgalutils.cc:1021 msgid "PolySet has nonplanar faces. Attempting alternate construction" msgstr "" -#: src/CGALEvaluator.cc:697 +#: src/cgalutils.cc:1025 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" msgstr "" -#: src/CGALEvaluator.cc:708 +#: src/cgalutils.cc:1036 #, c-format msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" msgstr "" -#: src/CGAL_Nef_polyhedron.cc:113 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." -msgstr "" - -#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 -#, c-format -msgid "ERROR: %s" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:107 -msgid "Warning: Scaling a 2D object with 0 - removing object" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:137 -msgid "Warning: Scaling a 3D object with 0 - removing object" -msgstr "" - -#: src/cgalutils.cc:138 -#, c-format -msgid "CGAL error in CGAL_Build_PolySet: %s" -msgstr "" - #: src/cgalworker.cc:36 msgid "Rendering cancelled." msgstr "" @@ -912,27 +908,27 @@ msgid "" "normalization.\n" msgstr "" -#: src/dxfdata.cc:83 +#: src/dxfdata.cc:84 #, c-format msgid "WARNING: Can't open DXF file '%s'." msgstr "" -#: src/dxfdata.cc:147 +#: src/dxfdata.cc:148 #, c-format msgid "WARNING: Illegal ID '%s' in `%s'" msgstr "" -#: src/dxfdata.cc:386 +#: src/dxfdata.cc:387 #, c-format msgid "WARNING: Illegal value %s in '%s'" msgstr "" -#: src/dxfdata.cc:392 +#: src/dxfdata.cc:393 #, c-format msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." msgstr "" -#: src/dxfdata.cc:395 +#: src/dxfdata.cc:396 #, c-format msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." msgstr "" @@ -952,40 +948,6 @@ msgstr "" msgid "WARNING: Can't find cross in '%s', layer '%s'!" msgstr "" -#: src/dxftess-cgal.cc:170 -msgid "" -"WARNING: Duplicate vertices and/or intersecting lines found during DXF " -"Tessellation." -msgstr "" - -#: src/dxftess-cgal.cc:171 -msgid "" -"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." -msgstr "" - -#: src/dxftess-cgal.cc:176 -#, c-format -msgid "CGAL error in dxf_tesselate(): %s" -msgstr "" - -#: src/dxftess-cgal.cc:475 -#, c-format -msgid "CGAL error in dxftess triangulate_polygon: %s" -msgstr "" - -#: src/dxftess-cgal.cc:491 -msgid "WARNING: PolySet has polygon with <3 points" -msgstr "" - -#: src/dxftess-cgal.cc:496 -msgid "WARNING: PolySet has degenerate polygon" -msgstr "" - -#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 -#, c-format -msgid "GLU tesselation error %s" -msgstr "" - #: src/evalcontext.cc:38 #, c-format msgid "EvalContext %p (%p) for %s inst (%p)" @@ -999,19 +961,32 @@ msgstr "" msgid " children:" msgstr "" -#: src/export.cc:48 +#: src/export.cc:180 src/export.cc:225 +msgid "Object isn't a valid 2-manifold! Modify your design.\n" +msgstr "" + +#: src/export.cc:187 +msgid "ERROR: Nef->PolySet failed" +msgstr "" + +#: src/export.cc:199 msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" msgstr "" -#: src/export.cc:120 src/export.cc:137 +#: src/export.cc:205 src/export.cc:234 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" msgstr "" -#: src/export.cc:123 +#: src/export.cc:208 msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" msgstr "" +#: src/expr.cc:166 +#, c-format +msgid "ERROR: Recursion detected calling function '%s'" +msgstr "" + #: src/feature.cc:21 msgid "Enable the concat() function." msgstr "" @@ -1055,6 +1030,69 @@ msgid "" "stack" msgstr "" +#: src/GeometryCache.cc:14 +#, c-format +msgid "Geometry Cache hit: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:24 +#, c-format +msgid "Geometry Cache insert: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:26 +#, c-format +msgid "Geometry Cache insert failed: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:44 +#, c-format +msgid "Geometries in cache: %d" +msgstr "" + +#: src/GeometryCache.cc:45 +#, c-format +msgid "Geometry cache size in bytes: %d" +msgstr "" + +#: src/GeometryEvaluator.cc:76 +msgid "WARNING: Mixing 2D and 3D objects is not supported." +msgstr "" + +#: src/GeometryEvaluator.cc:188 +msgid "WARNING: Resize in direction normal to flat object is not implemented" +msgstr "" + +#: src/GeometryEvaluator.cc:252 +msgid "WARNING: Ignoring 3D child object for 2D operation" +msgstr "" + +#: src/GeometryEvaluator.cc:276 +msgid "WARNING: GeometryEvaluator: Node didn't fit into cache" +msgstr "" + +#: src/GeometryEvaluator.cc:324 +msgid "WARNING: Ignoring 2D child object for 3D operation" +msgstr "" + +#: src/GeometryEvaluator.cc:365 +#, c-format +msgid "Error: Unknown boolean operation %d" +msgstr "" + +#: src/GeometryEvaluator.cc:517 +msgid "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." +msgstr "" + +#: src/GeometryEvaluator.cc:765 +#, c-format +msgid "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" +msgstr "" + #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" @@ -1068,21 +1106,21 @@ msgstr "" msgid "DEPRECATED: layername= is deprecated. Please use layer=" msgstr "" -#: src/import.cc:195 src/import.cc:281 +#: src/import.cc:201 src/import.cc:286 #, c-format msgid "WARNING: Can't open import file '%s'." msgstr "" -#: src/import.cc:247 +#: src/import.cc:251 #, c-format msgid "WARNING: Can't parse vertex line '%s'." msgstr "" -#: src/import.cc:292 +#: src/import.cc:295 msgid "WARNING: OFF import requires CGAL." msgstr "" -#: src/import.cc:306 +#: src/import.cc:305 #, c-format msgid "ERROR: Unsupported file format while trying to import file '%s'" msgstr "" @@ -1093,12 +1131,7 @@ msgid "" "future releases. Use a child import() instead." msgstr "" -#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 -#, c-format -msgid "WARNING: No suitable PolySetEvaluator found for %s module!" -msgstr "" - -#: src/mainwin.cc:119 +#: src/mainwin.cc:118 msgid "" "Copyright (C) 2009-2013 The OpenSCAD Developers\n" "\n" @@ -1108,272 +1141,254 @@ msgid "" "any later version." msgstr "" -#: src/mainwin.cc:525 +#: src/mainwin.cc:523 msgid "OpenSCAD - New Document[*]" msgstr "" -#: src/mainwin.cc:529 +#: src/mainwin.cc:527 msgid "OpenSCAD - " msgstr "" -#: src/mainwin.cc:529 +#: src/mainwin.cc:527 msgid "[*]" msgstr "" -#: src/mainwin.cc:603 +#: src/mainwin.cc:601 #, c-format msgid "Failed to open file %s: %s" msgstr "" -#: src/mainwin.cc:610 +#: src/mainwin.cc:608 #, c-format msgid "Loaded design '%s'." msgstr "" -#: src/mainwin.cc:657 +#: src/mainwin.cc:655 #, c-format msgid "Module cache size: %d modules" msgstr "" -#: src/mainwin.cc:741 +#: src/mainwin.cc:739 msgid "Compiling design (CSG Tree generation)..." msgstr "" -#: src/mainwin.cc:767 +#: src/mainwin.cc:765 msgid "ERROR: Compilation failed! (no top level object found)" msgstr "" -#: src/mainwin.cc:769 +#: src/mainwin.cc:767 msgid "ERROR: Compilation failed!" msgstr "" -#: src/mainwin.cc:782 +#: src/mainwin.cc:780 msgid "Compiling design (CSG Products generation)..." msgstr "" -#: src/mainwin.cc:804 +#: src/mainwin.cc:801 msgid "ERROR: CSG generation failed! (no top level object found)" msgstr "" -#: src/mainwin.cc:813 +#: src/mainwin.cc:810 msgid "CSG generation cancelled." msgstr "" -#: src/mainwin.cc:839 +#: src/mainwin.cc:836 #, c-format msgid "Compiling highlights (%d CSG Trees)..." msgstr "" -#: src/mainwin.cc:851 +#: src/mainwin.cc:848 #, c-format msgid "Compiling background (%d CSG Trees)..." msgstr "" -#: src/mainwin.cc:864 +#: src/mainwin.cc:861 #, c-format msgid "WARNING: Normalized tree has %d elements!" msgstr "" -#: src/mainwin.cc:865 +#: src/mainwin.cc:862 msgid "WARNING: OpenCSG rendering has been disabled." msgstr "" -#: src/mainwin.cc:878 +#: src/mainwin.cc:875 msgid "CSG generation finished." msgstr "" -#: src/mainwin.cc:880 src/mainwin.cc:1346 +#: src/mainwin.cc:877 src/mainwin.cc:1315 #, c-format msgid "Total rendering time: %d hours, %d minutes, %d seconds" msgstr "" -#: src/mainwin.cc:907 +#: src/mainwin.cc:904 msgid "Open File" msgstr "Ouvrir un fichier" -#: src/mainwin.cc:908 +#: src/mainwin.cc:905 msgid "OpenSCAD Designs (*.scad *.csg)" msgstr "" -#: src/mainwin.cc:1002 +#: src/mainwin.cc:999 #, c-format msgid "Failed to open file for writing: %s (%s)" msgstr "" -#: src/mainwin.cc:1003 +#: src/mainwin.cc:1000 msgid "" "Failed to open file for writing:\n" " %1 (%2)" msgstr "" -#: src/mainwin.cc:1010 +#: src/mainwin.cc:1007 #, c-format msgid "Saved design '%s'." msgstr "" -#: src/mainwin.cc:1020 +#: src/mainwin.cc:1017 msgid "Save File" msgstr "" -#: src/mainwin.cc:1021 +#: src/mainwin.cc:1018 msgid "Untitled.scad" msgstr "" -#: src/mainwin.cc:1022 +#: src/mainwin.cc:1019 msgid "OpenSCAD Designs (*.scad)" msgstr "" -#: src/mainwin.cc:1032 +#: src/mainwin.cc:1029 msgid "" "%1 already exists.\n" "Do you want to replace it?" msgstr "" -#: src/mainwin.cc:1047 +#: src/mainwin.cc:1044 #, c-format msgid "WARNING: Library path %s doesn't exist. Creating" msgstr "" -#: src/mainwin.cc:1049 +#: src/mainwin.cc:1046 #, c-format msgid "ERROR: Cannot create library path: %s" msgstr "" -#: src/mainwin.cc:1184 src/mainwin.cc:1857 +#: src/mainwin.cc:1181 src/mainwin.cc:1846 msgid "Application" msgstr "" -#: src/mainwin.cc:1185 +#: src/mainwin.cc:1182 msgid "" "The document has been modified.\n" "Do you really want to reload the file?" msgstr "" -#: src/mainwin.cc:1235 src/mainwin.cc:1279 +#: src/mainwin.cc:1232 src/mainwin.cc:1276 msgid "Parsing design (AST generation)..." msgstr "" -#: src/mainwin.cc:1263 +#: src/mainwin.cc:1260 #, c-format msgid "frame%05d.png" msgstr "" -#: src/mainwin.cc:1300 +#: src/mainwin.cc:1294 msgid "Rendering Polygon Mesh using CGAL..." msgstr "" -#: src/mainwin.cc:1321 -msgid " Top level object is a 2D object:" -msgstr "" - -#: src/mainwin.cc:1322 -#, c-format -msgid " Empty: %6s" -msgstr "" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "yes" -msgstr "" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "no" -msgstr "" - -#: src/mainwin.cc:1323 -#, c-format -msgid " Plane: %6s" -msgstr "" - -#: src/mainwin.cc:1324 src/mainwin.cc:1336 -#, c-format -msgid " Vertices: %6d" -msgstr "" - -#: src/mainwin.cc:1325 src/mainwin.cc:1337 -#, c-format -msgid " Halfedges: %6d" -msgstr "" - -#: src/mainwin.cc:1326 src/mainwin.cc:1338 -#, c-format -msgid " Edges: %6d" -msgstr "" - -#: src/mainwin.cc:1327 -#, c-format -msgid " Faces: %6d" -msgstr "" - -#: src/mainwin.cc:1328 -#, c-format -msgid " FaceCycles: %6d" -msgstr "" - -#: src/mainwin.cc:1329 -#, c-format -msgid " ConnComp: %6d" -msgstr "" - -#: src/mainwin.cc:1333 +#: src/mainwin.cc:1320 src/mainwin.cc:1334 msgid " Top level object is a 3D object:" msgstr "" -#: src/mainwin.cc:1334 +#: src/mainwin.cc:1321 #, c-format msgid " Simple: %6s" msgstr "" -#: src/mainwin.cc:1335 +#: src/mainwin.cc:1321 src/mainwin.cc:1322 +msgid "yes" +msgstr "" + +#: src/mainwin.cc:1321 src/mainwin.cc:1322 +msgid "no" +msgstr "" + +#: src/mainwin.cc:1322 #, c-format msgid " Valid: %6s" msgstr "" -#: src/mainwin.cc:1339 +#: src/mainwin.cc:1323 +#, c-format +msgid " Vertices: %6d" +msgstr "" + +#: src/mainwin.cc:1324 +#, c-format +msgid " Halfedges: %6d" +msgstr "" + +#: src/mainwin.cc:1325 +#, c-format +msgid " Edges: %6d" +msgstr "" + +#: src/mainwin.cc:1326 #, c-format msgid " Halffacets: %6d" msgstr "" -#: src/mainwin.cc:1340 +#: src/mainwin.cc:1327 src/mainwin.cc:1335 #, c-format msgid " Facets: %6d" msgstr "" -#: src/mainwin.cc:1341 +#: src/mainwin.cc:1328 #, c-format msgid " Volumes: %6d" msgstr "" -#: src/mainwin.cc:1359 +#: src/mainwin.cc:1337 +msgid " Top level object is a 2D object:" +msgstr "" + +#: src/mainwin.cc:1338 +#, c-format +msgid " Contours: %6d" +msgstr "" + +#: src/mainwin.cc:1340 +msgid "Unknown geometry type" +msgstr "" + +#: src/mainwin.cc:1342 msgid "Rendering finished." msgstr "" -#: src/mainwin.cc:1362 +#: src/mainwin.cc:1351 msgid "WARNING: No top level geometry to render" msgstr "" -#: src/mainwin.cc:1380 +#: src/mainwin.cc:1368 msgid "AST Dump" msgstr "" -#: src/mainwin.cc:1385 +#: src/mainwin.cc:1373 msgid "No AST to dump. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1398 +#: src/mainwin.cc:1386 msgid "CSG Tree Dump" msgstr "" -#: src/mainwin.cc:1403 +#: src/mainwin.cc:1391 msgid "No CSG to dump. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1416 +#: src/mainwin.cc:1404 msgid "CSG Products Dump" msgstr "" -#: src/mainwin.cc:1418 +#: src/mainwin.cc:1406 msgid "" "\n" "CSG before normalization:\n" @@ -1396,131 +1411,131 @@ msgid "" "%5\n" msgstr "" -#: src/mainwin.cc:1441 src/mainwin.cc:1501 +#: src/mainwin.cc:1429 src/mainwin.cc:1490 msgid "Nothing to export! Try building first (press F6)." msgstr "" -#: src/mainwin.cc:1447 +#: src/mainwin.cc:1435 msgid "Current top level object is not a 3D object." msgstr "" -#: src/mainwin.cc:1453 +#: src/mainwin.cc:1442 msgid "" "Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." "org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" -#: src/mainwin.cc:1460 +#: src/mainwin.cc:1449 msgid "Export STL File" msgstr "" -#: src/mainwin.cc:1460 +#: src/mainwin.cc:1449 msgid "Export OFF File" msgstr "" -#: src/mainwin.cc:1462 +#: src/mainwin.cc:1451 msgid "STL Files (*.stl)" msgstr "" -#: src/mainwin.cc:1462 +#: src/mainwin.cc:1451 msgid "OFF Files (*.off)" msgstr "" -#: src/mainwin.cc:1464 +#: src/mainwin.cc:1453 #, c-format msgid "No filename specified. %s export aborted." msgstr "" -#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 -#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 -#: src/openscad.cc:442 +#: src/mainwin.cc:1460 src/mainwin.cc:1513 src/mainwin.cc:1546 +#: src/openscad.cc:313 src/openscad.cc:325 src/openscad.cc:343 +#: src/openscad.cc:391 src/openscad.cc:406 src/openscad.cc:421 +#: src/openscad.cc:432 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" -#: src/mainwin.cc:1478 +#: src/mainwin.cc:1467 #, c-format msgid "%s export finished." msgstr "" -#: src/mainwin.cc:1507 +#: src/mainwin.cc:1496 msgid "Current top level object is not a 2D object." msgstr "" -#: src/mainwin.cc:1513 +#: src/mainwin.cc:1502 msgid "Export DXF File" msgstr "" -#: src/mainwin.cc:1514 +#: src/mainwin.cc:1503 msgid "Untitled.dxf" msgstr "" -#: src/mainwin.cc:1515 +#: src/mainwin.cc:1504 msgid "DXF Files (*.dxf)" msgstr "" -#: src/mainwin.cc:1517 +#: src/mainwin.cc:1506 msgid "No filename specified. DXF export aborted." msgstr "" -#: src/mainwin.cc:1529 +#: src/mainwin.cc:1518 msgid "DXF export finished." msgstr "" -#: src/mainwin.cc:1541 +#: src/mainwin.cc:1530 msgid "Nothing to export. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1546 +#: src/mainwin.cc:1535 msgid "Export CSG File" msgstr "" -#: src/mainwin.cc:1547 +#: src/mainwin.cc:1536 msgid "Untitled.csg" msgstr "" -#: src/mainwin.cc:1548 +#: src/mainwin.cc:1537 msgid "CSG Files (*.csg)" msgstr "" -#: src/mainwin.cc:1550 +#: src/mainwin.cc:1539 msgid "No filename specified. CSG export aborted." msgstr "" -#: src/mainwin.cc:1562 +#: src/mainwin.cc:1551 msgid "CSG export finished." msgstr "" -#: src/mainwin.cc:1573 +#: src/mainwin.cc:1562 msgid "Export Image" msgstr "" -#: src/mainwin.cc:1573 +#: src/mainwin.cc:1562 msgid "PNG Files (*.png)" msgstr "" -#: src/mainwin.cc:1575 +#: src/mainwin.cc:1564 msgid "No filename specified. Image export aborted." msgstr "" -#: src/mainwin.cc:1827 +#: src/mainwin.cc:1816 msgid "http://openscad.org/" msgstr "" -#: src/mainwin.cc:1833 +#: src/mainwin.cc:1822 msgid "http://www.openscad.org/documentation.html" msgstr "" -#: src/mainwin.cc:1842 +#: src/mainwin.cc:1831 msgid "OpenGL Info" msgstr "Information OpenGL" -#: src/mainwin.cc:1842 +#: src/mainwin.cc:1831 msgid "OpenSCAD Detailed Library and Build Information" msgstr "" -#: src/mainwin.cc:1858 +#: src/mainwin.cc:1847 msgid "" "The document has been modified.\n" "Do you want to save your changes?" @@ -1553,6 +1568,15 @@ msgstr "" msgid "ModuleContext: %p (%p)" msgstr "" +#: src/modcontext.cc:193 +#, c-format +msgid "New lib Context for %s func:" +msgstr "" + +#: src/modcontext.cc:217 +msgid "New file Context:" +msgstr "" + #: src/ModuleCache.cc:70 #, c-format msgid "Recompiling cached library: %s (%s)" @@ -1573,6 +1597,10 @@ msgstr "" msgid " compiled module: %p" msgstr "" +#: src/module.cc:139 +msgid "New eval ctx:" +msgstr "" + #: src/module.cc:180 #, c-format msgid "ERROR: Recursion detected calling module '%s'" @@ -1583,7 +1611,11 @@ msgstr "" msgid "WARNING: Failed to compile library '%s'." msgstr "" -#: src/openscad.cc:109 +#: src/OffscreenView.cc:27 +msgid "OpenSCAD recommended OpenGL version is 2.0." +msgstr "" + +#: src/openscad.cc:107 msgid "" "Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" "%2%[ -m make_command ] [ -D var=val [..] ] \\\n" @@ -1596,154 +1628,150 @@ msgid "" "%2%filename\n" msgstr "" -#: src/openscad.cc:126 +#: src/openscad.cc:124 #, c-format msgid "OpenSCAD version %s\n" msgstr "" -#: src/openscad.cc:138 +#: src/openscad.cc:136 #, c-format msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" msgstr "" -#: src/openscad.cc:182 +#: src/openscad.cc:180 msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" msgstr "" -#: src/openscad.cc:183 +#: src/openscad.cc:181 msgid "or 6 numbers for Vector Camera\n" msgstr "" -#: src/openscad.cc:199 +#: src/openscad.cc:197 msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" msgstr "" -#: src/openscad.cc:210 +#: src/openscad.cc:208 msgid "Need 2 numbers for imgsize\n" msgstr "" -#: src/openscad.cc:260 +#: src/openscad.cc:257 #, c-format msgid "Unknown suffix for output file %s\n" msgstr "" -#: src/openscad.cc:284 +#: src/openscad.cc:281 #, c-format msgid "Can't open input file '%s'!\n" msgstr "" -#: src/openscad.cc:293 +#: src/openscad.cc:290 #, c-format msgid "Can't parse file '%s'!\n" msgstr "" -#: src/openscad.cc:375 +#: src/openscad.cc:373 #, c-format msgid "Output file:%s\n" msgstr "" -#: src/openscad.cc:376 +#: src/openscad.cc:374 msgid "Sorry, don't know how to write deps for that file type. Exiting\n" msgstr "" -#: src/openscad.cc:381 +#: src/openscad.cc:379 msgid "error writing deps" msgstr "" -#: src/openscad.cc:388 src/openscad.cc:407 +#: src/openscad.cc:386 src/openscad.cc:401 msgid "Current top level object is not a 3D object.\n" msgstr "" -#: src/openscad.cc:392 src/openscad.cc:411 -msgid "Object isn't a valid 2-manifold! Modify your design.\n" -msgstr "" - -#: src/openscad.cc:426 +#: src/openscad.cc:416 msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:594 msgid "Allowed options" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:596 msgid "help message" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:597 msgid "print the version" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:598 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:599 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:600 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:601 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:602 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:600 +#: src/openscad.cc:603 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:601 +#: src/openscad.cc:604 msgid "out-file" msgstr "" -#: src/openscad.cc:602 +#: src/openscad.cc:605 msgid "stl-file" msgstr "" -#: src/openscad.cc:603 +#: src/openscad.cc:606 msgid "dxf-file" msgstr "" -#: src/openscad.cc:604 +#: src/openscad.cc:607 msgid "deps-file" msgstr "" -#: src/openscad.cc:605 +#: src/openscad.cc:608 msgid "makefile" msgstr "" -#: src/openscad.cc:606 +#: src/openscad.cc:609 msgid "var=val" msgstr "" -#: src/openscad.cc:607 +#: src/openscad.cc:610 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:609 +#: src/openscad.cc:612 msgid "Hidden options" msgstr "" -#: src/openscad.cc:611 +#: src/openscad.cc:614 msgid "input file" msgstr "" -#: src/openscad.cc:645 +#: src/openscad.cc:648 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:650 +#: src/openscad.cc:653 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:707 +#: src/openscad.cc:710 msgid "Requested GUI mode but can't open display!\n" msgstr "" @@ -1752,158 +1780,93 @@ msgstr "" msgid "ERROR: Cannot create %s" msgstr "" -#: src/PolySetCache.cc:24 -#, c-format -msgid "PolySets in cache: %d" -msgstr "" - -#: src/PolySetCache.cc:25 -#, c-format -msgid "PolySet cache size in bytes: %d" -msgstr "" - -#: src/polyset.cc:55 +#: src/polyset.cc:63 msgid "PolySet:" msgstr "" -#: src/polyset.cc:56 +#: src/polyset.cc:64 msgid "" "\n" " dimensions:" msgstr "" -#: src/polyset.cc:57 +#: src/polyset.cc:65 msgid "" "\n" " convexity:" msgstr "" -#: src/polyset.cc:58 +#: src/polyset.cc:66 msgid "" "\n" " num polygons: " msgstr "" -#: src/polyset.cc:59 +#: src/polyset.cc:67 msgid "" "\n" -" num borders: " +" num outlines: " msgstr "" -#: src/polyset.cc:60 +#: src/polyset.cc:68 msgid "" "\n" " polygons data:" msgstr "" -#: src/polyset.cc:62 +#: src/polyset.cc:70 msgid "" "\n" " polygon begin:" msgstr "" -#: src/polyset.cc:66 src/polyset.cc:75 +#: src/polyset.cc:74 msgid "" "\n" " vertex:" msgstr "" -#: src/polyset.cc:69 +#: src/polyset.cc:77 msgid "" "\n" -" borders data:" +" outlines data:" msgstr "" -#: src/polyset.cc:71 -msgid "" -"\n" -" border polygon begin:" -msgstr "" - -#: src/polyset.cc:78 +#: src/polyset.cc:79 msgid "" "\n" "PolySet end" msgstr "" -#: src/PolySetCGALEvaluator.cc:46 -msgid "" -"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " -"design.." -msgstr "" - -#: src/PolySetCGALEvaluator.cc:63 -#, c-format -msgid "CGAL error in projection node during plane intersection: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:65 -msgid "Trying alternative intersection using very large thin box: " -msgstr "" - -#: src/PolySetCGALEvaluator.cc:80 -#, c-format -msgid "CGAL error in projection node during bigbox intersection: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:87 -msgid "WARNING: projection() failed." -msgstr "" - -#: src/PolySetCGALEvaluator.cc:109 -#, c-format -msgid "CGAL error in projection node while flattening: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:303 -msgid "ERROR: linear_extrude() is not defined for 3D child objects!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:343 -#, c-format -msgid "" -"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:403 -msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:441 -msgid "WARNING: Body of render() isn't valid 2-manifold!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:466 -#, c-format -msgid "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" -msgstr "" - -#: src/primitives.cc:130 +#: src/primitives.cc:134 #, c-format msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." msgstr "" -#: src/primitives.cc:183 +#: src/primitives.cc:187 #, c-format msgid "WARNING: $fs too small - clamping to %f" msgstr "" -#: src/primitives.cc:187 +#: src/primitives.cc:191 #, c-format msgid "WARNING: $fa too small - clamping to %f" msgstr "" -#: src/primitives.cc:244 +#: src/primitives.cc:248 msgid "" "DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " "polyhedron(faces=[]) instead." msgstr "" -#: src/primitives.cc:536 +#: src/primitives.cc:515 #, c-format -msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" +msgid "ERROR: Unable to convert point at index %d to a vec3 of numbers" +msgstr "" + +#: src/primitives.cc:575 +#, c-format +msgid "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" msgstr "" #: src/QGLView.cc:105 @@ -1948,7 +1911,7 @@ msgid "" "distance = %.2f" msgstr "" -#: src/rotateextrude.cc:72 +#: src/rotateextrude.cc:71 msgid "" "DEPRECATED: Support for reading files in rotate_extrude will be removed in " "future releases. Use a child import() instead." @@ -1964,8 +1927,12 @@ msgstr "" msgid "WARNING: Illegal value in '%s': %s" msgstr "" -#: src/value.cc:640 +#: src/value.cc:644 msgid "" "DEPRECATED: Using ranges of the form [begin:end] with begin value greater " "than the end value is deprecated." msgstr "" + +#, fuzzy +#~ msgid "OpenGL Warning" +#~ msgstr "Information OpenGL" diff --git a/po/openscad.pot b/po/openscad.pot index a4a0f173..6c29e598 100644 --- a/po/openscad.pot +++ b/po/openscad.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: OpenSCAD 2014.01.09\n" +"Project-Id-Version: OpenSCAD 2014.01.31\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-09 19:02+0100\n" +"POT-Creation-Date: 2014-01-31 21:26+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,10 +17,6 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: objects/ui_AboutDialog.h:51 -msgid "About OpenSCAD" -msgstr "" - #: objects/ui_MainWindow.h:470 msgid "MainWindow" msgstr "" @@ -178,7 +174,7 @@ msgid "Hide editor" msgstr "" #: objects/ui_MainWindow.h:509 -msgid "&Reload and Compile" +msgid "&Reload and Preview" msgstr "" #: objects/ui_MainWindow.h:510 @@ -186,7 +182,7 @@ msgid "F4" msgstr "" #: objects/ui_MainWindow.h:511 -msgid "&Compile" +msgid "&Preview" msgstr "" #: objects/ui_MainWindow.h:512 @@ -194,7 +190,7 @@ msgid "F5" msgstr "" #: objects/ui_MainWindow.h:513 -msgid "Compile and &Render (CGAL)" +msgid "&Render" msgstr "" #: objects/ui_MainWindow.h:514 @@ -221,8 +217,8 @@ msgstr "" msgid "Export as &OFF..." msgstr "" -#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 -msgid "OpenCSG" +#: objects/ui_MainWindow.h:520 +msgid "Preview" msgstr "" #: objects/ui_MainWindow.h:521 @@ -230,7 +226,7 @@ msgid "F9" msgstr "" #: objects/ui_MainWindow.h:522 -msgid "CGAL Surfaces" +msgid "Surfaces" msgstr "" #: objects/ui_MainWindow.h:523 @@ -238,7 +234,7 @@ msgid "F10" msgstr "" #: objects/ui_MainWindow.h:524 -msgid "CGAL Grid Only" +msgid "Wireframe" msgstr "" #: objects/ui_MainWindow.h:525 @@ -373,7 +369,7 @@ msgstr "" msgid "Export as DXF..." msgstr "" -#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:558 msgid "Close" msgstr "" @@ -381,7 +377,7 @@ msgstr "" msgid "Ctrl+W" msgstr "" -#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:517 msgid "Preferences" msgstr "" @@ -394,7 +390,7 @@ msgid "OpenSCAD Homepage" msgstr "" #: objects/ui_MainWindow.h:563 -msgid "Automatic Reload and Compile" +msgid "Automatic Reload and Preview" msgstr "" #: objects/ui_MainWindow.h:564 @@ -421,7 +417,7 @@ msgstr "" msgid "Reset View" msgstr "" -#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 +#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:520 msgid "Editor" msgstr "" @@ -481,148 +477,122 @@ msgstr "" msgid "&Help" msgstr "" -#: objects/ui_OpenCSGWarningDialog.h:86 -msgid "OpenGL Warning" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "" - -#: objects/ui_Preferences.h:515 +#: objects/ui_Preferences.h:518 msgid "3D View" msgstr "" -#: objects/ui_Preferences.h:516 +#: objects/ui_Preferences.h:519 msgid "Advanced" msgstr "" -#: objects/ui_Preferences.h:518 +#: objects/ui_Preferences.h:521 msgid "Update" msgstr "" -#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +#: objects/ui_Preferences.h:522 objects/ui_Preferences.h:550 msgid "Features" msgstr "" -#: objects/ui_Preferences.h:521 +#: objects/ui_Preferences.h:524 msgid "Enable/Disable experimental features" msgstr "" -#: objects/ui_Preferences.h:523 +#: objects/ui_Preferences.h:526 msgid "Color scheme:" msgstr "" -#: objects/ui_Preferences.h:528 +#: objects/ui_Preferences.h:531 msgid "Cornfield" msgstr "" -#: objects/ui_Preferences.h:530 +#: objects/ui_Preferences.h:533 msgid "Metallic" msgstr "" -#: objects/ui_Preferences.h:532 +#: objects/ui_Preferences.h:535 msgid "Sunset" msgstr "" -#: objects/ui_Preferences.h:535 +#: objects/ui_Preferences.h:538 msgid "Font" msgstr "" -#: objects/ui_Preferences.h:536 +#: objects/ui_Preferences.h:539 msgid "Color syntax highlighting" msgstr "" -#: objects/ui_Preferences.h:539 -msgid "For Light Background" -msgstr "" - -#: objects/ui_Preferences.h:540 -msgid "For Dark Background" -msgstr "" - -#: objects/ui_Preferences.h:541 +#: objects/ui_Preferences.h:542 msgid "Off" msgstr "" #: objects/ui_Preferences.h:543 -msgid "Automatically check for updates" +msgid "For Light Background" msgstr "" #: objects/ui_Preferences.h:544 -msgid "Include development snapshots" -msgstr "" - -#: objects/ui_Preferences.h:545 -msgid "Check Now" +msgid "For Dark Background" msgstr "" #: objects/ui_Preferences.h:546 -msgid "Last checked: " +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:547 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:548 +msgid "Check Now" msgstr "" #: objects/ui_Preferences.h:549 -msgid "Show capability warning" -msgstr "" - -#: objects/ui_Preferences.h:550 -msgid "Enable for OpenGL 1.x" +msgid "Last checked: " msgstr "" #: objects/ui_Preferences.h:551 -msgid "Turn off rendering at " +msgid "OpenCSG" msgstr "" #: objects/ui_Preferences.h:552 -msgid "elements" +msgid "Show capability warning" msgstr "" #: objects/ui_Preferences.h:553 -msgid "Force Goldfeather" +msgid "Enable for OpenGL 1.x" msgstr "" #: objects/ui_Preferences.h:554 -msgid "CGAL Cache size" +msgid "Turn off rendering at " msgstr "" -#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 -msgid "bytes" +#: objects/ui_Preferences.h:555 +msgid "elements" msgstr "" #: objects/ui_Preferences.h:556 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:557 +msgid "CGAL Cache size" +msgstr "" + +#: objects/ui_Preferences.h:558 objects/ui_Preferences.h:560 +msgid "bytes" +msgstr "" + +#: objects/ui_Preferences.h:559 msgid "PolySet Cache size" msgstr "" -#: objects/ui_Preferences.h:558 +#: objects/ui_Preferences.h:561 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" + +#: objects/ui_Preferences.h:562 msgid "toolBar" msgstr "" -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "" - #: src/AboutDialog.h:16 msgid "About OpenSCAD " msgstr "" @@ -631,24 +601,25 @@ msgstr "" msgid "Trimming cache: %1% (%2% bytes)" msgstr "" -#: src/CGAL_Nef3_workaround.h:255 -msgid "ERROR: CGAL NefPolyhedron Triangulation failed" +#: src/CGAL_Nef3_workaround.h:256 +#, c-format +msgid "WARNING: CGAL NefPolyhedron Triangulation failed: %s" msgstr "" #: src/CsgInfo.h:48 msgid "Error: CSG generation failed! (no top level object found)" msgstr "" -#: src/CsgInfo.h:53 src/mainwin.cc:821 +#: src/CsgInfo.h:53 src/mainwin.cc:818 msgid "Compiling design (CSG Products normalization)..." msgstr "" -#: src/CsgInfo.h:60 src/mainwin.cc:868 +#: src/CsgInfo.h:60 src/mainwin.cc:865 #, c-format msgid "Normalized CSG tree has %d elements" msgstr "" -#: src/CsgInfo.h:64 src/mainwin.cc:833 +#: src/CsgInfo.h:64 src/mainwin.cc:830 msgid "WARNING: CSG normalization resulted in an empty tree" msgstr "" @@ -662,39 +633,6 @@ msgstr "" msgid "Compiling background (%i CSG Trees)..." msgstr "" -#: src/cgaladv_minkowski2.cc:43 -msgid " vertices:" -msgstr "" - -#: src/cgaladv_minkowski2.cc:55 -msgid "{ Outer boundary = " -msgstr "" - -#: src/cgaladv_minkowski2.cc:58 -msgid "{ Unbounded polygon." -msgstr "" - -#: src/cgaladv_minkowski2.cc:63 -msgid " holes:" -msgstr "" - -#: src/cgaladv_minkowski2.cc:65 -msgid " Hole #" -msgstr "" - -#: src/cgaladv_minkowski2.cc:90 -msgid "" -"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" -msgstr "" - -#: src/cgaladv_minkowski2.cc:123 -msgid "WARNING: minkowski() could not get any points from object 1!" -msgstr "" - -#: src/cgaladv_minkowski2.cc:126 -msgid "WARNING: minkowski() could not get any points from object 2!" -msgstr "" - #: src/CGALCache.cc:15 #, c-format msgid "CGAL Cache hit: %s (%d bytes)" @@ -720,88 +658,147 @@ msgstr "" msgid "CGAL cache size in bytes: %d" msgstr "" -#: src/CGALEvaluator.cc:89 +#: src/CGAL_Nef_polyhedron.cc:74 src/cgalutils.cc:44 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +msgstr "" + +#: src/CGAL_Nef_polyhedron.cc:75 src/cgalutils.cc:45 src/PlatformUtils.cc:19 #, c-format -msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +msgid "ERROR: %s" msgstr "" -#: src/CGALEvaluator.cc:141 -msgid "WARNING: hull() does not support mixing 2D and 3D objects." +#: src/CGAL_Nef_polyhedron_DxfData.cc:49 +msgid "Warning: Scaling a 3D object with 0 - removing object" msgstr "" -#: src/CGALEvaluator.cc:159 +#: src/cgalutils.cc:30 msgid "" "Hull() currently requires a valid 2-manifold. Please modify your design. See " "http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" -#: src/CGALEvaluator.cc:172 +#: src/cgalutils.cc:107 #, c-format -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +msgid "ERROR: Unsupported CGAL operator: %d" msgstr "" -#: src/CGALEvaluator.cc:207 -msgid "WARNING: Cannot resize to sizes less than 0." +#: src/cgalutils.cc:113 +#, c-format +msgid "CGAL error in CGALUtils::applyBinaryOperator %s: %s" msgstr "" -#: src/CGALEvaluator.cc:234 -msgid "WARNING: Resize in direction normal to flat object is not implemented" +#: src/cgalutils.cc:159 +#, c-format +msgid "CGALUtils::project during plane intersection: %s" msgstr "" -#: src/CGALEvaluator.cc:336 -msgid "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." +#: src/cgalutils.cc:161 +msgid "Trying alternative intersection using very large thin box: " msgstr "" -#: src/CGALEvaluator.cc:384 -msgid "WARNING: glide() is not implemented yet!" +#: src/cgalutils.cc:176 +#, c-format +msgid "CGAL error in CGALUtils::project during bigbox intersection: %s" msgstr "" -#: src/CGALEvaluator.cc:388 -msgid "WARNING: subdiv() is not implemented yet!" +#: src/cgalutils.cc:182 +msgid "WARNING: projection() failed." msgstr "" -#: src/CGALEvaluator.cc:422 -msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" +#: src/cgalutils.cc:204 +#, c-format +msgid "CGAL error in CGALUtils::project while flattening: %s" msgstr "" -#: src/CGALEvaluator.cc:693 +#: src/cgalutils.cc:496 +msgid "ERROR: deproject failure" +msgstr "" + +#: src/cgalutils.cc:582 +msgid "ERROR: failed to find projection" +msgstr "" + +#: src/cgalutils.cc:593 +msgid "input polygon has 3 points. shortcut tessellation." +msgstr "" + +#: src/cgalutils.cc:605 +msgid "finding good projection" +msgstr "" + +#: src/cgalutils.cc:608 +#, c-format +msgid "plane %s" +msgstr "" + +#: src/cgalutils.cc:609 +#, c-format +msgid "proj: %i %i" +msgstr "" + +#: src/cgalutils.cc:610 +msgid "Inserting points and edges into Constrained Delaunay Triangulation" +msgstr "" + +#: src/cgalutils.cc:632 +#, c-format +msgid "WARNING: Constraint insertion failure %s" +msgstr "" + +#: src/cgalutils.cc:639 +#, c-format +msgid "seeding %i holes" +msgstr "" + +#: src/cgalutils.cc:660 +#, c-format +msgid "seed %f,%f" +msgstr "" + +#: src/cgalutils.cc:662 +msgid "seeding done" +msgstr "" + +#: src/cgalutils.cc:664 +msgid "meshing" +msgstr "" + +#: src/cgalutils.cc:669 +msgid "meshing done" +msgstr "" + +#: src/cgalutils.cc:690 +msgid "WARNING: 2d->3d deprojection failure" +msgstr "" + +#: src/cgalutils.cc:698 +#, c-format +msgid "built %i triangles\n" +msgstr "" + +#: src/cgalutils.cc:741 +msgid "WARNING: triangle doesn't have 3 points. skipping" +msgstr "" + +#: src/cgalutils.cc:941 +#, c-format +msgid "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" +msgstr "" + +#: src/cgalutils.cc:1021 msgid "PolySet has nonplanar faces. Attempting alternate construction" msgstr "" -#: src/CGALEvaluator.cc:697 +#: src/cgalutils.cc:1025 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" msgstr "" -#: src/CGALEvaluator.cc:708 +#: src/cgalutils.cc:1036 #, c-format msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" msgstr "" -#: src/CGAL_Nef_polyhedron.cc:113 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." -msgstr "" - -#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 -#, c-format -msgid "ERROR: %s" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:107 -msgid "Warning: Scaling a 2D object with 0 - removing object" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:137 -msgid "Warning: Scaling a 3D object with 0 - removing object" -msgstr "" - -#: src/cgalutils.cc:138 -#, c-format -msgid "CGAL error in CGAL_Build_PolySet: %s" -msgstr "" - #: src/cgalworker.cc:36 msgid "Rendering cancelled." msgstr "" @@ -909,27 +906,27 @@ msgid "" "normalization.\n" msgstr "" -#: src/dxfdata.cc:83 +#: src/dxfdata.cc:84 #, c-format msgid "WARNING: Can't open DXF file '%s'." msgstr "" -#: src/dxfdata.cc:147 +#: src/dxfdata.cc:148 #, c-format msgid "WARNING: Illegal ID '%s' in `%s'" msgstr "" -#: src/dxfdata.cc:386 +#: src/dxfdata.cc:387 #, c-format msgid "WARNING: Illegal value %s in '%s'" msgstr "" -#: src/dxfdata.cc:392 +#: src/dxfdata.cc:393 #, c-format msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." msgstr "" -#: src/dxfdata.cc:395 +#: src/dxfdata.cc:396 #, c-format msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." msgstr "" @@ -949,40 +946,6 @@ msgstr "" msgid "WARNING: Can't find cross in '%s', layer '%s'!" msgstr "" -#: src/dxftess-cgal.cc:170 -msgid "" -"WARNING: Duplicate vertices and/or intersecting lines found during DXF " -"Tessellation." -msgstr "" - -#: src/dxftess-cgal.cc:171 -msgid "" -"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." -msgstr "" - -#: src/dxftess-cgal.cc:176 -#, c-format -msgid "CGAL error in dxf_tesselate(): %s" -msgstr "" - -#: src/dxftess-cgal.cc:475 -#, c-format -msgid "CGAL error in dxftess triangulate_polygon: %s" -msgstr "" - -#: src/dxftess-cgal.cc:491 -msgid "WARNING: PolySet has polygon with <3 points" -msgstr "" - -#: src/dxftess-cgal.cc:496 -msgid "WARNING: PolySet has degenerate polygon" -msgstr "" - -#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 -#, c-format -msgid "GLU tesselation error %s" -msgstr "" - #: src/evalcontext.cc:38 #, c-format msgid "EvalContext %p (%p) for %s inst (%p)" @@ -996,19 +959,32 @@ msgstr "" msgid " children:" msgstr "" -#: src/export.cc:48 +#: src/export.cc:180 src/export.cc:225 +msgid "Object isn't a valid 2-manifold! Modify your design.\n" +msgstr "" + +#: src/export.cc:187 +msgid "ERROR: Nef->PolySet failed" +msgstr "" + +#: src/export.cc:199 msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" msgstr "" -#: src/export.cc:120 src/export.cc:137 +#: src/export.cc:205 src/export.cc:234 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" msgstr "" -#: src/export.cc:123 +#: src/export.cc:208 msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" msgstr "" +#: src/expr.cc:166 +#, c-format +msgid "ERROR: Recursion detected calling function '%s'" +msgstr "" + #: src/feature.cc:21 msgid "Enable the concat() function." msgstr "" @@ -1052,6 +1028,69 @@ msgid "" "stack" msgstr "" +#: src/GeometryCache.cc:14 +#, c-format +msgid "Geometry Cache hit: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:24 +#, c-format +msgid "Geometry Cache insert: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:26 +#, c-format +msgid "Geometry Cache insert failed: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:44 +#, c-format +msgid "Geometries in cache: %d" +msgstr "" + +#: src/GeometryCache.cc:45 +#, c-format +msgid "Geometry cache size in bytes: %d" +msgstr "" + +#: src/GeometryEvaluator.cc:76 +msgid "WARNING: Mixing 2D and 3D objects is not supported." +msgstr "" + +#: src/GeometryEvaluator.cc:188 +msgid "WARNING: Resize in direction normal to flat object is not implemented" +msgstr "" + +#: src/GeometryEvaluator.cc:252 +msgid "WARNING: Ignoring 3D child object for 2D operation" +msgstr "" + +#: src/GeometryEvaluator.cc:276 +msgid "WARNING: GeometryEvaluator: Node didn't fit into cache" +msgstr "" + +#: src/GeometryEvaluator.cc:324 +msgid "WARNING: Ignoring 2D child object for 3D operation" +msgstr "" + +#: src/GeometryEvaluator.cc:365 +#, c-format +msgid "Error: Unknown boolean operation %d" +msgstr "" + +#: src/GeometryEvaluator.cc:517 +msgid "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." +msgstr "" + +#: src/GeometryEvaluator.cc:765 +#, c-format +msgid "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" +msgstr "" + #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" @@ -1065,21 +1104,21 @@ msgstr "" msgid "DEPRECATED: layername= is deprecated. Please use layer=" msgstr "" -#: src/import.cc:195 src/import.cc:281 +#: src/import.cc:201 src/import.cc:286 #, c-format msgid "WARNING: Can't open import file '%s'." msgstr "" -#: src/import.cc:247 +#: src/import.cc:251 #, c-format msgid "WARNING: Can't parse vertex line '%s'." msgstr "" -#: src/import.cc:292 +#: src/import.cc:295 msgid "WARNING: OFF import requires CGAL." msgstr "" -#: src/import.cc:306 +#: src/import.cc:305 #, c-format msgid "ERROR: Unsupported file format while trying to import file '%s'" msgstr "" @@ -1090,12 +1129,7 @@ msgid "" "future releases. Use a child import() instead." msgstr "" -#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 -#, c-format -msgid "WARNING: No suitable PolySetEvaluator found for %s module!" -msgstr "" - -#: src/mainwin.cc:119 +#: src/mainwin.cc:118 msgid "" "Copyright (C) 2009-2013 The OpenSCAD Developers\n" "\n" @@ -1105,272 +1139,254 @@ msgid "" "any later version." msgstr "" -#: src/mainwin.cc:525 +#: src/mainwin.cc:523 msgid "OpenSCAD - New Document[*]" msgstr "" -#: src/mainwin.cc:529 +#: src/mainwin.cc:527 msgid "OpenSCAD - " msgstr "" -#: src/mainwin.cc:529 +#: src/mainwin.cc:527 msgid "[*]" msgstr "" -#: src/mainwin.cc:603 +#: src/mainwin.cc:601 #, c-format msgid "Failed to open file %s: %s" msgstr "" -#: src/mainwin.cc:610 +#: src/mainwin.cc:608 #, c-format msgid "Loaded design '%s'." msgstr "" -#: src/mainwin.cc:657 +#: src/mainwin.cc:655 #, c-format msgid "Module cache size: %d modules" msgstr "" -#: src/mainwin.cc:741 +#: src/mainwin.cc:739 msgid "Compiling design (CSG Tree generation)..." msgstr "" -#: src/mainwin.cc:767 +#: src/mainwin.cc:765 msgid "ERROR: Compilation failed! (no top level object found)" msgstr "" -#: src/mainwin.cc:769 +#: src/mainwin.cc:767 msgid "ERROR: Compilation failed!" msgstr "" -#: src/mainwin.cc:782 +#: src/mainwin.cc:780 msgid "Compiling design (CSG Products generation)..." msgstr "" -#: src/mainwin.cc:804 +#: src/mainwin.cc:801 msgid "ERROR: CSG generation failed! (no top level object found)" msgstr "" -#: src/mainwin.cc:813 +#: src/mainwin.cc:810 msgid "CSG generation cancelled." msgstr "" -#: src/mainwin.cc:839 +#: src/mainwin.cc:836 #, c-format msgid "Compiling highlights (%d CSG Trees)..." msgstr "" -#: src/mainwin.cc:851 +#: src/mainwin.cc:848 #, c-format msgid "Compiling background (%d CSG Trees)..." msgstr "" -#: src/mainwin.cc:864 +#: src/mainwin.cc:861 #, c-format msgid "WARNING: Normalized tree has %d elements!" msgstr "" -#: src/mainwin.cc:865 +#: src/mainwin.cc:862 msgid "WARNING: OpenCSG rendering has been disabled." msgstr "" -#: src/mainwin.cc:878 +#: src/mainwin.cc:875 msgid "CSG generation finished." msgstr "" -#: src/mainwin.cc:880 src/mainwin.cc:1346 +#: src/mainwin.cc:877 src/mainwin.cc:1315 #, c-format msgid "Total rendering time: %d hours, %d minutes, %d seconds" msgstr "" -#: src/mainwin.cc:907 +#: src/mainwin.cc:904 msgid "Open File" msgstr "" -#: src/mainwin.cc:908 +#: src/mainwin.cc:905 msgid "OpenSCAD Designs (*.scad *.csg)" msgstr "" -#: src/mainwin.cc:1002 +#: src/mainwin.cc:999 #, c-format msgid "Failed to open file for writing: %s (%s)" msgstr "" -#: src/mainwin.cc:1003 +#: src/mainwin.cc:1000 msgid "" "Failed to open file for writing:\n" " %1 (%2)" msgstr "" -#: src/mainwin.cc:1010 +#: src/mainwin.cc:1007 #, c-format msgid "Saved design '%s'." msgstr "" -#: src/mainwin.cc:1020 +#: src/mainwin.cc:1017 msgid "Save File" msgstr "" -#: src/mainwin.cc:1021 +#: src/mainwin.cc:1018 msgid "Untitled.scad" msgstr "" -#: src/mainwin.cc:1022 +#: src/mainwin.cc:1019 msgid "OpenSCAD Designs (*.scad)" msgstr "" -#: src/mainwin.cc:1032 +#: src/mainwin.cc:1029 msgid "" "%1 already exists.\n" "Do you want to replace it?" msgstr "" -#: src/mainwin.cc:1047 +#: src/mainwin.cc:1044 #, c-format msgid "WARNING: Library path %s doesn't exist. Creating" msgstr "" -#: src/mainwin.cc:1049 +#: src/mainwin.cc:1046 #, c-format msgid "ERROR: Cannot create library path: %s" msgstr "" -#: src/mainwin.cc:1184 src/mainwin.cc:1857 +#: src/mainwin.cc:1181 src/mainwin.cc:1846 msgid "Application" msgstr "" -#: src/mainwin.cc:1185 +#: src/mainwin.cc:1182 msgid "" "The document has been modified.\n" "Do you really want to reload the file?" msgstr "" -#: src/mainwin.cc:1235 src/mainwin.cc:1279 +#: src/mainwin.cc:1232 src/mainwin.cc:1276 msgid "Parsing design (AST generation)..." msgstr "" -#: src/mainwin.cc:1263 +#: src/mainwin.cc:1260 #, c-format msgid "frame%05d.png" msgstr "" -#: src/mainwin.cc:1300 +#: src/mainwin.cc:1294 msgid "Rendering Polygon Mesh using CGAL..." msgstr "" -#: src/mainwin.cc:1321 -msgid " Top level object is a 2D object:" -msgstr "" - -#: src/mainwin.cc:1322 -#, c-format -msgid " Empty: %6s" -msgstr "" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "yes" -msgstr "" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "no" -msgstr "" - -#: src/mainwin.cc:1323 -#, c-format -msgid " Plane: %6s" -msgstr "" - -#: src/mainwin.cc:1324 src/mainwin.cc:1336 -#, c-format -msgid " Vertices: %6d" -msgstr "" - -#: src/mainwin.cc:1325 src/mainwin.cc:1337 -#, c-format -msgid " Halfedges: %6d" -msgstr "" - -#: src/mainwin.cc:1326 src/mainwin.cc:1338 -#, c-format -msgid " Edges: %6d" -msgstr "" - -#: src/mainwin.cc:1327 -#, c-format -msgid " Faces: %6d" -msgstr "" - -#: src/mainwin.cc:1328 -#, c-format -msgid " FaceCycles: %6d" -msgstr "" - -#: src/mainwin.cc:1329 -#, c-format -msgid " ConnComp: %6d" -msgstr "" - -#: src/mainwin.cc:1333 +#: src/mainwin.cc:1320 src/mainwin.cc:1334 msgid " Top level object is a 3D object:" msgstr "" -#: src/mainwin.cc:1334 +#: src/mainwin.cc:1321 #, c-format msgid " Simple: %6s" msgstr "" -#: src/mainwin.cc:1335 +#: src/mainwin.cc:1321 src/mainwin.cc:1322 +msgid "yes" +msgstr "" + +#: src/mainwin.cc:1321 src/mainwin.cc:1322 +msgid "no" +msgstr "" + +#: src/mainwin.cc:1322 #, c-format msgid " Valid: %6s" msgstr "" -#: src/mainwin.cc:1339 +#: src/mainwin.cc:1323 +#, c-format +msgid " Vertices: %6d" +msgstr "" + +#: src/mainwin.cc:1324 +#, c-format +msgid " Halfedges: %6d" +msgstr "" + +#: src/mainwin.cc:1325 +#, c-format +msgid " Edges: %6d" +msgstr "" + +#: src/mainwin.cc:1326 #, c-format msgid " Halffacets: %6d" msgstr "" -#: src/mainwin.cc:1340 +#: src/mainwin.cc:1327 src/mainwin.cc:1335 #, c-format msgid " Facets: %6d" msgstr "" -#: src/mainwin.cc:1341 +#: src/mainwin.cc:1328 #, c-format msgid " Volumes: %6d" msgstr "" -#: src/mainwin.cc:1359 +#: src/mainwin.cc:1337 +msgid " Top level object is a 2D object:" +msgstr "" + +#: src/mainwin.cc:1338 +#, c-format +msgid " Contours: %6d" +msgstr "" + +#: src/mainwin.cc:1340 +msgid "Unknown geometry type" +msgstr "" + +#: src/mainwin.cc:1342 msgid "Rendering finished." msgstr "" -#: src/mainwin.cc:1362 +#: src/mainwin.cc:1351 msgid "WARNING: No top level geometry to render" msgstr "" -#: src/mainwin.cc:1380 +#: src/mainwin.cc:1368 msgid "AST Dump" msgstr "" -#: src/mainwin.cc:1385 +#: src/mainwin.cc:1373 msgid "No AST to dump. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1398 +#: src/mainwin.cc:1386 msgid "CSG Tree Dump" msgstr "" -#: src/mainwin.cc:1403 +#: src/mainwin.cc:1391 msgid "No CSG to dump. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1416 +#: src/mainwin.cc:1404 msgid "CSG Products Dump" msgstr "" -#: src/mainwin.cc:1418 +#: src/mainwin.cc:1406 msgid "" "\n" "CSG before normalization:\n" @@ -1393,131 +1409,131 @@ msgid "" "%5\n" msgstr "" -#: src/mainwin.cc:1441 src/mainwin.cc:1501 +#: src/mainwin.cc:1429 src/mainwin.cc:1490 msgid "Nothing to export! Try building first (press F6)." msgstr "" -#: src/mainwin.cc:1447 +#: src/mainwin.cc:1435 msgid "Current top level object is not a 3D object." msgstr "" -#: src/mainwin.cc:1453 +#: src/mainwin.cc:1442 msgid "" "Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." "org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" -#: src/mainwin.cc:1460 +#: src/mainwin.cc:1449 msgid "Export STL File" msgstr "" -#: src/mainwin.cc:1460 +#: src/mainwin.cc:1449 msgid "Export OFF File" msgstr "" -#: src/mainwin.cc:1462 +#: src/mainwin.cc:1451 msgid "STL Files (*.stl)" msgstr "" -#: src/mainwin.cc:1462 +#: src/mainwin.cc:1451 msgid "OFF Files (*.off)" msgstr "" -#: src/mainwin.cc:1464 +#: src/mainwin.cc:1453 #, c-format msgid "No filename specified. %s export aborted." msgstr "" -#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 -#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 -#: src/openscad.cc:442 +#: src/mainwin.cc:1460 src/mainwin.cc:1513 src/mainwin.cc:1546 +#: src/openscad.cc:313 src/openscad.cc:325 src/openscad.cc:343 +#: src/openscad.cc:391 src/openscad.cc:406 src/openscad.cc:421 +#: src/openscad.cc:432 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" -#: src/mainwin.cc:1478 +#: src/mainwin.cc:1467 #, c-format msgid "%s export finished." msgstr "" -#: src/mainwin.cc:1507 +#: src/mainwin.cc:1496 msgid "Current top level object is not a 2D object." msgstr "" -#: src/mainwin.cc:1513 +#: src/mainwin.cc:1502 msgid "Export DXF File" msgstr "" -#: src/mainwin.cc:1514 +#: src/mainwin.cc:1503 msgid "Untitled.dxf" msgstr "" -#: src/mainwin.cc:1515 +#: src/mainwin.cc:1504 msgid "DXF Files (*.dxf)" msgstr "" -#: src/mainwin.cc:1517 +#: src/mainwin.cc:1506 msgid "No filename specified. DXF export aborted." msgstr "" -#: src/mainwin.cc:1529 +#: src/mainwin.cc:1518 msgid "DXF export finished." msgstr "" -#: src/mainwin.cc:1541 +#: src/mainwin.cc:1530 msgid "Nothing to export. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1546 +#: src/mainwin.cc:1535 msgid "Export CSG File" msgstr "" -#: src/mainwin.cc:1547 +#: src/mainwin.cc:1536 msgid "Untitled.csg" msgstr "" -#: src/mainwin.cc:1548 +#: src/mainwin.cc:1537 msgid "CSG Files (*.csg)" msgstr "" -#: src/mainwin.cc:1550 +#: src/mainwin.cc:1539 msgid "No filename specified. CSG export aborted." msgstr "" -#: src/mainwin.cc:1562 +#: src/mainwin.cc:1551 msgid "CSG export finished." msgstr "" -#: src/mainwin.cc:1573 +#: src/mainwin.cc:1562 msgid "Export Image" msgstr "" -#: src/mainwin.cc:1573 +#: src/mainwin.cc:1562 msgid "PNG Files (*.png)" msgstr "" -#: src/mainwin.cc:1575 +#: src/mainwin.cc:1564 msgid "No filename specified. Image export aborted." msgstr "" -#: src/mainwin.cc:1827 +#: src/mainwin.cc:1816 msgid "http://openscad.org/" msgstr "" -#: src/mainwin.cc:1833 +#: src/mainwin.cc:1822 msgid "http://www.openscad.org/documentation.html" msgstr "" -#: src/mainwin.cc:1842 +#: src/mainwin.cc:1831 msgid "OpenGL Info" msgstr "" -#: src/mainwin.cc:1842 +#: src/mainwin.cc:1831 msgid "OpenSCAD Detailed Library and Build Information" msgstr "" -#: src/mainwin.cc:1858 +#: src/mainwin.cc:1847 msgid "" "The document has been modified.\n" "Do you want to save your changes?" @@ -1550,6 +1566,15 @@ msgstr "" msgid "ModuleContext: %p (%p)" msgstr "" +#: src/modcontext.cc:193 +#, c-format +msgid "New lib Context for %s func:" +msgstr "" + +#: src/modcontext.cc:217 +msgid "New file Context:" +msgstr "" + #: src/ModuleCache.cc:70 #, c-format msgid "Recompiling cached library: %s (%s)" @@ -1570,6 +1595,10 @@ msgstr "" msgid " compiled module: %p" msgstr "" +#: src/module.cc:139 +msgid "New eval ctx:" +msgstr "" + #: src/module.cc:180 #, c-format msgid "ERROR: Recursion detected calling module '%s'" @@ -1580,7 +1609,11 @@ msgstr "" msgid "WARNING: Failed to compile library '%s'." msgstr "" -#: src/openscad.cc:109 +#: src/OffscreenView.cc:27 +msgid "OpenSCAD recommended OpenGL version is 2.0." +msgstr "" + +#: src/openscad.cc:107 msgid "" "Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" "%2%[ -m make_command ] [ -D var=val [..] ] \\\n" @@ -1593,154 +1626,150 @@ msgid "" "%2%filename\n" msgstr "" -#: src/openscad.cc:126 +#: src/openscad.cc:124 #, c-format msgid "OpenSCAD version %s\n" msgstr "" -#: src/openscad.cc:138 +#: src/openscad.cc:136 #, c-format msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" msgstr "" -#: src/openscad.cc:182 +#: src/openscad.cc:180 msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" msgstr "" -#: src/openscad.cc:183 +#: src/openscad.cc:181 msgid "or 6 numbers for Vector Camera\n" msgstr "" -#: src/openscad.cc:199 +#: src/openscad.cc:197 msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" msgstr "" -#: src/openscad.cc:210 +#: src/openscad.cc:208 msgid "Need 2 numbers for imgsize\n" msgstr "" -#: src/openscad.cc:260 +#: src/openscad.cc:257 #, c-format msgid "Unknown suffix for output file %s\n" msgstr "" -#: src/openscad.cc:284 +#: src/openscad.cc:281 #, c-format msgid "Can't open input file '%s'!\n" msgstr "" -#: src/openscad.cc:293 +#: src/openscad.cc:290 #, c-format msgid "Can't parse file '%s'!\n" msgstr "" -#: src/openscad.cc:375 +#: src/openscad.cc:373 #, c-format msgid "Output file:%s\n" msgstr "" -#: src/openscad.cc:376 +#: src/openscad.cc:374 msgid "Sorry, don't know how to write deps for that file type. Exiting\n" msgstr "" -#: src/openscad.cc:381 +#: src/openscad.cc:379 msgid "error writing deps" msgstr "" -#: src/openscad.cc:388 src/openscad.cc:407 +#: src/openscad.cc:386 src/openscad.cc:401 msgid "Current top level object is not a 3D object.\n" msgstr "" -#: src/openscad.cc:392 src/openscad.cc:411 -msgid "Object isn't a valid 2-manifold! Modify your design.\n" -msgstr "" - -#: src/openscad.cc:426 +#: src/openscad.cc:416 msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:594 msgid "Allowed options" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:596 msgid "help message" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:597 msgid "print the version" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:598 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:599 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:600 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:601 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:602 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:600 +#: src/openscad.cc:603 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:601 +#: src/openscad.cc:604 msgid "out-file" msgstr "" -#: src/openscad.cc:602 +#: src/openscad.cc:605 msgid "stl-file" msgstr "" -#: src/openscad.cc:603 +#: src/openscad.cc:606 msgid "dxf-file" msgstr "" -#: src/openscad.cc:604 +#: src/openscad.cc:607 msgid "deps-file" msgstr "" -#: src/openscad.cc:605 +#: src/openscad.cc:608 msgid "makefile" msgstr "" -#: src/openscad.cc:606 +#: src/openscad.cc:609 msgid "var=val" msgstr "" -#: src/openscad.cc:607 +#: src/openscad.cc:610 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:609 +#: src/openscad.cc:612 msgid "Hidden options" msgstr "" -#: src/openscad.cc:611 +#: src/openscad.cc:614 msgid "input file" msgstr "" -#: src/openscad.cc:645 +#: src/openscad.cc:648 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:650 +#: src/openscad.cc:653 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:707 +#: src/openscad.cc:710 msgid "Requested GUI mode but can't open display!\n" msgstr "" @@ -1749,158 +1778,93 @@ msgstr "" msgid "ERROR: Cannot create %s" msgstr "" -#: src/PolySetCache.cc:24 -#, c-format -msgid "PolySets in cache: %d" -msgstr "" - -#: src/PolySetCache.cc:25 -#, c-format -msgid "PolySet cache size in bytes: %d" -msgstr "" - -#: src/polyset.cc:55 +#: src/polyset.cc:63 msgid "PolySet:" msgstr "" -#: src/polyset.cc:56 +#: src/polyset.cc:64 msgid "" "\n" " dimensions:" msgstr "" -#: src/polyset.cc:57 +#: src/polyset.cc:65 msgid "" "\n" " convexity:" msgstr "" -#: src/polyset.cc:58 +#: src/polyset.cc:66 msgid "" "\n" " num polygons: " msgstr "" -#: src/polyset.cc:59 +#: src/polyset.cc:67 msgid "" "\n" -" num borders: " +" num outlines: " msgstr "" -#: src/polyset.cc:60 +#: src/polyset.cc:68 msgid "" "\n" " polygons data:" msgstr "" -#: src/polyset.cc:62 +#: src/polyset.cc:70 msgid "" "\n" " polygon begin:" msgstr "" -#: src/polyset.cc:66 src/polyset.cc:75 +#: src/polyset.cc:74 msgid "" "\n" " vertex:" msgstr "" -#: src/polyset.cc:69 +#: src/polyset.cc:77 msgid "" "\n" -" borders data:" +" outlines data:" msgstr "" -#: src/polyset.cc:71 -msgid "" -"\n" -" border polygon begin:" -msgstr "" - -#: src/polyset.cc:78 +#: src/polyset.cc:79 msgid "" "\n" "PolySet end" msgstr "" -#: src/PolySetCGALEvaluator.cc:46 -msgid "" -"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " -"design.." -msgstr "" - -#: src/PolySetCGALEvaluator.cc:63 -#, c-format -msgid "CGAL error in projection node during plane intersection: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:65 -msgid "Trying alternative intersection using very large thin box: " -msgstr "" - -#: src/PolySetCGALEvaluator.cc:80 -#, c-format -msgid "CGAL error in projection node during bigbox intersection: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:87 -msgid "WARNING: projection() failed." -msgstr "" - -#: src/PolySetCGALEvaluator.cc:109 -#, c-format -msgid "CGAL error in projection node while flattening: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:303 -msgid "ERROR: linear_extrude() is not defined for 3D child objects!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:343 -#, c-format -msgid "" -"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:403 -msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:441 -msgid "WARNING: Body of render() isn't valid 2-manifold!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:466 -#, c-format -msgid "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" -msgstr "" - -#: src/primitives.cc:130 +#: src/primitives.cc:134 #, c-format msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." msgstr "" -#: src/primitives.cc:183 +#: src/primitives.cc:187 #, c-format msgid "WARNING: $fs too small - clamping to %f" msgstr "" -#: src/primitives.cc:187 +#: src/primitives.cc:191 #, c-format msgid "WARNING: $fa too small - clamping to %f" msgstr "" -#: src/primitives.cc:244 +#: src/primitives.cc:248 msgid "" "DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " "polyhedron(faces=[]) instead." msgstr "" -#: src/primitives.cc:536 +#: src/primitives.cc:515 #, c-format -msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" +msgid "ERROR: Unable to convert point at index %d to a vec3 of numbers" +msgstr "" + +#: src/primitives.cc:575 +#, c-format +msgid "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" msgstr "" #: src/QGLView.cc:105 @@ -1945,7 +1909,7 @@ msgid "" "distance = %.2f" msgstr "" -#: src/rotateextrude.cc:72 +#: src/rotateextrude.cc:71 msgid "" "DEPRECATED: Support for reading files in rotate_extrude will be removed in " "future releases. Use a child import() instead." @@ -1961,7 +1925,7 @@ msgstr "" msgid "WARNING: Illegal value in '%s': %s" msgstr "" -#: src/value.cc:640 +#: src/value.cc:644 msgid "" "DEPRECATED: Using ranges of the form [begin:end] with begin value greater " "than the end value is deprecated." diff --git a/po/ru.po b/po/ru.po index 7e03d171..cf2fce7c 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-09 18:17+0100\n" +"POT-Creation-Date: 2014-01-31 21:18+0100\n" "PO-Revision-Date: 2013-02-24 17:50+0100\n" "Last-Translator: \n" "Language-Team: Russian\n" @@ -18,10 +18,6 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: objects/ui_AboutDialog.h:51 -msgid "About OpenSCAD" -msgstr "О программе OpenSCAD" - #: objects/ui_MainWindow.h:470 msgid "MainWindow" msgstr "" @@ -179,7 +175,8 @@ msgid "Hide editor" msgstr "Скрыть редактор" #: objects/ui_MainWindow.h:509 -msgid "&Reload and Compile" +#, fuzzy +msgid "&Reload and Preview" msgstr "&Обновить и компилировать" #: objects/ui_MainWindow.h:510 @@ -187,16 +184,16 @@ msgid "F4" msgstr "" #: objects/ui_MainWindow.h:511 -msgid "&Compile" -msgstr "&Компилировать" +msgid "&Preview" +msgstr "" #: objects/ui_MainWindow.h:512 msgid "F5" msgstr "" #: objects/ui_MainWindow.h:513 -msgid "Compile and &Render (CGAL)" -msgstr "Компилировать и &отрисовать (CGAL)" +msgid "&Render" +msgstr "" #: objects/ui_MainWindow.h:514 msgid "F6" @@ -222,8 +219,8 @@ msgstr "Экспортировать в &STL..." msgid "Export as &OFF..." msgstr "Экспортировать в &OFF..." -#: objects/ui_MainWindow.h:520 objects/ui_Preferences.h:548 -msgid "OpenCSG" +#: objects/ui_MainWindow.h:520 +msgid "Preview" msgstr "" #: objects/ui_MainWindow.h:521 @@ -231,7 +228,8 @@ msgid "F9" msgstr "" #: objects/ui_MainWindow.h:522 -msgid "CGAL Surfaces" +#, fuzzy +msgid "Surfaces" msgstr "Поверхности CGAL" #: objects/ui_MainWindow.h:523 @@ -239,8 +237,8 @@ msgid "F10" msgstr "" #: objects/ui_MainWindow.h:524 -msgid "CGAL Grid Only" -msgstr "Только сетка CGAL" +msgid "Wireframe" +msgstr "" #: objects/ui_MainWindow.h:525 msgid "F11" @@ -374,7 +372,7 @@ msgstr "Очистить список" msgid "Export as DXF..." msgstr "Экспортировать в DXF..." -#: objects/ui_MainWindow.h:558 objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:558 msgid "Close" msgstr "Закрыть" @@ -382,7 +380,7 @@ msgstr "Закрыть" msgid "Ctrl+W" msgstr "" -#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:514 +#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:517 msgid "Preferences" msgstr "Настройки" @@ -395,7 +393,8 @@ msgid "OpenSCAD Homepage" msgstr "Домашняя страница OpenSCAD" #: objects/ui_MainWindow.h:563 -msgid "Automatic Reload and Compile" +#, fuzzy +msgid "Automatic Reload and Preview" msgstr "Автоматически обновлять и комилировать" #: objects/ui_MainWindow.h:564 @@ -422,7 +421,7 @@ msgstr "Открыть каталог библиотек..." msgid "Reset View" msgstr "Сбросить настройки вида" -#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:517 +#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:520 msgid "Editor" msgstr "Редактор" @@ -482,148 +481,122 @@ msgstr "&Вид" msgid "&Help" msgstr "&Справка" -#: objects/ui_OpenCSGWarningDialog.h:86 -msgid "OpenGL Warning" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "" - -#: objects/ui_Preferences.h:515 +#: objects/ui_Preferences.h:518 msgid "3D View" msgstr "3D Вид" -#: objects/ui_Preferences.h:516 +#: objects/ui_Preferences.h:519 msgid "Advanced" msgstr "Дополнительные" -#: objects/ui_Preferences.h:518 +#: objects/ui_Preferences.h:521 msgid "Update" msgstr "Обновления" -#: objects/ui_Preferences.h:519 objects/ui_Preferences.h:547 +#: objects/ui_Preferences.h:522 objects/ui_Preferences.h:550 msgid "Features" msgstr "Функции" -#: objects/ui_Preferences.h:521 +#: objects/ui_Preferences.h:524 msgid "Enable/Disable experimental features" msgstr "" -#: objects/ui_Preferences.h:523 +#: objects/ui_Preferences.h:526 msgid "Color scheme:" msgstr "Цветовая схема:" -#: objects/ui_Preferences.h:528 +#: objects/ui_Preferences.h:531 msgid "Cornfield" msgstr "" -#: objects/ui_Preferences.h:530 +#: objects/ui_Preferences.h:533 msgid "Metallic" msgstr "" -#: objects/ui_Preferences.h:532 +#: objects/ui_Preferences.h:535 msgid "Sunset" msgstr "" -#: objects/ui_Preferences.h:535 +#: objects/ui_Preferences.h:538 msgid "Font" msgstr "Шрифт" -#: objects/ui_Preferences.h:536 +#: objects/ui_Preferences.h:539 msgid "Color syntax highlighting" msgstr "Подсветка синтаксиса" -#: objects/ui_Preferences.h:539 -msgid "For Light Background" -msgstr "Для светлого фона" - -#: objects/ui_Preferences.h:540 -msgid "For Dark Background" -msgstr "Для тёмного фона" - -#: objects/ui_Preferences.h:541 +#: objects/ui_Preferences.h:542 msgid "Off" msgstr "Выключить" #: objects/ui_Preferences.h:543 +msgid "For Light Background" +msgstr "Для светлого фона" + +#: objects/ui_Preferences.h:544 +msgid "For Dark Background" +msgstr "Для тёмного фона" + +#: objects/ui_Preferences.h:546 msgid "Automatically check for updates" msgstr "Автоматически проверять обновления" -#: objects/ui_Preferences.h:544 +#: objects/ui_Preferences.h:547 msgid "Include development snapshots" msgstr "Включая рабочие сборки" -#: objects/ui_Preferences.h:545 +#: objects/ui_Preferences.h:548 msgid "Check Now" msgstr "Проверить сейчас" -#: objects/ui_Preferences.h:546 +#: objects/ui_Preferences.h:549 msgid "Last checked: " msgstr "Последняя проверка: " -#: objects/ui_Preferences.h:549 +#: objects/ui_Preferences.h:551 +msgid "OpenCSG" +msgstr "" + +#: objects/ui_Preferences.h:552 msgid "Show capability warning" msgstr "Показывать предупреждение о возможностях" -#: objects/ui_Preferences.h:550 +#: objects/ui_Preferences.h:553 msgid "Enable for OpenGL 1.x" msgstr "Включить для OpenGL 1.x" -#: objects/ui_Preferences.h:551 +#: objects/ui_Preferences.h:554 msgid "Turn off rendering at " msgstr "Отключать отрисовку на " -#: objects/ui_Preferences.h:552 +#: objects/ui_Preferences.h:555 msgid "elements" msgstr "элементах" -#: objects/ui_Preferences.h:553 +#: objects/ui_Preferences.h:556 msgid "Force Goldfeather" msgstr "Принудительно использовать алгоритм Goldfeather («Золотое перо»)" -#: objects/ui_Preferences.h:554 +#: objects/ui_Preferences.h:557 msgid "CGAL Cache size" msgstr "Размер кэша CGAL" -#: objects/ui_Preferences.h:555 objects/ui_Preferences.h:557 +#: objects/ui_Preferences.h:558 objects/ui_Preferences.h:560 msgid "bytes" msgstr "байт" -#: objects/ui_Preferences.h:556 +#: objects/ui_Preferences.h:559 msgid "PolySet Cache size" msgstr "Размер кэша PolySet" -#: objects/ui_Preferences.h:558 +#: objects/ui_Preferences.h:561 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" + +#: objects/ui_Preferences.h:562 msgid "toolBar" msgstr "" -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "" - #: src/AboutDialog.h:16 msgid "About OpenSCAD " msgstr "" @@ -632,24 +605,25 @@ msgstr "" msgid "Trimming cache: %1% (%2% bytes)" msgstr "" -#: src/CGAL_Nef3_workaround.h:255 -msgid "ERROR: CGAL NefPolyhedron Triangulation failed" +#: src/CGAL_Nef3_workaround.h:256 +#, c-format +msgid "WARNING: CGAL NefPolyhedron Triangulation failed: %s" msgstr "" #: src/CsgInfo.h:48 msgid "Error: CSG generation failed! (no top level object found)" msgstr "" -#: src/CsgInfo.h:53 src/mainwin.cc:821 +#: src/CsgInfo.h:53 src/mainwin.cc:818 msgid "Compiling design (CSG Products normalization)..." msgstr "" -#: src/CsgInfo.h:60 src/mainwin.cc:868 +#: src/CsgInfo.h:60 src/mainwin.cc:865 #, c-format msgid "Normalized CSG tree has %d elements" msgstr "" -#: src/CsgInfo.h:64 src/mainwin.cc:833 +#: src/CsgInfo.h:64 src/mainwin.cc:830 msgid "WARNING: CSG normalization resulted in an empty tree" msgstr "" @@ -663,39 +637,6 @@ msgstr "" msgid "Compiling background (%i CSG Trees)..." msgstr "" -#: src/cgaladv_minkowski2.cc:43 -msgid " vertices:" -msgstr "" - -#: src/cgaladv_minkowski2.cc:55 -msgid "{ Outer boundary = " -msgstr "" - -#: src/cgaladv_minkowski2.cc:58 -msgid "{ Unbounded polygon." -msgstr "" - -#: src/cgaladv_minkowski2.cc:63 -msgid " holes:" -msgstr "" - -#: src/cgaladv_minkowski2.cc:65 -msgid " Hole #" -msgstr "" - -#: src/cgaladv_minkowski2.cc:90 -msgid "" -"WARNING: minkowski() and hull() is not implemented for 2d objects with holes!" -msgstr "" - -#: src/cgaladv_minkowski2.cc:123 -msgid "WARNING: minkowski() could not get any points from object 1!" -msgstr "" - -#: src/cgaladv_minkowski2.cc:126 -msgid "WARNING: minkowski() could not get any points from object 2!" -msgstr "" - #: src/CGALCache.cc:15 #, c-format msgid "CGAL Cache hit: %s (%d bytes)" @@ -721,88 +662,147 @@ msgstr "" msgid "CGAL cache size in bytes: %d" msgstr "" -#: src/CGALEvaluator.cc:89 +#: src/CGAL_Nef_polyhedron.cc:74 src/cgalutils.cc:44 +msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." +msgstr "" + +#: src/CGAL_Nef_polyhedron.cc:75 src/cgalutils.cc:45 src/PlatformUtils.cc:19 #, c-format -msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +msgid "ERROR: %s" msgstr "" -#: src/CGALEvaluator.cc:141 -msgid "WARNING: hull() does not support mixing 2D and 3D objects." +#: src/CGAL_Nef_polyhedron_DxfData.cc:49 +msgid "Warning: Scaling a 3D object with 0 - removing object" msgstr "" -#: src/CGALEvaluator.cc:159 +#: src/cgalutils.cc:30 msgid "" "Hull() currently requires a valid 2-manifold. Please modify your design. See " "http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" -#: src/CGALEvaluator.cc:172 +#: src/cgalutils.cc:107 #, c-format -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed. %s" +msgid "ERROR: Unsupported CGAL operator: %d" msgstr "" -#: src/CGALEvaluator.cc:207 -msgid "WARNING: Cannot resize to sizes less than 0." +#: src/cgalutils.cc:113 +#, c-format +msgid "CGAL error in CGALUtils::applyBinaryOperator %s: %s" msgstr "" -#: src/CGALEvaluator.cc:234 -msgid "WARNING: Resize in direction normal to flat object is not implemented" +#: src/cgalutils.cc:159 +#, c-format +msgid "CGALUtils::project during plane intersection: %s" msgstr "" -#: src/CGALEvaluator.cc:336 -msgid "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." +#: src/cgalutils.cc:161 +msgid "Trying alternative intersection using very large thin box: " msgstr "" -#: src/CGALEvaluator.cc:384 -msgid "WARNING: glide() is not implemented yet!" +#: src/cgalutils.cc:176 +#, c-format +msgid "CGAL error in CGALUtils::project during bigbox intersection: %s" msgstr "" -#: src/CGALEvaluator.cc:388 -msgid "WARNING: subdiv() is not implemented yet!" +#: src/cgalutils.cc:182 +msgid "WARNING: projection() failed." msgstr "" -#: src/CGALEvaluator.cc:422 -msgid "WARNING: CGAL Evaluator: Root node didn't fit into cache" +#: src/cgalutils.cc:204 +#, c-format +msgid "CGAL error in CGALUtils::project while flattening: %s" msgstr "" -#: src/CGALEvaluator.cc:693 +#: src/cgalutils.cc:496 +msgid "ERROR: deproject failure" +msgstr "" + +#: src/cgalutils.cc:582 +msgid "ERROR: failed to find projection" +msgstr "" + +#: src/cgalutils.cc:593 +msgid "input polygon has 3 points. shortcut tessellation." +msgstr "" + +#: src/cgalutils.cc:605 +msgid "finding good projection" +msgstr "" + +#: src/cgalutils.cc:608 +#, c-format +msgid "plane %s" +msgstr "" + +#: src/cgalutils.cc:609 +#, c-format +msgid "proj: %i %i" +msgstr "" + +#: src/cgalutils.cc:610 +msgid "Inserting points and edges into Constrained Delaunay Triangulation" +msgstr "" + +#: src/cgalutils.cc:632 +#, c-format +msgid "WARNING: Constraint insertion failure %s" +msgstr "" + +#: src/cgalutils.cc:639 +#, c-format +msgid "seeding %i holes" +msgstr "" + +#: src/cgalutils.cc:660 +#, c-format +msgid "seed %f,%f" +msgstr "" + +#: src/cgalutils.cc:662 +msgid "seeding done" +msgstr "" + +#: src/cgalutils.cc:664 +msgid "meshing" +msgstr "" + +#: src/cgalutils.cc:669 +msgid "meshing done" +msgstr "" + +#: src/cgalutils.cc:690 +msgid "WARNING: 2d->3d deprojection failure" +msgstr "" + +#: src/cgalutils.cc:698 +#, c-format +msgid "built %i triangles\n" +msgstr "" + +#: src/cgalutils.cc:741 +msgid "WARNING: triangle doesn't have 3 points. skipping" +msgstr "" + +#: src/cgalutils.cc:941 +#, c-format +msgid "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" +msgstr "" + +#: src/cgalutils.cc:1021 msgid "PolySet has nonplanar faces. Attempting alternate construction" msgstr "" -#: src/CGALEvaluator.cc:697 +#: src/cgalutils.cc:1025 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" msgstr "" -#: src/CGALEvaluator.cc:708 +#: src/cgalutils.cc:1036 #, c-format msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" msgstr "" -#: src/CGAL_Nef_polyhedron.cc:113 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." -msgstr "" - -#: src/CGAL_Nef_polyhedron.cc:114 src/PlatformUtils.cc:19 -#, c-format -msgid "ERROR: %s" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:107 -msgid "Warning: Scaling a 2D object with 0 - removing object" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:137 -msgid "Warning: Scaling a 3D object with 0 - removing object" -msgstr "" - -#: src/cgalutils.cc:138 -#, c-format -msgid "CGAL error in CGAL_Build_PolySet: %s" -msgstr "" - #: src/cgalworker.cc:36 msgid "Rendering cancelled." msgstr "" @@ -910,27 +910,27 @@ msgid "" "normalization.\n" msgstr "" -#: src/dxfdata.cc:83 +#: src/dxfdata.cc:84 #, c-format msgid "WARNING: Can't open DXF file '%s'." msgstr "" -#: src/dxfdata.cc:147 +#: src/dxfdata.cc:148 #, c-format msgid "WARNING: Illegal ID '%s' in `%s'" msgstr "" -#: src/dxfdata.cc:386 +#: src/dxfdata.cc:387 #, c-format msgid "WARNING: Illegal value %s in '%s'" msgstr "" -#: src/dxfdata.cc:392 +#: src/dxfdata.cc:393 #, c-format msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." msgstr "" -#: src/dxfdata.cc:395 +#: src/dxfdata.cc:396 #, c-format msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." msgstr "" @@ -950,40 +950,6 @@ msgstr "" msgid "WARNING: Can't find cross in '%s', layer '%s'!" msgstr "" -#: src/dxftess-cgal.cc:170 -msgid "" -"WARNING: Duplicate vertices and/or intersecting lines found during DXF " -"Tessellation." -msgstr "" - -#: src/dxftess-cgal.cc:171 -msgid "" -"WARNING: Modify the polygon to be a Simple Polygon. Render is incomplete." -msgstr "" - -#: src/dxftess-cgal.cc:176 -#, c-format -msgid "CGAL error in dxf_tesselate(): %s" -msgstr "" - -#: src/dxftess-cgal.cc:475 -#, c-format -msgid "CGAL error in dxftess triangulate_polygon: %s" -msgstr "" - -#: src/dxftess-cgal.cc:491 -msgid "WARNING: PolySet has polygon with <3 points" -msgstr "" - -#: src/dxftess-cgal.cc:496 -msgid "WARNING: PolySet has degenerate polygon" -msgstr "" - -#: src/dxftess-glu.cc:108 src/dxftess-glu.cc:109 -#, c-format -msgid "GLU tesselation error %s" -msgstr "" - #: src/evalcontext.cc:38 #, c-format msgid "EvalContext %p (%p) for %s inst (%p)" @@ -997,19 +963,32 @@ msgstr "" msgid " children:" msgstr "" -#: src/export.cc:48 +#: src/export.cc:180 src/export.cc:225 +msgid "Object isn't a valid 2-manifold! Modify your design.\n" +msgstr "" + +#: src/export.cc:187 +msgid "ERROR: Nef->PolySet failed" +msgstr "" + +#: src/export.cc:199 msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" msgstr "" -#: src/export.cc:120 src/export.cc:137 +#: src/export.cc:205 src/export.cc:234 #, c-format msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" msgstr "" -#: src/export.cc:123 +#: src/export.cc:208 msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" msgstr "" +#: src/expr.cc:166 +#, c-format +msgid "ERROR: Recursion detected calling function '%s'" +msgstr "" + #: src/feature.cc:21 msgid "Enable the concat() function." msgstr "" @@ -1053,6 +1032,69 @@ msgid "" "stack" msgstr "" +#: src/GeometryCache.cc:14 +#, c-format +msgid "Geometry Cache hit: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:24 +#, c-format +msgid "Geometry Cache insert: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:26 +#, c-format +msgid "Geometry Cache insert failed: %s (%d bytes)" +msgstr "" + +#: src/GeometryCache.cc:44 +#, c-format +msgid "Geometries in cache: %d" +msgstr "" + +#: src/GeometryCache.cc:45 +#, c-format +msgid "Geometry cache size in bytes: %d" +msgstr "" + +#: src/GeometryEvaluator.cc:76 +msgid "WARNING: Mixing 2D and 3D objects is not supported." +msgstr "" + +#: src/GeometryEvaluator.cc:188 +msgid "WARNING: Resize in direction normal to flat object is not implemented" +msgstr "" + +#: src/GeometryEvaluator.cc:252 +msgid "WARNING: Ignoring 3D child object for 2D operation" +msgstr "" + +#: src/GeometryEvaluator.cc:276 +msgid "WARNING: GeometryEvaluator: Node didn't fit into cache" +msgstr "" + +#: src/GeometryEvaluator.cc:324 +msgid "WARNING: Ignoring 2D child object for 3D operation" +msgstr "" + +#: src/GeometryEvaluator.cc:365 +#, c-format +msgid "Error: Unknown boolean operation %d" +msgstr "" + +#: src/GeometryEvaluator.cc:517 +msgid "" +"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " +"removing object." +msgstr "" + +#: src/GeometryEvaluator.cc:765 +#, c-format +msgid "" +"ERROR: all points for rotate_extrude() must have the same X coordinate sign " +"(range is %.2f -> %.2f)" +msgstr "" + #: src/handle_dep.cc:36 #, c-format msgid "Can't open dependencies file `%s' for writing!\n" @@ -1066,21 +1108,21 @@ msgstr "" msgid "DEPRECATED: layername= is deprecated. Please use layer=" msgstr "" -#: src/import.cc:195 src/import.cc:281 +#: src/import.cc:201 src/import.cc:286 #, c-format msgid "WARNING: Can't open import file '%s'." msgstr "" -#: src/import.cc:247 +#: src/import.cc:251 #, c-format msgid "WARNING: Can't parse vertex line '%s'." msgstr "" -#: src/import.cc:292 +#: src/import.cc:295 msgid "WARNING: OFF import requires CGAL." msgstr "" -#: src/import.cc:306 +#: src/import.cc:305 #, c-format msgid "ERROR: Unsupported file format while trying to import file '%s'" msgstr "" @@ -1091,12 +1133,7 @@ msgid "" "future releases. Use a child import() instead." msgstr "" -#: src/linearextrude.cc:133 src/projection.cc:74 src/rotateextrude.cc:98 -#, c-format -msgid "WARNING: No suitable PolySetEvaluator found for %s module!" -msgstr "" - -#: src/mainwin.cc:119 +#: src/mainwin.cc:118 msgid "" "Copyright (C) 2009-2013 The OpenSCAD Developers\n" "\n" @@ -1106,272 +1143,254 @@ msgid "" "any later version." msgstr "" -#: src/mainwin.cc:525 +#: src/mainwin.cc:523 msgid "OpenSCAD - New Document[*]" msgstr "" -#: src/mainwin.cc:529 +#: src/mainwin.cc:527 msgid "OpenSCAD - " msgstr "" -#: src/mainwin.cc:529 +#: src/mainwin.cc:527 msgid "[*]" msgstr "" -#: src/mainwin.cc:603 +#: src/mainwin.cc:601 #, c-format msgid "Failed to open file %s: %s" msgstr "" -#: src/mainwin.cc:610 +#: src/mainwin.cc:608 #, c-format msgid "Loaded design '%s'." msgstr "" -#: src/mainwin.cc:657 +#: src/mainwin.cc:655 #, c-format msgid "Module cache size: %d modules" msgstr "" -#: src/mainwin.cc:741 +#: src/mainwin.cc:739 msgid "Compiling design (CSG Tree generation)..." msgstr "" -#: src/mainwin.cc:767 +#: src/mainwin.cc:765 msgid "ERROR: Compilation failed! (no top level object found)" msgstr "" -#: src/mainwin.cc:769 +#: src/mainwin.cc:767 msgid "ERROR: Compilation failed!" msgstr "" -#: src/mainwin.cc:782 +#: src/mainwin.cc:780 msgid "Compiling design (CSG Products generation)..." msgstr "" -#: src/mainwin.cc:804 +#: src/mainwin.cc:801 msgid "ERROR: CSG generation failed! (no top level object found)" msgstr "" -#: src/mainwin.cc:813 +#: src/mainwin.cc:810 msgid "CSG generation cancelled." msgstr "" -#: src/mainwin.cc:839 +#: src/mainwin.cc:836 #, c-format msgid "Compiling highlights (%d CSG Trees)..." msgstr "" -#: src/mainwin.cc:851 +#: src/mainwin.cc:848 #, c-format msgid "Compiling background (%d CSG Trees)..." msgstr "" -#: src/mainwin.cc:864 +#: src/mainwin.cc:861 #, c-format msgid "WARNING: Normalized tree has %d elements!" msgstr "" -#: src/mainwin.cc:865 +#: src/mainwin.cc:862 msgid "WARNING: OpenCSG rendering has been disabled." msgstr "" -#: src/mainwin.cc:878 +#: src/mainwin.cc:875 msgid "CSG generation finished." msgstr "" -#: src/mainwin.cc:880 src/mainwin.cc:1346 +#: src/mainwin.cc:877 src/mainwin.cc:1315 #, c-format msgid "Total rendering time: %d hours, %d minutes, %d seconds" msgstr "" -#: src/mainwin.cc:907 +#: src/mainwin.cc:904 msgid "Open File" msgstr "Открыть файл" -#: src/mainwin.cc:908 +#: src/mainwin.cc:905 msgid "OpenSCAD Designs (*.scad *.csg)" msgstr "Модели OpenSCAD (*.scad *.csg)" -#: src/mainwin.cc:1002 +#: src/mainwin.cc:999 #, c-format msgid "Failed to open file for writing: %s (%s)" msgstr "" -#: src/mainwin.cc:1003 +#: src/mainwin.cc:1000 msgid "" "Failed to open file for writing:\n" " %1 (%2)" msgstr "" -#: src/mainwin.cc:1010 +#: src/mainwin.cc:1007 #, c-format msgid "Saved design '%s'." msgstr "" -#: src/mainwin.cc:1020 +#: src/mainwin.cc:1017 msgid "Save File" msgstr "Сохранить файл" -#: src/mainwin.cc:1021 +#: src/mainwin.cc:1018 msgid "Untitled.scad" msgstr "Безымянный.scad" -#: src/mainwin.cc:1022 +#: src/mainwin.cc:1019 msgid "OpenSCAD Designs (*.scad)" msgstr "Модели OpenSCAD (*.scad)" -#: src/mainwin.cc:1032 +#: src/mainwin.cc:1029 msgid "" "%1 already exists.\n" "Do you want to replace it?" msgstr "" -#: src/mainwin.cc:1047 +#: src/mainwin.cc:1044 #, c-format msgid "WARNING: Library path %s doesn't exist. Creating" msgstr "" -#: src/mainwin.cc:1049 +#: src/mainwin.cc:1046 #, c-format msgid "ERROR: Cannot create library path: %s" msgstr "" -#: src/mainwin.cc:1184 src/mainwin.cc:1857 +#: src/mainwin.cc:1181 src/mainwin.cc:1846 msgid "Application" msgstr "" -#: src/mainwin.cc:1185 +#: src/mainwin.cc:1182 msgid "" "The document has been modified.\n" "Do you really want to reload the file?" msgstr "" -#: src/mainwin.cc:1235 src/mainwin.cc:1279 +#: src/mainwin.cc:1232 src/mainwin.cc:1276 msgid "Parsing design (AST generation)..." msgstr "" -#: src/mainwin.cc:1263 +#: src/mainwin.cc:1260 #, c-format msgid "frame%05d.png" msgstr "" -#: src/mainwin.cc:1300 +#: src/mainwin.cc:1294 msgid "Rendering Polygon Mesh using CGAL..." msgstr "" -#: src/mainwin.cc:1321 -msgid " Top level object is a 2D object:" -msgstr "" - -#: src/mainwin.cc:1322 -#, c-format -msgid " Empty: %6s" -msgstr "" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "yes" -msgstr "" - -#: src/mainwin.cc:1322 src/mainwin.cc:1323 src/mainwin.cc:1334 -#: src/mainwin.cc:1335 -msgid "no" -msgstr "" - -#: src/mainwin.cc:1323 -#, c-format -msgid " Plane: %6s" -msgstr "" - -#: src/mainwin.cc:1324 src/mainwin.cc:1336 -#, c-format -msgid " Vertices: %6d" -msgstr "" - -#: src/mainwin.cc:1325 src/mainwin.cc:1337 -#, c-format -msgid " Halfedges: %6d" -msgstr "" - -#: src/mainwin.cc:1326 src/mainwin.cc:1338 -#, c-format -msgid " Edges: %6d" -msgstr "" - -#: src/mainwin.cc:1327 -#, c-format -msgid " Faces: %6d" -msgstr "" - -#: src/mainwin.cc:1328 -#, c-format -msgid " FaceCycles: %6d" -msgstr "" - -#: src/mainwin.cc:1329 -#, c-format -msgid " ConnComp: %6d" -msgstr "" - -#: src/mainwin.cc:1333 +#: src/mainwin.cc:1320 src/mainwin.cc:1334 msgid " Top level object is a 3D object:" msgstr "" -#: src/mainwin.cc:1334 +#: src/mainwin.cc:1321 #, c-format msgid " Simple: %6s" msgstr "" -#: src/mainwin.cc:1335 +#: src/mainwin.cc:1321 src/mainwin.cc:1322 +msgid "yes" +msgstr "" + +#: src/mainwin.cc:1321 src/mainwin.cc:1322 +msgid "no" +msgstr "" + +#: src/mainwin.cc:1322 #, c-format msgid " Valid: %6s" msgstr "" -#: src/mainwin.cc:1339 +#: src/mainwin.cc:1323 +#, c-format +msgid " Vertices: %6d" +msgstr "" + +#: src/mainwin.cc:1324 +#, c-format +msgid " Halfedges: %6d" +msgstr "" + +#: src/mainwin.cc:1325 +#, c-format +msgid " Edges: %6d" +msgstr "" + +#: src/mainwin.cc:1326 #, c-format msgid " Halffacets: %6d" msgstr "" -#: src/mainwin.cc:1340 +#: src/mainwin.cc:1327 src/mainwin.cc:1335 #, c-format msgid " Facets: %6d" msgstr "" -#: src/mainwin.cc:1341 +#: src/mainwin.cc:1328 #, c-format msgid " Volumes: %6d" msgstr "" -#: src/mainwin.cc:1359 +#: src/mainwin.cc:1337 +msgid " Top level object is a 2D object:" +msgstr "" + +#: src/mainwin.cc:1338 +#, c-format +msgid " Contours: %6d" +msgstr "" + +#: src/mainwin.cc:1340 +msgid "Unknown geometry type" +msgstr "" + +#: src/mainwin.cc:1342 msgid "Rendering finished." msgstr "" -#: src/mainwin.cc:1362 +#: src/mainwin.cc:1351 msgid "WARNING: No top level geometry to render" msgstr "" -#: src/mainwin.cc:1380 +#: src/mainwin.cc:1368 msgid "AST Dump" msgstr "" -#: src/mainwin.cc:1385 +#: src/mainwin.cc:1373 msgid "No AST to dump. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1398 +#: src/mainwin.cc:1386 msgid "CSG Tree Dump" msgstr "" -#: src/mainwin.cc:1403 +#: src/mainwin.cc:1391 msgid "No CSG to dump. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1416 +#: src/mainwin.cc:1404 msgid "CSG Products Dump" msgstr "" -#: src/mainwin.cc:1418 +#: src/mainwin.cc:1406 msgid "" "\n" "CSG before normalization:\n" @@ -1394,135 +1413,136 @@ msgid "" "%5\n" msgstr "" -#: src/mainwin.cc:1441 src/mainwin.cc:1501 +#: src/mainwin.cc:1429 src/mainwin.cc:1490 msgid "Nothing to export! Try building first (press F6)." msgstr "" -#: src/mainwin.cc:1447 +#: src/mainwin.cc:1435 msgid "Current top level object is not a 3D object." msgstr "" -#: src/mainwin.cc:1453 +#: src/mainwin.cc:1442 msgid "" "Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." "org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" msgstr "" -#: src/mainwin.cc:1460 +#: src/mainwin.cc:1449 msgid "Export STL File" msgstr "" -#: src/mainwin.cc:1460 +#: src/mainwin.cc:1449 msgid "Export OFF File" msgstr "" -#: src/mainwin.cc:1462 +#: src/mainwin.cc:1451 msgid "STL Files (*.stl)" msgstr "" -#: src/mainwin.cc:1462 +#: src/mainwin.cc:1451 msgid "OFF Files (*.off)" msgstr "" -#: src/mainwin.cc:1464 +#: src/mainwin.cc:1453 #, c-format msgid "No filename specified. %s export aborted." msgstr "" -#: src/mainwin.cc:1471 src/mainwin.cc:1524 src/mainwin.cc:1557 -#: src/openscad.cc:316 src/openscad.cc:328 src/openscad.cc:346 -#: src/openscad.cc:397 src/openscad.cc:416 src/openscad.cc:431 -#: src/openscad.cc:442 +#: src/mainwin.cc:1460 src/mainwin.cc:1513 src/mainwin.cc:1546 +#: src/openscad.cc:313 src/openscad.cc:325 src/openscad.cc:343 +#: src/openscad.cc:391 src/openscad.cc:406 src/openscad.cc:421 +#: src/openscad.cc:432 #, c-format msgid "Can't open file \"%s\" for export" msgstr "" -#: src/mainwin.cc:1478 +#: src/mainwin.cc:1467 #, c-format msgid "%s export finished." msgstr "" -#: src/mainwin.cc:1507 +#: src/mainwin.cc:1496 msgid "Current top level object is not a 2D object." msgstr "" -#: src/mainwin.cc:1513 +#: src/mainwin.cc:1502 msgid "Export DXF File" msgstr "" -#: src/mainwin.cc:1514 +#: src/mainwin.cc:1503 msgid "Untitled.dxf" msgstr "" -#: src/mainwin.cc:1515 +#: src/mainwin.cc:1504 msgid "DXF Files (*.dxf)" msgstr "" -#: src/mainwin.cc:1517 +#: src/mainwin.cc:1506 msgid "No filename specified. DXF export aborted." msgstr "" -#: src/mainwin.cc:1529 +#: src/mainwin.cc:1518 msgid "DXF export finished." msgstr "" -#: src/mainwin.cc:1541 +#: src/mainwin.cc:1530 msgid "Nothing to export. Please try compiling first..." msgstr "" -#: src/mainwin.cc:1546 +#: src/mainwin.cc:1535 msgid "Export CSG File" msgstr "" -#: src/mainwin.cc:1547 +#: src/mainwin.cc:1536 msgid "Untitled.csg" msgstr "" -#: src/mainwin.cc:1548 +#: src/mainwin.cc:1537 msgid "CSG Files (*.csg)" msgstr "" -#: src/mainwin.cc:1550 +#: src/mainwin.cc:1539 msgid "No filename specified. CSG export aborted." msgstr "" -#: src/mainwin.cc:1562 +#: src/mainwin.cc:1551 msgid "CSG export finished." msgstr "" -#: src/mainwin.cc:1573 +#: src/mainwin.cc:1562 msgid "Export Image" msgstr "" -#: src/mainwin.cc:1573 +#: src/mainwin.cc:1562 msgid "PNG Files (*.png)" msgstr "" -#: src/mainwin.cc:1575 +#: src/mainwin.cc:1564 msgid "No filename specified. Image export aborted." msgstr "" -#: src/mainwin.cc:1827 +#: src/mainwin.cc:1816 msgid "http://openscad.org/" msgstr "" -#: src/mainwin.cc:1833 +#: src/mainwin.cc:1822 msgid "http://www.openscad.org/documentation.html" msgstr "" -#: src/mainwin.cc:1842 +#: src/mainwin.cc:1831 msgid "OpenGL Info" msgstr "" -#: src/mainwin.cc:1842 +#: src/mainwin.cc:1831 msgid "OpenSCAD Detailed Library and Build Information" msgstr "Подробная информация о библиотеках и сборке OpenSCAD" -#: src/mainwin.cc:1858 +#: src/mainwin.cc:1847 msgid "" "The document has been modified.\n" "Do you want to save your changes?" -msgstr "Документ был изменен.\n" +msgstr "" +"Документ был изменен.\n" "Сохранить изменения?" #: src/modcontext.cc:100 @@ -1552,6 +1572,15 @@ msgstr "" msgid "ModuleContext: %p (%p)" msgstr "" +#: src/modcontext.cc:193 +#, c-format +msgid "New lib Context for %s func:" +msgstr "" + +#: src/modcontext.cc:217 +msgid "New file Context:" +msgstr "" + #: src/ModuleCache.cc:70 #, c-format msgid "Recompiling cached library: %s (%s)" @@ -1572,6 +1601,10 @@ msgstr "" msgid " compiled module: %p" msgstr "" +#: src/module.cc:139 +msgid "New eval ctx:" +msgstr "" + #: src/module.cc:180 #, c-format msgid "ERROR: Recursion detected calling module '%s'" @@ -1582,7 +1615,11 @@ msgstr "" msgid "WARNING: Failed to compile library '%s'." msgstr "" -#: src/openscad.cc:109 +#: src/OffscreenView.cc:27 +msgid "OpenSCAD recommended OpenGL version is 2.0." +msgstr "" + +#: src/openscad.cc:107 msgid "" "Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" "%2%[ -m make_command ] [ -D var=val [..] ] \\\n" @@ -1595,154 +1632,150 @@ msgid "" "%2%filename\n" msgstr "" -#: src/openscad.cc:126 +#: src/openscad.cc:124 #, c-format msgid "OpenSCAD version %s\n" msgstr "" -#: src/openscad.cc:138 +#: src/openscad.cc:136 #, c-format msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" msgstr "" -#: src/openscad.cc:182 +#: src/openscad.cc:180 msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" msgstr "" -#: src/openscad.cc:183 +#: src/openscad.cc:181 msgid "or 6 numbers for Vector Camera\n" msgstr "" -#: src/openscad.cc:199 +#: src/openscad.cc:197 msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" msgstr "" -#: src/openscad.cc:210 +#: src/openscad.cc:208 msgid "Need 2 numbers for imgsize\n" msgstr "" -#: src/openscad.cc:260 +#: src/openscad.cc:257 #, c-format msgid "Unknown suffix for output file %s\n" msgstr "" -#: src/openscad.cc:284 +#: src/openscad.cc:281 #, c-format msgid "Can't open input file '%s'!\n" msgstr "" -#: src/openscad.cc:293 +#: src/openscad.cc:290 #, c-format msgid "Can't parse file '%s'!\n" msgstr "" -#: src/openscad.cc:375 +#: src/openscad.cc:373 #, c-format msgid "Output file:%s\n" msgstr "" -#: src/openscad.cc:376 +#: src/openscad.cc:374 msgid "Sorry, don't know how to write deps for that file type. Exiting\n" msgstr "" -#: src/openscad.cc:381 +#: src/openscad.cc:379 msgid "error writing deps" msgstr "" -#: src/openscad.cc:388 src/openscad.cc:407 +#: src/openscad.cc:386 src/openscad.cc:401 msgid "Current top level object is not a 3D object.\n" msgstr "" -#: src/openscad.cc:392 src/openscad.cc:411 -msgid "Object isn't a valid 2-manifold! Modify your design.\n" -msgstr "" - -#: src/openscad.cc:426 +#: src/openscad.cc:416 msgid "Current top level object is not a 2D object.\n" msgstr "" -#: src/openscad.cc:591 +#: src/openscad.cc:594 msgid "Allowed options" msgstr "" -#: src/openscad.cc:593 +#: src/openscad.cc:596 msgid "help message" msgstr "" -#: src/openscad.cc:594 +#: src/openscad.cc:597 msgid "print the version" msgstr "" -#: src/openscad.cc:595 +#: src/openscad.cc:598 msgid "print information about the building process" msgstr "" -#: src/openscad.cc:596 +#: src/openscad.cc:599 msgid "if exporting a png image, do a full CGAL render" msgstr "" -#: src/openscad.cc:597 +#: src/openscad.cc:600 msgid "" "if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" msgstr "" -#: src/openscad.cc:598 +#: src/openscad.cc:601 msgid "parameters for camera when exporting png" msgstr "" -#: src/openscad.cc:599 +#: src/openscad.cc:602 msgid "=width,height for exporting png" msgstr "" -#: src/openscad.cc:600 +#: src/openscad.cc:603 msgid "(o)rtho or (p)erspective when exporting png" msgstr "" -#: src/openscad.cc:601 +#: src/openscad.cc:604 msgid "out-file" msgstr "" -#: src/openscad.cc:602 +#: src/openscad.cc:605 msgid "stl-file" msgstr "" -#: src/openscad.cc:603 +#: src/openscad.cc:606 msgid "dxf-file" msgstr "" -#: src/openscad.cc:604 +#: src/openscad.cc:607 msgid "deps-file" msgstr "" -#: src/openscad.cc:605 +#: src/openscad.cc:608 msgid "makefile" msgstr "" -#: src/openscad.cc:606 +#: src/openscad.cc:609 msgid "var=val" msgstr "" -#: src/openscad.cc:607 +#: src/openscad.cc:610 msgid "enable experimental features" msgstr "" -#: src/openscad.cc:609 +#: src/openscad.cc:612 msgid "Hidden options" msgstr "" -#: src/openscad.cc:611 +#: src/openscad.cc:614 msgid "input file" msgstr "" -#: src/openscad.cc:645 +#: src/openscad.cc:648 msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:650 +#: src/openscad.cc:653 msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" msgstr "" -#: src/openscad.cc:707 +#: src/openscad.cc:710 msgid "Requested GUI mode but can't open display!\n" msgstr "" @@ -1751,158 +1784,93 @@ msgstr "" msgid "ERROR: Cannot create %s" msgstr "" -#: src/PolySetCache.cc:24 -#, c-format -msgid "PolySets in cache: %d" -msgstr "" - -#: src/PolySetCache.cc:25 -#, c-format -msgid "PolySet cache size in bytes: %d" -msgstr "" - -#: src/polyset.cc:55 +#: src/polyset.cc:63 msgid "PolySet:" msgstr "" -#: src/polyset.cc:56 +#: src/polyset.cc:64 msgid "" "\n" " dimensions:" msgstr "" -#: src/polyset.cc:57 +#: src/polyset.cc:65 msgid "" "\n" " convexity:" msgstr "" -#: src/polyset.cc:58 +#: src/polyset.cc:66 msgid "" "\n" " num polygons: " msgstr "" -#: src/polyset.cc:59 +#: src/polyset.cc:67 msgid "" "\n" -" num borders: " +" num outlines: " msgstr "" -#: src/polyset.cc:60 +#: src/polyset.cc:68 msgid "" "\n" " polygons data:" msgstr "" -#: src/polyset.cc:62 +#: src/polyset.cc:70 msgid "" "\n" " polygon begin:" msgstr "" -#: src/polyset.cc:66 src/polyset.cc:75 +#: src/polyset.cc:74 msgid "" "\n" " vertex:" msgstr "" -#: src/polyset.cc:69 +#: src/polyset.cc:77 msgid "" "\n" -" borders data:" +" outlines data:" msgstr "" -#: src/polyset.cc:71 -msgid "" -"\n" -" border polygon begin:" -msgstr "" - -#: src/polyset.cc:78 +#: src/polyset.cc:79 msgid "" "\n" "PolySet end" msgstr "" -#: src/PolySetCGALEvaluator.cc:46 -msgid "" -"WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your " -"design.." -msgstr "" - -#: src/PolySetCGALEvaluator.cc:63 -#, c-format -msgid "CGAL error in projection node during plane intersection: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:65 -msgid "Trying alternative intersection using very large thin box: " -msgstr "" - -#: src/PolySetCGALEvaluator.cc:80 -#, c-format -msgid "CGAL error in projection node during bigbox intersection: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:87 -msgid "WARNING: projection() failed." -msgstr "" - -#: src/PolySetCGALEvaluator.cc:109 -#, c-format -msgid "CGAL error in projection node while flattening: %s" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:303 -msgid "ERROR: linear_extrude() is not defined for 3D child objects!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:343 -#, c-format -msgid "" -"WARNING: Open paths in dxf_linear_extrude(file = \"%s\", layer = \"%s\"):" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:403 -msgid "ERROR: rotate_extrude() is not defined for 3D child objects!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:441 -msgid "WARNING: Body of render() isn't valid 2-manifold!" -msgstr "" - -#: src/PolySetCGALEvaluator.cc:466 -#, c-format -msgid "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" -msgstr "" - -#: src/primitives.cc:130 +#: src/primitives.cc:134 #, c-format msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." msgstr "" -#: src/primitives.cc:183 +#: src/primitives.cc:187 #, c-format msgid "WARNING: $fs too small - clamping to %f" msgstr "" -#: src/primitives.cc:187 +#: src/primitives.cc:191 #, c-format msgid "WARNING: $fa too small - clamping to %f" msgstr "" -#: src/primitives.cc:244 +#: src/primitives.cc:248 msgid "" "DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " "polyhedron(faces=[]) instead." msgstr "" -#: src/primitives.cc:536 +#: src/primitives.cc:515 #, c-format -msgid "ERROR: Unable to convert point at index %d to a vec2 of numbers" +msgid "ERROR: Unable to convert point at index %d to a vec3 of numbers" +msgstr "" + +#: src/primitives.cc:575 +#, c-format +msgid "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" msgstr "" #: src/QGLView.cc:105 @@ -1947,7 +1915,7 @@ msgid "" "distance = %.2f" msgstr "" -#: src/rotateextrude.cc:72 +#: src/rotateextrude.cc:71 msgid "" "DEPRECATED: Support for reading files in rotate_extrude will be removed in " "future releases. Use a child import() instead." @@ -1963,8 +1931,20 @@ msgstr "" msgid "WARNING: Illegal value in '%s': %s" msgstr "" -#: src/value.cc:640 +#: src/value.cc:644 msgid "" "DEPRECATED: Using ranges of the form [begin:end] with begin value greater " "than the end value is deprecated." msgstr "" + +#~ msgid "About OpenSCAD" +#~ msgstr "О программе OpenSCAD" + +#~ msgid "&Compile" +#~ msgstr "&Компилировать" + +#~ msgid "Compile and &Render (CGAL)" +#~ msgstr "Компилировать и &отрисовать (CGAL)" + +#~ msgid "CGAL Grid Only" +#~ msgstr "Только сетка CGAL" From 27594848dbe6180ad5cd1f70657fc7debefe6d52 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 19 Oct 2014 17:41:22 +0200 Subject: [PATCH 027/263] Fix translation file build on Windows; Use host gettext tools. --- openscad.pro | 2 +- scripts/generate-potfiles.sh | 8 +++++++- scripts/translation-make.sh | 21 +++++++++++++++++++++ scripts/translation-update.sh | 21 ++++++++++++++++----- 4 files changed, 45 insertions(+), 7 deletions(-) create mode 100755 scripts/translation-make.sh diff --git a/openscad.pro b/openscad.pro index ce21d5dc..cab317f0 100644 --- a/openscad.pro +++ b/openscad.pro @@ -492,7 +492,7 @@ INSTALLS += target isEmpty(LOCALE_PREFIX): LOCALE_PREFIX = $$PREFIX/share/openscad/locale # Run translation update scripts as last step after linking the target -QMAKE_POST_LINK += ./scripts/generate-potfiles.sh > po/POTFILES ; ./scripts/translation-update.sh +QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh # Create install targets for the languages defined in LINGUAS LINGUAS = $$cat(po/LINGUAS) diff --git a/scripts/generate-potfiles.sh b/scripts/generate-potfiles.sh index 8414cc23..2298aba9 100755 --- a/scripts/generate-potfiles.sh +++ b/scripts/generate-potfiles.sh @@ -7,7 +7,13 @@ for ui in src/*.ui do UI="${ui#src/}" UI="${UI%.ui}" - echo "objects/ui_$UI.h" + for d in mingw64 mingw32 . + do + if [ -f "$d/objects/ui_$UI.h" ] + then + echo "$d/objects/ui_$UI.h" + fi + done done for src in src/*.h src/*.cc diff --git a/scripts/translation-make.sh b/scripts/translation-make.sh new file mode 100755 index 00000000..0ca06756 --- /dev/null +++ b/scripts/translation-make.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Script for use from qmake to generate the translation +# related files. +# +# Step 1) call generate-potfiles.sh to collect input files +# Step 2) call translation-update.sh to generate *.mo files +# + +SCRIPTDIR="`dirname \"$0\"`" +TOPDIR="`dirname \"$SCRIPTDIR\"`" + +cd "$TOPDIR" + +echo "Generating POTFILES..." +./scripts/generate-potfiles.sh > po/POTFILES + +echo "Updating translation files..." +./scripts/translation-update.sh + +echo "Done. \ No newline at end of file diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index 2f8c5c8a..bba298bc 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -4,10 +4,21 @@ updatepot() { - if [ ! -e objects/ui_MainWindow.h ]; then - echo cannot find objects/ui_xxxxx.h files. perhaps if you run make...? + # check we have all files from POTFILES present + while read f + do + if [ ! -f "$f" ]; then + echo "cannot find file '$f' from POTFILES" + exit 1 + fi + done < po/POTFILES + + grep ui_MainWindow.h po/POTFILES >/dev/null 2>/dev/null + if [ $? -ne 0 ] ; then + echo "cannot find .../ui_xxxxx.h files. perhaps if you run make...?" exit 1 fi + VER=`date +"%Y.%m.%d"` OPTS= OPTS=$OPTS' --package-name=OpenSCAD' @@ -56,9 +67,9 @@ updatemo() } GETTEXT_PATH="" -if [ "x$OPENSCAD_LIBRARIES" != x ]; then - GETTEXT_PATH="$OPENSCAD_LIBRARIES/bin/" -fi +#if [ "x$OPENSCAD_LIBRARIES" != x ]; then +# GETTEXT_PATH="$OPENSCAD_LIBRARIES/bin/" +#fi if [ "x$1" = xupdatemo ]; then updatemo From d6989488daa84fc9f22e52c9bbff1d64188a5f9e Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 19 Oct 2014 18:01:50 +0200 Subject: [PATCH 028/263] Fix typo in script. --- scripts/translation-make.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/translation-make.sh b/scripts/translation-make.sh index 0ca06756..f9877661 100755 --- a/scripts/translation-make.sh +++ b/scripts/translation-make.sh @@ -18,4 +18,4 @@ echo "Generating POTFILES..." echo "Updating translation files..." ./scripts/translation-update.sh -echo "Done. \ No newline at end of file +echo "Done." \ No newline at end of file From f0ce0e663e4f3b70c569fdcabfc5e4eabd2355a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Sun, 19 Oct 2014 18:34:57 +0200 Subject: [PATCH 029/263] Add Czech translation from #614. --- po/LINGUAS | 2 +- po/cs.po | 1146 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1147 insertions(+), 1 deletion(-) create mode 100644 po/cs.po diff --git a/po/LINGUAS b/po/LINGUAS index f7f046e1..9f82de46 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1,2 +1,2 @@ # available languages -fr ru de +fr ru de cs diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 00000000..64dab28b --- /dev/null +++ b/po/cs.po @@ -0,0 +1,1146 @@ +# Czech translations for OpenSCAD package. +# Copyright (C) 2014 THE OpenSCAD'S COPYRIGHT HOLDER +# This file is distributed under the same license as the OpenSCAD package. +# Miro Hrončok , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2013.02.24\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-10-19 18:27+0200\n" +"PO-Revision-Date: 2014-01-29 18:32+0100\n" +"Last-Translator: Miro Hrončok \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>=2 && n<=4 ? 1 : 2;\n" +"X-Poedit-SourceCharset: UTF-8\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "" + +#: objects/ui_FontListDialog.h:102 +#, fuzzy +msgid "OpenSCAD Font List" +msgstr "Manuál k OpenSCADu (anglicky)" + +#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 +msgid "&OK" +msgstr "" + +#: objects/ui_FontListDialog.h:105 +msgid "Paste font selector to Editor Window" +msgstr "" + +#: objects/ui_FontListDialog.h:107 +msgid "Copy to Clipboard" +msgstr "" + +#: objects/ui_FontListDialog.h:108 +msgid "Filter:" +msgstr "" + +#: objects/ui_FontListDialog.h:109 +msgid "" +"

This list shows the fonts currently registered with " +"OpenSCAD.

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" +msgstr "" + +#: objects/ui_LibraryInfoDialog.h:75 +msgid "Lib & Build Info" +msgstr "" + +#: objects/ui_LibraryInfoDialog.h:76 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "" + +#: objects/ui_MainWindow.h:732 +msgid "&New" +msgstr "&Nový" + +#: objects/ui_MainWindow.h:733 +msgid "Ctrl+N" +msgstr "" + +#: objects/ui_MainWindow.h:734 +msgid "&Open..." +msgstr "&Otevřít..." + +#: objects/ui_MainWindow.h:735 +msgid "Ctrl+O" +msgstr "" + +#: objects/ui_MainWindow.h:736 +msgid "&Save" +msgstr "&Uložit" + +#: objects/ui_MainWindow.h:737 +msgid "Ctrl+S" +msgstr "" + +#: objects/ui_MainWindow.h:738 +msgid "Save &As..." +msgstr "Uložit &jako..." + +#: objects/ui_MainWindow.h:739 +msgid "Ctrl+Shift+S" +msgstr "" + +#: objects/ui_MainWindow.h:740 +msgid "&Reload" +msgstr "&Znovu načíst" + +#: objects/ui_MainWindow.h:741 +msgid "Ctrl+R" +msgstr "" + +#: objects/ui_MainWindow.h:742 +msgid "&Quit" +msgstr "U&končit" + +#: objects/ui_MainWindow.h:743 +msgid "Ctrl+Q" +msgstr "" + +#: objects/ui_MainWindow.h:744 +msgid "&Undo" +msgstr "&Zpět" + +#: objects/ui_MainWindow.h:745 +msgid "Ctrl+Z" +msgstr "" + +#: objects/ui_MainWindow.h:746 +msgid "&Redo" +msgstr "Zn&ovu" + +#: objects/ui_MainWindow.h:747 +msgid "Ctrl+Shift+Z" +msgstr "" + +#: objects/ui_MainWindow.h:748 +msgid "Cu&t" +msgstr "&Vyjmout" + +#: objects/ui_MainWindow.h:749 +msgid "Ctrl+X" +msgstr "" + +#: objects/ui_MainWindow.h:750 +msgid "&Copy" +msgstr "&Kopírovat" + +#: objects/ui_MainWindow.h:751 +msgid "Ctrl+C" +msgstr "" + +#: objects/ui_MainWindow.h:752 +msgid "&Paste" +msgstr "V&ložit" + +#: objects/ui_MainWindow.h:753 +msgid "Ctrl+V" +msgstr "" + +#: objects/ui_MainWindow.h:754 +msgid "&Indent" +msgstr "Odsad&it" + +#: objects/ui_MainWindow.h:755 +msgid "Ctrl+I" +msgstr "" + +#: objects/ui_MainWindow.h:756 +msgid "U&nindent" +msgstr "Z&rušit odsazení" + +#: objects/ui_MainWindow.h:757 +msgid "Ctrl+Shift+I" +msgstr "" + +#: objects/ui_MainWindow.h:758 +msgid "C&omment" +msgstr "&Zakomentovat" + +#: objects/ui_MainWindow.h:759 +msgid "Ctrl+D" +msgstr "" + +#: objects/ui_MainWindow.h:760 +msgid "Unco&mment" +msgstr "&Odkomentovat" + +#: objects/ui_MainWindow.h:761 +msgid "Ctrl+Shift+D" +msgstr "" + +#: objects/ui_MainWindow.h:762 +msgid "Paste viewport translation" +msgstr "Vložit posun pohledu" + +#: objects/ui_MainWindow.h:763 +msgid "Ctrl+T" +msgstr "" + +#: objects/ui_MainWindow.h:764 +msgid "Paste viewport rotation" +msgstr "Vložit rotaci pohledu" + +#: objects/ui_MainWindow.h:765 objects/ui_MainWindow.h:844 +msgid "Zoom In" +msgstr "Přiblížit" + +#: objects/ui_MainWindow.h:766 +msgid "Ctrl++" +msgstr "" + +#: objects/ui_MainWindow.h:767 objects/ui_MainWindow.h:846 +msgid "Zoom Out" +msgstr "Oddálit" + +#: objects/ui_MainWindow.h:768 +msgid "Ctrl+-" +msgstr "" + +#: objects/ui_MainWindow.h:769 +msgid "Hide editor" +msgstr "Skrýt editor" + +#: objects/ui_MainWindow.h:770 +#, fuzzy +msgid "&Reload and Preview" +msgstr "Znovu &načíst a zkompilovat" + +#: objects/ui_MainWindow.h:771 +msgid "F4" +msgstr "" + +#: objects/ui_MainWindow.h:772 +msgid "&Preview" +msgstr "" + +#: objects/ui_MainWindow.h:773 +msgid "F5" +msgstr "" + +#: objects/ui_MainWindow.h:774 +msgid "&Render" +msgstr "" + +#: objects/ui_MainWindow.h:775 +msgid "F6" +msgstr "" + +#: objects/ui_MainWindow.h:776 +msgid "Check Validity" +msgstr "" + +#: objects/ui_MainWindow.h:777 +msgid "Display &AST..." +msgstr "Ukázat &ATS..." + +#: objects/ui_MainWindow.h:778 +msgid "Display CSG &Tree..." +msgstr "Ukázat CSG s&trom..." + +#: objects/ui_MainWindow.h:779 +msgid "Display CSG &Products..." +msgstr "Ukázat CSG &produkty..." + +#: objects/ui_MainWindow.h:780 +msgid "Export as &STL..." +msgstr "Exportovat jako &STL..." + +#: objects/ui_MainWindow.h:781 +msgid "Export as &OFF..." +msgstr "Exportovat jako &OFF..." + +#: objects/ui_MainWindow.h:782 +msgid "Preview" +msgstr "" + +#: objects/ui_MainWindow.h:783 +msgid "F9" +msgstr "" + +#: objects/ui_MainWindow.h:784 +#, fuzzy +msgid "Surfaces" +msgstr "CGAL povrch" + +#: objects/ui_MainWindow.h:785 +msgid "F10" +msgstr "" + +#: objects/ui_MainWindow.h:786 +msgid "Wireframe" +msgstr "" + +#: objects/ui_MainWindow.h:787 +msgid "F11" +msgstr "" + +#: objects/ui_MainWindow.h:788 +msgid "Thrown Together" +msgstr "Vše společně" + +#: objects/ui_MainWindow.h:789 +msgid "F12" +msgstr "" + +#: objects/ui_MainWindow.h:790 +msgid "Show Edges" +msgstr "Zobrazit hrany" + +#: objects/ui_MainWindow.h:791 +msgid "Ctrl+1" +msgstr "" + +#: objects/ui_MainWindow.h:792 +msgid "Show Axes" +msgstr "Zobrazit osy" + +#: objects/ui_MainWindow.h:793 +msgid "Ctrl+2" +msgstr "" + +#: objects/ui_MainWindow.h:794 +msgid "Show Crosshairs" +msgstr "Zobrazit zaměřovač" + +#: objects/ui_MainWindow.h:795 +msgid "Ctrl+3" +msgstr "" + +#: objects/ui_MainWindow.h:796 +msgid "Animate" +msgstr "Animovat" + +#: objects/ui_MainWindow.h:797 +msgid "Top" +msgstr "Shora" + +#: objects/ui_MainWindow.h:798 +msgid "Ctrl+4" +msgstr "" + +#: objects/ui_MainWindow.h:799 +msgid "Bottom" +msgstr "Zespoda" + +#: objects/ui_MainWindow.h:800 +msgid "Ctrl+5" +msgstr "" + +#: objects/ui_MainWindow.h:801 +msgid "Left" +msgstr "Zleva" + +#: objects/ui_MainWindow.h:802 +msgid "Ctrl+6" +msgstr "" + +#: objects/ui_MainWindow.h:803 +msgid "Right" +msgstr "Zprava" + +#: objects/ui_MainWindow.h:804 +msgid "Ctrl+7" +msgstr "" + +#: objects/ui_MainWindow.h:805 +msgid "Front" +msgstr "Zepředu" + +#: objects/ui_MainWindow.h:806 +msgid "Ctrl+8" +msgstr "" + +#: objects/ui_MainWindow.h:807 +msgid "Back" +msgstr "Zezadu" + +#: objects/ui_MainWindow.h:808 +msgid "Ctrl+9" +msgstr "" + +#: objects/ui_MainWindow.h:809 +msgid "Diagonal" +msgstr "Diagonálně" + +#: objects/ui_MainWindow.h:810 +msgid "Ctrl+0" +msgstr "" + +#: objects/ui_MainWindow.h:811 +msgid "Center" +msgstr "Vycentrovat" + +#: objects/ui_MainWindow.h:812 +msgid "Perspective" +msgstr "Perspektivně" + +#: objects/ui_MainWindow.h:813 +msgid "Orthogonal" +msgstr "Ortogonálně" + +#: objects/ui_MainWindow.h:814 +msgid "Hide console" +msgstr "Skrýt terminál" + +#: objects/ui_MainWindow.h:815 +msgid "About" +msgstr "O aplikaci" + +#: objects/ui_MainWindow.h:816 +msgid "Documentation" +msgstr "" + +#: objects/ui_MainWindow.h:817 +msgid "Clear Recent" +msgstr "Zapomenout nedávné" + +#: objects/ui_MainWindow.h:818 +msgid "Export as DXF..." +msgstr "Exportovat jako &DXF" + +#: objects/ui_MainWindow.h:819 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "Zavřít" + +#: objects/ui_MainWindow.h:820 +msgid "Ctrl+W" +msgstr "" + +#: objects/ui_MainWindow.h:821 objects/ui_Preferences.h:609 +msgid "Preferences" +msgstr "Předvolby" + +#: objects/ui_MainWindow.h:822 +msgid "Find..." +msgstr "" + +#: objects/ui_MainWindow.h:823 +msgid "Ctrl+F" +msgstr "" + +#: objects/ui_MainWindow.h:824 +msgid "Find and Replace..." +msgstr "" + +#: objects/ui_MainWindow.h:825 +msgid "Ctrl+Alt+F" +msgstr "" + +#: objects/ui_MainWindow.h:826 +msgid "Find Next" +msgstr "" + +#: objects/ui_MainWindow.h:827 +msgid "Ctrl+G" +msgstr "" + +#: objects/ui_MainWindow.h:828 +msgid "Find Previous" +msgstr "" + +#: objects/ui_MainWindow.h:829 +msgid "Ctrl+Shift+G" +msgstr "" + +#: objects/ui_MainWindow.h:830 +msgid "Use Selection for Find" +msgstr "" + +#: objects/ui_MainWindow.h:831 +msgid "Ctrl+E" +msgstr "" + +#: objects/ui_MainWindow.h:832 +msgid "Flush Caches" +msgstr "Vyprázdnit mezipaměť" + +#: objects/ui_MainWindow.h:833 +msgid "OpenSCAD Homepage" +msgstr "Domovská stránka OpenSCADu" + +#: objects/ui_MainWindow.h:834 +#, fuzzy +msgid "Automatic Reload and Preview" +msgstr "Automaticky načítat a kompilovat" + +#: objects/ui_MainWindow.h:835 +msgid "Export as Image..." +msgstr "Exportovat jako obrázek..." + +#: objects/ui_MainWindow.h:836 +msgid "Export as CSG..." +msgstr "Exportovat jako CSG..." + +#: objects/ui_MainWindow.h:837 +msgid "Library info" +msgstr "Informace o knihovnách" + +#: objects/ui_MainWindow.h:838 +msgid "Check for Update.." +msgstr "" + +#: objects/ui_MainWindow.h:839 +msgid "Show Library Folder..." +msgstr "" + +#: objects/ui_MainWindow.h:840 +msgid "Reset View" +msgstr "" + +#: objects/ui_MainWindow.h:841 +#, fuzzy +msgid "Font List" +msgstr "Písmo" + +#: objects/ui_MainWindow.h:842 +#, fuzzy +msgid "Export as SVG..." +msgstr "Exportovat jako CSG..." + +#: objects/ui_MainWindow.h:843 +#, fuzzy +msgid "Export as AMF..." +msgstr "Exportovat jako &DXF" + +#: objects/ui_MainWindow.h:845 +msgid "Ctrl+]" +msgstr "" + +#: objects/ui_MainWindow.h:847 +msgid "Ctrl+[" +msgstr "" + +#: objects/ui_MainWindow.h:848 +#, fuzzy +msgid "View All" +msgstr "&Zobrazit" + +#: objects/ui_MainWindow.h:849 +msgid "Convert Tabs to Spaces" +msgstr "" + +#: objects/ui_MainWindow.h:850 +#, fuzzy +msgid "Hide toolbars" +msgstr "Skrýt editor" + +#: objects/ui_MainWindow.h:851 +msgid "Time:" +msgstr "Čas:" + +#: objects/ui_MainWindow.h:852 +msgid "FPS:" +msgstr "FPS:" + +#: objects/ui_MainWindow.h:853 +msgid "Steps:" +msgstr "Kroky:" + +#: objects/ui_MainWindow.h:854 +msgid "Dump Pictures" +msgstr "Ukládat obrázky" + +#: objects/ui_MainWindow.h:855 +msgid "&File" +msgstr "&Soubor" + +#: objects/ui_MainWindow.h:856 +msgid "Recent Files" +msgstr "" + +#: objects/ui_MainWindow.h:857 objects/ui_launchingscreen.h:282 +#: objects/ui_launchingscreen.h:284 +msgid "Examples" +msgstr "Příklady" + +#: objects/ui_MainWindow.h:858 +msgid "Export" +msgstr "" + +#: objects/ui_MainWindow.h:859 +msgid "&Edit" +msgstr "&Upravit" + +#: objects/ui_MainWindow.h:860 +msgid "&Design" +msgstr "&Design" + +#: objects/ui_MainWindow.h:861 +msgid "&View" +msgstr "&Zobrazit" + +#: objects/ui_MainWindow.h:862 +msgid "&Help" +msgstr "&Nápověda" + +#: objects/ui_MainWindow.h:865 +msgid "Find" +msgstr "" + +#: objects/ui_MainWindow.h:866 objects/ui_MainWindow.h:873 +msgid "Replace" +msgstr "" + +#: objects/ui_MainWindow.h:868 +msgid "Search string" +msgstr "" + +#: objects/ui_MainWindow.h:869 +msgid "<" +msgstr "" + +#: objects/ui_MainWindow.h:870 +msgid ">" +msgstr "" + +#: objects/ui_MainWindow.h:871 +msgid "Done" +msgstr "" + +#: objects/ui_MainWindow.h:872 +#, fuzzy +msgid "Replacement string" +msgstr "prvcích" + +#: objects/ui_MainWindow.h:874 +msgid "All" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +#, fuzzy +msgid "Enable OpenCSG" +msgstr "Povolit pro OpenGL 1.x" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + +#: objects/ui_Preferences.h:610 +msgid "3D View" +msgstr "3D zobrazení" + +#: objects/ui_Preferences.h:611 src/UIUtils.cc:85 +msgid "Advanced" +msgstr "Pokročilé" + +#: objects/ui_Preferences.h:612 src/mainwin.cc:2292 +msgid "Editor" +msgstr "Editor" + +#: objects/ui_Preferences.h:613 +msgid "Update" +msgstr "" + +#: objects/ui_Preferences.h:614 objects/ui_Preferences.h:661 +msgid "Features" +msgstr "" + +#: objects/ui_Preferences.h:616 +msgid "Enable/Disable experimental features" +msgstr "" + +#: objects/ui_Preferences.h:618 +msgid "Color scheme:" +msgstr "Barevné téma:" + +#: objects/ui_Preferences.h:623 +msgid "Cornfield" +msgstr "Kukuřice" + +#: objects/ui_Preferences.h:625 +msgid "Metallic" +msgstr "Kov" + +#: objects/ui_Preferences.h:627 +msgid "Sunset" +msgstr "Západ slunce" + +#: objects/ui_Preferences.h:629 +msgid "Starnight" +msgstr "" + +#: objects/ui_Preferences.h:631 +msgid "BeforeDawn" +msgstr "" + +#: objects/ui_Preferences.h:633 +msgid "Nature" +msgstr "" + +#: objects/ui_Preferences.h:635 +msgid "DeepOcean" +msgstr "" + +#: objects/ui_Preferences.h:638 +#, fuzzy +msgid "Editor Type" +msgstr "Editor" + +#: objects/ui_Preferences.h:641 +#, fuzzy +msgid "Simple Editor" +msgstr "Skrýt editor" + +#: objects/ui_Preferences.h:642 +msgid "QScintilla Editor" +msgstr "" + +#: objects/ui_Preferences.h:644 +msgid "(requires restart)" +msgstr "" + +#: objects/ui_Preferences.h:645 +msgid "Font" +msgstr "Písmo" + +#: objects/ui_Preferences.h:646 +msgid "Color syntax highlighting" +msgstr "" + +#: objects/ui_Preferences.h:649 +msgid "For Light Background" +msgstr "" + +#: objects/ui_Preferences.h:650 +msgid "For Dark Background" +msgstr "" + +#: objects/ui_Preferences.h:651 +msgid "Monokai" +msgstr "" + +#: objects/ui_Preferences.h:652 +msgid "Solarized" +msgstr "" + +#: objects/ui_Preferences.h:653 +msgid "Off" +msgstr "" + +#: objects/ui_Preferences.h:655 +msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" +msgstr "" + +#: objects/ui_Preferences.h:657 +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:658 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:659 +msgid "Check Now" +msgstr "" + +#: objects/ui_Preferences.h:660 +msgid "Last checked: " +msgstr "" + +#: objects/ui_Preferences.h:662 +msgid "OpenCSG" +msgstr "OpenCSG" + +#: objects/ui_Preferences.h:663 +msgid "Show capability warning" +msgstr "Zobrazovat varování o vlastnostech" + +#: objects/ui_Preferences.h:664 +msgid "Enable for OpenGL 1.x" +msgstr "Povolit pro OpenGL 1.x" + +#: objects/ui_Preferences.h:665 +msgid "Turn off rendering at " +msgstr "Vypnout renderování při" + +#: objects/ui_Preferences.h:666 +msgid "elements" +msgstr "prvcích" + +#: objects/ui_Preferences.h:667 +msgid "Force Goldfeather" +msgstr "Vynutit Goldfeathera" + +#: objects/ui_Preferences.h:668 +msgid "CGAL Cache size" +msgstr "Velikost CGAL cache" + +#: objects/ui_Preferences.h:669 objects/ui_Preferences.h:671 +msgid "bytes" +msgstr "bytů" + +#: objects/ui_Preferences.h:670 +msgid "PolySet Cache size" +msgstr "Velikost PolySet cache" + +#: objects/ui_Preferences.h:672 +msgid "Allow to open multiple documents" +msgstr "" + +#: objects/ui_Preferences.h:673 +msgid "Enable undocking of Editor and Console" +msgstr "" + +#: objects/ui_Preferences.h:674 +msgid "Show Welcome Screen" +msgstr "" + +#: objects/ui_Preferences.h:675 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" + +#: objects/ui_Preferences.h:676 +msgid "toolBar" +msgstr "" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "" + +#: objects/ui_launchingscreen.h:277 +#, fuzzy +msgid "New" +msgstr "&Nový" + +#: objects/ui_launchingscreen.h:278 +#, fuzzy +msgid "Open" +msgstr "OpenCSG" + +#: objects/ui_launchingscreen.h:279 +#, fuzzy +msgid "Help" +msgstr "&Nápověda" + +#: objects/ui_launchingscreen.h:280 +#, fuzzy +msgid "Recents" +msgstr "Nedávné soubory" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "Nedávné soubory" + +#: objects/ui_launchingscreen.h:285 +#, fuzzy +msgid "Open Example" +msgstr "Příklady" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "" + +#: src/AboutDialog.h:15 +#, fuzzy +msgid "About OpenSCAD " +msgstr "Manuál k OpenSCADu (anglicky)" + +#: src/QGLView.cc:114 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" + +#: src/QGLView.cc:131 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:134 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:137 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/QGLView.cc:141 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/QGLView.cc:171 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Basics" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Shapes" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Extrusion" +msgstr "" + +#: src/mainwin.cc:728 src/mainwin.cc:1269 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1268 +msgid "Save File" +msgstr "" + +#: src/mainwin.cc:1270 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1280 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1608 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1609 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1907 src/mainwin.cc:1964 +#, fuzzy +msgid "Export %1 File" +msgstr "Exportovat STL soubor" + +#: src/mainwin.cc:1908 src/mainwin.cc:1968 +msgid "%1 Files (*%2)" +msgstr "" + +#: src/mainwin.cc:1909 +msgid "Untitled" +msgstr "" + +#: src/mainwin.cc:1966 +msgid "Untitled%1" +msgstr "" + +#: src/mainwin.cc:2017 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:2018 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:2019 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:2045 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:2045 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:2297 +msgid "Console" +msgstr "Terminál" + +#: src/mainwin.cc:2420 +msgid "The document has been modified." +msgstr "" + +#: src/mainwin.cc:2421 +msgid "Do you want to save your changes?" +msgstr "" + +#~ msgid "&Compile" +#~ msgstr "Z&kompilovat" + +#~ msgid "Compile and &Render (CGAL)" +#~ msgstr "Zkompilovat a vy&renderovat" + +#~ msgid "CGAL Grid Only" +#~ msgstr "CGAL mřížka" + +#~ msgid "Editor for SCAD code" +#~ msgstr "Editor SCAD kódu" + +#~ msgid "OpenGL preview of SCAD model" +#~ msgstr "OpenGL náhled SCAD modelu" + +#~ msgid "Console messages" +#~ msgstr "Zprávy terminálu" + +#~ msgid " vertices:" +#~ msgstr "vrcholy:" + +#~ msgid "{ Outer boundary = " +#~ msgstr "{ Vnější hranice = " + +#~ msgid "{ Unbounded polygon." +#~ msgstr "{ Neohraničený polygon." + +#~ msgid " holes:" +#~ msgstr "díry:" + +#~ msgid " Hole #" +#~ msgstr " Díra #" + +#~ msgid "" +#~ "WARNING: minkowski() and hull() is not implemented for 2d objects with " +#~ "holes!" +#~ msgstr "" +#~ "VAROVÁNÍ: minkowski() a hull() nejsou implementovány pro 2D objekty s " +#~ "dírami" + +#~ msgid "WARNING: minkowski() could not get any points from object 1!" +#~ msgstr "VAROVÁNÍ: minkowski() nenalezl žádné body v objektu 1!" + +#~ msgid "WARNING: minkowski() could not get any points from object 2!" +#~ msgstr "VAROVÁNÍ: minkowski() nenalezl žádné body v objektu 2!" + +#~ msgid "CGAL error in CGAL_Nef_polyhedron's %s operator: %s" +#~ msgstr "CGAL chyba v CGAL_Nef_polyhedron operátoru %s: %s" + +#~ msgid "WARNING: hull() does not support mixing 2D and 3D objects." +#~ msgstr "VAROVÁNÍ: hull() neumožňuje kombinovat 2D a 3D objekty." + +#~ msgid "" +#~ "Hull() currently requires a valid 2-manifold. Please modify your design. " +#~ "See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/" +#~ "STL_Import_and_Export" +#~ msgstr "" +#~ "Hull() nyní podporuje jen validní 2-manifold objekty. Upravte svůj " +#~ "design. Viz http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/" +#~ "STL_Import_and_Export" + +#~ msgid "Rendering cancelled." +#~ msgstr "Renderování zrušeno." + +#~ msgid "" +#~ "DEPRECATED: The %s() module will be removed in future releases. Use %s() " +#~ "instead." +#~ msgstr "" +#~ "ZASTARALÉ: Zápis %s() bude v dalších verzích odstraněn. Místo něj " +#~ "použijte %s()." + +#~ msgid "OpenSCAD - New Document[*]" +#~ msgstr "OpenSCAD - Nový dokument[*]" + +#~ msgid "Failed to open file %s: %s" +#~ msgstr "Nepodařilo se otevřít soubor %s: %s" + +#~ msgid "Loaded design '%s'." +#~ msgstr "Načten design '%s'." + +#~ msgid "ERROR: Compilation failed! (no top level object found)" +#~ msgstr "CHYBA: Kompilace selhala! (nenalezen hlavní objekt)" + +#~ msgid "ERROR: Compilation failed!" +#~ msgstr "CHYBA: Kompilace selhala!" + +#~ msgid "yes" +#~ msgstr "ano" + +#~ msgid "no" +#~ msgstr "ne" + +#~ msgid " Vertices: %6d" +#~ msgstr " Vrcholů: %6d" + +#~ msgid " Halfedges: %6d" +#~ msgstr " Půlhran: %6d" + +#~ msgid " Edges: %6d" +#~ msgstr " Hran: %6d" + +#~ msgid " Faces: %6d" +#~ msgstr " Trojúhelníků: %6d" + +#~ msgid " Simple: %6s" +#~ msgstr " Jednoduchý: %6s" + +#~ msgid " Valid: %6s" +#~ msgstr " Validní: %6s" + +#~ msgid " Facets: %6d" +#~ msgstr " Stěn: %6d" + +#~ msgid " Volumes: %6d" +#~ msgstr " Objemů: %6d" + +#~ msgid "Rendering finished." +#~ msgstr "Renderování dokončeno." + +#~ msgid "Export OFF File" +#~ msgstr "Exportovat OFF soubor" From 1974cf863bca926c02338b6297410b6a4e1aa1f7 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 21 Oct 2014 00:02:53 +0200 Subject: [PATCH 030/263] Update German translation, incorporating comments from #988. --- po/de.po | 75 +- po/openscad.pot | 2742 ++++++++++++++++------------------------------- 2 files changed, 933 insertions(+), 1884 deletions(-) diff --git a/po/de.po b/po/de.po index b6d3d9dc..96014e73 100644 --- a/po/de.po +++ b/po/de.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-10-19 00:48+0200\n" -"PO-Revision-Date: 2014-10-19 00:48+0100\n" +"PO-Revision-Date: 2014-10-21 00:00+0100\n" "Last-Translator: Torsten Paul \n" "Language-Team: German\n" "Language: de\n" @@ -54,8 +54,8 @@ msgid "" "family:'Courier New,courier';\"> text(t = "OpenSCAD", font = " ""Liberation Sans:style=Italic");" msgstr "" -"

This list shows the fonts currently registered with " -"OpenSCAD.

Example:

Diese Liste zeigt die Fonts, die momentan mit OpenSCAD " +"registriert sind.

Beispiele:

  text(t = "
 ""OpenSCAD", font = "DejaVu Sans");
\n"
 "Language-Team: LANGUAGE \n"
@@ -17,1884 +17,888 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: objects/ui_MainWindow.h:470
-msgid "MainWindow"
+#: objects/ui_AboutDialog.h:51
+msgid "About OpenSCAD"
 msgstr ""
 
-#: objects/ui_MainWindow.h:471
-msgid "&New"
+#: objects/ui_FontListDialog.h:102
+msgid "OpenSCAD Font List"
 msgstr ""
 
-#: objects/ui_MainWindow.h:472
-msgid "Ctrl+N"
+#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77
+msgid "&OK"
 msgstr ""
 
-#: objects/ui_MainWindow.h:473
-msgid "&Open..."
+#: objects/ui_FontListDialog.h:105
+msgid "Paste font selector to Editor Window"
 msgstr ""
 
-#: objects/ui_MainWindow.h:474
-msgid "Ctrl+O"
+#: objects/ui_FontListDialog.h:107
+msgid "Copy to Clipboard"
 msgstr ""
 
-#: objects/ui_MainWindow.h:475
-msgid "&Save"
+#: objects/ui_FontListDialog.h:108
+msgid "Filter:"
 msgstr ""
 
-#: objects/ui_MainWindow.h:476
-msgid "Ctrl+S"
-msgstr ""
-
-#: objects/ui_MainWindow.h:477
-msgid "Save &As..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:478
-msgid "Ctrl+Shift+S"
-msgstr ""
-
-#: objects/ui_MainWindow.h:479
-msgid "&Reload"
-msgstr ""
-
-#: objects/ui_MainWindow.h:480
-msgid "Ctrl+R"
-msgstr ""
-
-#: objects/ui_MainWindow.h:481
-msgid "&Quit"
-msgstr ""
-
-#: objects/ui_MainWindow.h:482
-msgid "Ctrl+Q"
-msgstr ""
-
-#: objects/ui_MainWindow.h:483
-msgid "&Undo"
-msgstr ""
-
-#: objects/ui_MainWindow.h:484
-msgid "Ctrl+Z"
-msgstr ""
-
-#: objects/ui_MainWindow.h:485
-msgid "&Redo"
-msgstr ""
-
-#: objects/ui_MainWindow.h:486
-msgid "Ctrl+Shift+Z"
-msgstr ""
-
-#: objects/ui_MainWindow.h:487
-msgid "Cu&t"
-msgstr ""
-
-#: objects/ui_MainWindow.h:488
-msgid "Ctrl+X"
-msgstr ""
-
-#: objects/ui_MainWindow.h:489
-msgid "&Copy"
-msgstr ""
-
-#: objects/ui_MainWindow.h:490
-msgid "Ctrl+C"
-msgstr ""
-
-#: objects/ui_MainWindow.h:491
-msgid "&Paste"
-msgstr ""
-
-#: objects/ui_MainWindow.h:492
-msgid "Ctrl+V"
-msgstr ""
-
-#: objects/ui_MainWindow.h:493
-msgid "&Indent"
-msgstr ""
-
-#: objects/ui_MainWindow.h:494
-msgid "Ctrl+I"
-msgstr ""
-
-#: objects/ui_MainWindow.h:495
-msgid "U&nindent"
-msgstr ""
-
-#: objects/ui_MainWindow.h:496
-msgid "Ctrl+Shift+I"
-msgstr ""
-
-#: objects/ui_MainWindow.h:497
-msgid "C&omment"
-msgstr ""
-
-#: objects/ui_MainWindow.h:498
-msgid "Ctrl+D"
-msgstr ""
-
-#: objects/ui_MainWindow.h:499
-msgid "Unco&mment"
-msgstr ""
-
-#: objects/ui_MainWindow.h:500
-msgid "Ctrl+Shift+D"
-msgstr ""
-
-#: objects/ui_MainWindow.h:501
-msgid "Paste viewport translation"
-msgstr ""
-
-#: objects/ui_MainWindow.h:502
-msgid "Ctrl+T"
-msgstr ""
-
-#: objects/ui_MainWindow.h:503
-msgid "Paste viewport rotation"
-msgstr ""
-
-#: objects/ui_MainWindow.h:504
-msgid "Zoom In"
-msgstr ""
-
-#: objects/ui_MainWindow.h:505
-msgid "Ctrl++"
-msgstr ""
-
-#: objects/ui_MainWindow.h:506
-msgid "Zoom Out"
-msgstr ""
-
-#: objects/ui_MainWindow.h:507
-msgid "Ctrl+-"
-msgstr ""
-
-#: objects/ui_MainWindow.h:508
-msgid "Hide editor"
-msgstr ""
-
-#: objects/ui_MainWindow.h:509
-msgid "&Reload and Preview"
-msgstr ""
-
-#: objects/ui_MainWindow.h:510
-msgid "F4"
-msgstr ""
-
-#: objects/ui_MainWindow.h:511
-msgid "&Preview"
-msgstr ""
-
-#: objects/ui_MainWindow.h:512
-msgid "F5"
-msgstr ""
-
-#: objects/ui_MainWindow.h:513
-msgid "&Render"
-msgstr ""
-
-#: objects/ui_MainWindow.h:514
-msgid "F6"
-msgstr ""
-
-#: objects/ui_MainWindow.h:515
-msgid "Display &AST..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:516
-msgid "Display CSG &Tree..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:517
-msgid "Display CSG &Products..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:518
-msgid "Export as &STL..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:519
-msgid "Export as &OFF..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:520
-msgid "Preview"
-msgstr ""
-
-#: objects/ui_MainWindow.h:521
-msgid "F9"
-msgstr ""
-
-#: objects/ui_MainWindow.h:522
-msgid "Surfaces"
-msgstr ""
-
-#: objects/ui_MainWindow.h:523
-msgid "F10"
-msgstr ""
-
-#: objects/ui_MainWindow.h:524
-msgid "Wireframe"
-msgstr ""
-
-#: objects/ui_MainWindow.h:525
-msgid "F11"
-msgstr ""
-
-#: objects/ui_MainWindow.h:526
-msgid "Thrown Together"
-msgstr ""
-
-#: objects/ui_MainWindow.h:527
-msgid "F12"
-msgstr ""
-
-#: objects/ui_MainWindow.h:528
-msgid "Show Edges"
-msgstr ""
-
-#: objects/ui_MainWindow.h:529
-msgid "Ctrl+1"
-msgstr ""
-
-#: objects/ui_MainWindow.h:530
-msgid "Show Axes"
-msgstr ""
-
-#: objects/ui_MainWindow.h:531
-msgid "Ctrl+2"
-msgstr ""
-
-#: objects/ui_MainWindow.h:532
-msgid "Show Crosshairs"
-msgstr ""
-
-#: objects/ui_MainWindow.h:533
-msgid "Ctrl+3"
-msgstr ""
-
-#: objects/ui_MainWindow.h:534
-msgid "Animate"
-msgstr ""
-
-#: objects/ui_MainWindow.h:535
-msgid "Top"
-msgstr ""
-
-#: objects/ui_MainWindow.h:536
-msgid "Ctrl+4"
-msgstr ""
-
-#: objects/ui_MainWindow.h:537
-msgid "Bottom"
-msgstr ""
-
-#: objects/ui_MainWindow.h:538
-msgid "Ctrl+5"
-msgstr ""
-
-#: objects/ui_MainWindow.h:539
-msgid "Left"
-msgstr ""
-
-#: objects/ui_MainWindow.h:540
-msgid "Ctrl+6"
-msgstr ""
-
-#: objects/ui_MainWindow.h:541
-msgid "Right"
-msgstr ""
-
-#: objects/ui_MainWindow.h:542
-msgid "Ctrl+7"
-msgstr ""
-
-#: objects/ui_MainWindow.h:543
-msgid "Front"
-msgstr ""
-
-#: objects/ui_MainWindow.h:544
-msgid "Ctrl+8"
-msgstr ""
-
-#: objects/ui_MainWindow.h:545
-msgid "Back"
-msgstr ""
-
-#: objects/ui_MainWindow.h:546
-msgid "Ctrl+9"
-msgstr ""
-
-#: objects/ui_MainWindow.h:547
-msgid "Diagonal"
-msgstr ""
-
-#: objects/ui_MainWindow.h:548
-msgid "Ctrl+0"
-msgstr ""
-
-#: objects/ui_MainWindow.h:549
-msgid "Center"
-msgstr ""
-
-#: objects/ui_MainWindow.h:550
-msgid "Ctrl+P"
-msgstr ""
-
-#: objects/ui_MainWindow.h:551
-msgid "Perspective"
-msgstr ""
-
-#: objects/ui_MainWindow.h:552
-msgid "Orthogonal"
-msgstr ""
-
-#: objects/ui_MainWindow.h:553
-msgid "Hide console"
-msgstr ""
-
-#: objects/ui_MainWindow.h:554
-msgid "About"
-msgstr ""
-
-#: objects/ui_MainWindow.h:555
-msgid "Documentation"
-msgstr ""
-
-#: objects/ui_MainWindow.h:556
-msgid "Clear Recent"
-msgstr ""
-
-#: objects/ui_MainWindow.h:557
-msgid "Export as DXF..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:558
-msgid "Close"
-msgstr ""
-
-#: objects/ui_MainWindow.h:559
-msgid "Ctrl+W"
-msgstr ""
-
-#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:517
-msgid "Preferences"
-msgstr ""
-
-#: objects/ui_MainWindow.h:561
-msgid "Flush Caches"
-msgstr ""
-
-#: objects/ui_MainWindow.h:562
-msgid "OpenSCAD Homepage"
-msgstr ""
-
-#: objects/ui_MainWindow.h:563
-msgid "Automatic Reload and Preview"
-msgstr ""
-
-#: objects/ui_MainWindow.h:564
-msgid "Export as Image..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:565
-msgid "Export as CSG..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:566
-msgid "Library info"
-msgstr ""
-
-#: objects/ui_MainWindow.h:567
-msgid "Check for Update.."
-msgstr ""
-
-#: objects/ui_MainWindow.h:568
-msgid "Show Library Folder..."
-msgstr ""
-
-#: objects/ui_MainWindow.h:569
-msgid "Reset View"
-msgstr ""
-
-#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:520
-msgid "Editor"
-msgstr ""
-
-#: objects/ui_MainWindow.h:574
-msgid "Editor for SCAD code"
-msgstr ""
-
-#: objects/ui_MainWindow.h:577
-msgid "Console"
-msgstr ""
-
-#: objects/ui_MainWindow.h:580
-msgid "Console messages"
-msgstr ""
-
-#: objects/ui_MainWindow.h:582
-msgid "Time:"
-msgstr ""
-
-#: objects/ui_MainWindow.h:583
-msgid "FPS:"
-msgstr ""
-
-#: objects/ui_MainWindow.h:584
-msgid "Steps:"
-msgstr ""
-
-#: objects/ui_MainWindow.h:585
-msgid "Dump Pictures"
-msgstr ""
-
-#: objects/ui_MainWindow.h:586
-msgid "&File"
-msgstr ""
-
-#: objects/ui_MainWindow.h:587
-msgid "Open Recent"
-msgstr ""
-
-#: objects/ui_MainWindow.h:588
-msgid "Examples"
-msgstr ""
-
-#: objects/ui_MainWindow.h:589
-msgid "&Edit"
-msgstr ""
-
-#: objects/ui_MainWindow.h:590
-msgid "&Design"
-msgstr ""
-
-#: objects/ui_MainWindow.h:591
-msgid "&View"
-msgstr ""
-
-#: objects/ui_MainWindow.h:592
-msgid "&Help"
-msgstr ""
-
-#: objects/ui_Preferences.h:518
-msgid "3D View"
-msgstr ""
-
-#: objects/ui_Preferences.h:519
-msgid "Advanced"
-msgstr ""
-
-#: objects/ui_Preferences.h:521
-msgid "Update"
-msgstr ""
-
-#: objects/ui_Preferences.h:522 objects/ui_Preferences.h:550
-msgid "Features"
-msgstr ""
-
-#: objects/ui_Preferences.h:524
-msgid "Enable/Disable experimental features"
-msgstr ""
-
-#: objects/ui_Preferences.h:526
-msgid "Color scheme:"
-msgstr ""
-
-#: objects/ui_Preferences.h:531
-msgid "Cornfield"
-msgstr ""
-
-#: objects/ui_Preferences.h:533
-msgid "Metallic"
-msgstr ""
-
-#: objects/ui_Preferences.h:535
-msgid "Sunset"
-msgstr ""
-
-#: objects/ui_Preferences.h:538
-msgid "Font"
-msgstr ""
-
-#: objects/ui_Preferences.h:539
-msgid "Color syntax highlighting"
-msgstr ""
-
-#: objects/ui_Preferences.h:542
-msgid "Off"
-msgstr ""
-
-#: objects/ui_Preferences.h:543
-msgid "For Light Background"
-msgstr ""
-
-#: objects/ui_Preferences.h:544
-msgid "For Dark Background"
-msgstr ""
-
-#: objects/ui_Preferences.h:546
-msgid "Automatically check for updates"
-msgstr ""
-
-#: objects/ui_Preferences.h:547
-msgid "Include development snapshots"
-msgstr ""
-
-#: objects/ui_Preferences.h:548
-msgid "Check Now"
-msgstr ""
-
-#: objects/ui_Preferences.h:549
-msgid "Last checked: "
-msgstr ""
-
-#: objects/ui_Preferences.h:551
-msgid "OpenCSG"
-msgstr ""
-
-#: objects/ui_Preferences.h:552
-msgid "Show capability warning"
-msgstr ""
-
-#: objects/ui_Preferences.h:553
-msgid "Enable for OpenGL 1.x"
-msgstr ""
-
-#: objects/ui_Preferences.h:554
-msgid "Turn off rendering at "
-msgstr ""
-
-#: objects/ui_Preferences.h:555
-msgid "elements"
-msgstr ""
-
-#: objects/ui_Preferences.h:556
-msgid "Force Goldfeather"
-msgstr ""
-
-#: objects/ui_Preferences.h:557
-msgid "CGAL Cache size"
-msgstr ""
-
-#: objects/ui_Preferences.h:558 objects/ui_Preferences.h:560
-msgid "bytes"
-msgstr ""
-
-#: objects/ui_Preferences.h:559
-msgid "PolySet Cache size"
-msgstr ""
-
-#: objects/ui_Preferences.h:561
-msgid "Enable user interface localization (requires restart of OpenSCAD)"
-msgstr ""
-
-#: objects/ui_Preferences.h:562
-msgid "toolBar"
-msgstr ""
-
-#: src/AboutDialog.h:16
-msgid "About OpenSCAD "
-msgstr ""
-
-#: src/cache.h:181
-msgid "Trimming cache: %1% (%2% bytes)"
-msgstr ""
-
-#: src/CGAL_Nef3_workaround.h:256
-#, c-format
-msgid "WARNING: CGAL NefPolyhedron Triangulation failed: %s"
-msgstr ""
-
-#: src/CsgInfo.h:48
-msgid "Error: CSG generation failed! (no top level object found)"
-msgstr ""
-
-#: src/CsgInfo.h:53 src/mainwin.cc:818
-msgid "Compiling design (CSG Products normalization)..."
-msgstr ""
-
-#: src/CsgInfo.h:60 src/mainwin.cc:865
-#, c-format
-msgid "Normalized CSG tree has %d elements"
-msgstr ""
-
-#: src/CsgInfo.h:64 src/mainwin.cc:830
-msgid "WARNING: CSG normalization resulted in an empty tree"
-msgstr ""
-
-#: src/CsgInfo.h:69
-#, c-format
-msgid "Compiling highlights (%i CSG Trees)..."
-msgstr ""
-
-#: src/CsgInfo.h:79
-#, c-format
-msgid "Compiling background (%i CSG Trees)..."
-msgstr ""
-
-#: src/CGALCache.cc:15
-#, c-format
-msgid "CGAL Cache hit: %s (%d bytes)"
-msgstr ""
-
-#: src/CGALCache.cc:24
-#, c-format
-msgid "CGAL Cache insert: %s (%d bytes)"
-msgstr ""
-
-#: src/CGALCache.cc:25
-#, c-format
-msgid "CGAL Cache insert failed: %s (%d bytes)"
-msgstr ""
-
-#: src/CGALCache.cc:47
-#, c-format
-msgid "CGAL Polyhedrons in cache: %d"
-msgstr ""
-
-#: src/CGALCache.cc:48
-#, c-format
-msgid "CGAL cache size in bytes: %d"
-msgstr ""
-
-#: src/CGAL_Nef_polyhedron.cc:74 src/cgalutils.cc:44
-msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed."
-msgstr ""
-
-#: src/CGAL_Nef_polyhedron.cc:75 src/cgalutils.cc:45 src/PlatformUtils.cc:19
-#, c-format
-msgid "ERROR: %s"
-msgstr ""
-
-#: src/CGAL_Nef_polyhedron_DxfData.cc:49
-msgid "Warning: Scaling a 3D object with 0 - removing object"
-msgstr ""
-
-#: src/cgalutils.cc:30
+#: objects/ui_FontListDialog.h:109
 msgid ""
-"Hull() currently requires a valid 2-manifold. Please modify your design. See "
-"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export"
+"

This list shows the fonts currently registered with " +"OpenSCAD.

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" msgstr "" -#: src/cgalutils.cc:107 -#, c-format -msgid "ERROR: Unsupported CGAL operator: %d" +#: objects/ui_LibraryInfoDialog.h:75 +msgid "Lib & Build Info" msgstr "" -#: src/cgalutils.cc:113 -#, c-format -msgid "CGAL error in CGALUtils::applyBinaryOperator %s: %s" -msgstr "" - -#: src/cgalutils.cc:159 -#, c-format -msgid "CGALUtils::project during plane intersection: %s" -msgstr "" - -#: src/cgalutils.cc:161 -msgid "Trying alternative intersection using very large thin box: " -msgstr "" - -#: src/cgalutils.cc:176 -#, c-format -msgid "CGAL error in CGALUtils::project during bigbox intersection: %s" -msgstr "" - -#: src/cgalutils.cc:182 -msgid "WARNING: projection() failed." -msgstr "" - -#: src/cgalutils.cc:204 -#, c-format -msgid "CGAL error in CGALUtils::project while flattening: %s" -msgstr "" - -#: src/cgalutils.cc:496 -msgid "ERROR: deproject failure" -msgstr "" - -#: src/cgalutils.cc:582 -msgid "ERROR: failed to find projection" -msgstr "" - -#: src/cgalutils.cc:593 -msgid "input polygon has 3 points. shortcut tessellation." -msgstr "" - -#: src/cgalutils.cc:605 -msgid "finding good projection" -msgstr "" - -#: src/cgalutils.cc:608 -#, c-format -msgid "plane %s" -msgstr "" - -#: src/cgalutils.cc:609 -#, c-format -msgid "proj: %i %i" -msgstr "" - -#: src/cgalutils.cc:610 -msgid "Inserting points and edges into Constrained Delaunay Triangulation" -msgstr "" - -#: src/cgalutils.cc:632 -#, c-format -msgid "WARNING: Constraint insertion failure %s" -msgstr "" - -#: src/cgalutils.cc:639 -#, c-format -msgid "seeding %i holes" -msgstr "" - -#: src/cgalutils.cc:660 -#, c-format -msgid "seed %f,%f" -msgstr "" - -#: src/cgalutils.cc:662 -msgid "seeding done" -msgstr "" - -#: src/cgalutils.cc:664 -msgid "meshing" -msgstr "" - -#: src/cgalutils.cc:669 -msgid "meshing done" -msgstr "" - -#: src/cgalutils.cc:690 -msgid "WARNING: 2d->3d deprojection failure" -msgstr "" - -#: src/cgalutils.cc:698 -#, c-format -msgid "built %i triangles\n" -msgstr "" - -#: src/cgalutils.cc:741 -msgid "WARNING: triangle doesn't have 3 points. skipping" -msgstr "" - -#: src/cgalutils.cc:941 -#, c-format -msgid "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" -msgstr "" - -#: src/cgalutils.cc:1021 -msgid "PolySet has nonplanar faces. Attempting alternate construction" -msgstr "" - -#: src/cgalutils.cc:1025 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "" - -#: src/cgalutils.cc:1036 -#, c-format -msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "" - -#: src/cgalworker.cc:36 -msgid "Rendering cancelled." -msgstr "" - -#: src/color.cc:69 -#, c-format -msgid "" -"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " -"large." -msgstr "" - -#: src/color.cc:81 -#, c-format -msgid "WARNING: Color name \"%s\" unknown. Please see" -msgstr "" - -#: src/color.cc:82 -msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" -msgstr "" - -#: src/context.cc:97 -#, c-format -msgid "WARNING: Attempt to modify constant '%s'." -msgstr "" - -#: src/context.cc:121 -#, c-format -msgid "WARNING: Ignoring unknown variable '%s'." -msgstr "" - -#: src/context.cc:128 -#, c-format -msgid "WARNING: Ignoring unknown function '%s'." -msgstr "" - -#: src/context.cc:135 -#, c-format -msgid "WARNING: Ignoring unknown module '%s'." -msgstr "" - -#: src/context.cc:156 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p)" -msgstr "" - -#: src/context.cc:158 src/evalcontext.cc:40 -#, c-format -msgid "Context: %p (%p)" -msgstr "" - -#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 -#, c-format -msgid " document path: %s" -msgstr "" - -#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 -msgid " module args:" -msgstr "" - -#: src/context.cc:170 src/modcontext.cc:159 -msgid " vars:" -msgstr "" - -#: src/control.cc:83 -#, c-format -msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." -msgstr "" - -#: src/control.cc:133 src/control.cc:138 src/control.cc:247 -#, c-format -msgid "" -"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " -"vector, range." -msgstr "" - -#: src/control.cc:144 -#, c-format -msgid "WARNING: Negative children index (%d) not allowed" -msgstr "" - -#: src/control.cc:150 -#, c-format -msgid "WARNING: Children index (%d) out of bounds (%d children)" -msgstr "" - -#: src/control.cc:170 -#, c-format -msgid "WARNING: Negative child index (%d) not allowed" -msgstr "" - -#: src/control.cc:189 -#, c-format -msgid "WARNING: Child index (%d) out of bounds (%d children)" -msgstr "" - -#: src/control.cc:234 -#, c-format -msgid "WARNING: Bad range parameter for children: too many elements (%lu)." -msgstr "" - -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 -#, c-format -msgid "" -"WARNING: Normalized tree is growing past %d elements. Aborting " -"normalization.\n" -msgstr "" - -#: src/dxfdata.cc:84 -#, c-format -msgid "WARNING: Can't open DXF file '%s'." -msgstr "" - -#: src/dxfdata.cc:148 -#, c-format -msgid "WARNING: Illegal ID '%s' in `%s'" -msgstr "" - -#: src/dxfdata.cc:387 -#, c-format -msgid "WARNING: Illegal value %s in '%s'" -msgstr "" - -#: src/dxfdata.cc:393 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." -msgstr "" - -#: src/dxfdata.cc:396 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." -msgstr "" - -#: src/dxfdim.cc:131 -#, c-format -msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" -msgstr "" - -#: src/dxfdim.cc:136 -#, c-format -msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" -msgstr "" - -#: src/dxfdim.cc:211 -#, c-format -msgid "WARNING: Can't find cross in '%s', layer '%s'!" -msgstr "" - -#: src/evalcontext.cc:38 -#, c-format -msgid "EvalContext %p (%p) for %s inst (%p)" -msgstr "" - -#: src/evalcontext.cc:43 -msgid " eval args:" -msgstr "" - -#: src/evalcontext.cc:48 -msgid " children:" -msgstr "" - -#: src/export.cc:180 src/export.cc:225 -msgid "Object isn't a valid 2-manifold! Modify your design.\n" -msgstr "" - -#: src/export.cc:187 -msgid "ERROR: Nef->PolySet failed" -msgstr "" - -#: src/export.cc:199 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" -msgstr "" - -#: src/export.cc:205 src/export.cc:234 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" -msgstr "" - -#: src/export.cc:208 -msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" -msgstr "" - -#: src/expr.cc:166 -#, c-format -msgid "ERROR: Recursion detected calling function '%s'" -msgstr "" - -#: src/feature.cc:21 -msgid "Enable the concat() function." -msgstr "" - -#: src/feature.cc:60 -#, c-format -msgid "WARNING: Ignoring request to enable unknown feature '%s'." -msgstr "" - -#: src/fileutils.cc:25 -#, c-format -msgid "" -"WARNING: Imported file (%s) found in document root instead of relative to " -"the importing module. This behavior is deprecated" -msgstr "" - -#: src/func.cc:503 src/func.cc:536 -#, c-format -msgid " WARNING: search term not found: \"%s\"" -msgstr "" - -#: src/func.cc:533 -#, c-format -msgid " WARNING: search term not found: %s" -msgstr "" - -#: src/func.cc:545 -#, c-format -msgid " WARNING: search: none performed on input %s" -msgstr "" - -#: src/func.cc:591 -#, c-format -msgid "WARNING: Negative parent module index (%d) not allowed" -msgstr "" - -#: src/func.cc:595 -#, c-format -msgid "" -"WARNING: Parent module index (%d) greater than the number of modules on the " -"stack" -msgstr "" - -#: src/GeometryCache.cc:14 -#, c-format -msgid "Geometry Cache hit: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:24 -#, c-format -msgid "Geometry Cache insert: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:26 -#, c-format -msgid "Geometry Cache insert failed: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:44 -#, c-format -msgid "Geometries in cache: %d" -msgstr "" - -#: src/GeometryCache.cc:45 -#, c-format -msgid "Geometry cache size in bytes: %d" -msgstr "" - -#: src/GeometryEvaluator.cc:76 -msgid "WARNING: Mixing 2D and 3D objects is not supported." -msgstr "" - -#: src/GeometryEvaluator.cc:188 -msgid "WARNING: Resize in direction normal to flat object is not implemented" -msgstr "" - -#: src/GeometryEvaluator.cc:252 -msgid "WARNING: Ignoring 3D child object for 2D operation" -msgstr "" - -#: src/GeometryEvaluator.cc:276 -msgid "WARNING: GeometryEvaluator: Node didn't fit into cache" -msgstr "" - -#: src/GeometryEvaluator.cc:324 -msgid "WARNING: Ignoring 2D child object for 3D operation" -msgstr "" - -#: src/GeometryEvaluator.cc:365 -#, c-format -msgid "Error: Unknown boolean operation %d" -msgstr "" - -#: src/GeometryEvaluator.cc:517 -msgid "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." -msgstr "" - -#: src/GeometryEvaluator.cc:765 -#, c-format -msgid "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" -msgstr "" - -#: src/handle_dep.cc:36 -#, c-format -msgid "Can't open dependencies file `%s' for writing!\n" -msgstr "" - -#: src/import.cc:98 -msgid "DEPRECATED: filename= is deprecated. Please use file=" -msgstr "" - -#: src/import.cc:122 -msgid "DEPRECATED: layername= is deprecated. Please use layer=" -msgstr "" - -#: src/import.cc:201 src/import.cc:286 -#, c-format -msgid "WARNING: Can't open import file '%s'." -msgstr "" - -#: src/import.cc:251 -#, c-format -msgid "WARNING: Can't parse vertex line '%s'." -msgstr "" - -#: src/import.cc:295 -msgid "WARNING: OFF import requires CGAL." -msgstr "" - -#: src/import.cc:305 -#, c-format -msgid "ERROR: Unsupported file format while trying to import file '%s'" -msgstr "" - -#: src/linearextrude.cc:77 -msgid "" -"DEPRECATED: Support for reading files in linear_extrude will be removed in " -"future releases. Use a child import() instead." -msgstr "" - -#: src/mainwin.cc:118 -msgid "" -"Copyright (C) 2009-2013 The OpenSCAD Developers\n" -"\n" -"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." -msgstr "" - -#: src/mainwin.cc:523 -msgid "OpenSCAD - New Document[*]" -msgstr "" - -#: src/mainwin.cc:527 -msgid "OpenSCAD - " -msgstr "" - -#: src/mainwin.cc:527 -msgid "[*]" -msgstr "" - -#: src/mainwin.cc:601 -#, c-format -msgid "Failed to open file %s: %s" -msgstr "" - -#: src/mainwin.cc:608 -#, c-format -msgid "Loaded design '%s'." -msgstr "" - -#: src/mainwin.cc:655 -#, c-format -msgid "Module cache size: %d modules" -msgstr "" - -#: src/mainwin.cc:739 -msgid "Compiling design (CSG Tree generation)..." -msgstr "" - -#: src/mainwin.cc:765 -msgid "ERROR: Compilation failed! (no top level object found)" -msgstr "" - -#: src/mainwin.cc:767 -msgid "ERROR: Compilation failed!" -msgstr "" - -#: src/mainwin.cc:780 -msgid "Compiling design (CSG Products generation)..." -msgstr "" - -#: src/mainwin.cc:801 -msgid "ERROR: CSG generation failed! (no top level object found)" -msgstr "" - -#: src/mainwin.cc:810 -msgid "CSG generation cancelled." -msgstr "" - -#: src/mainwin.cc:836 -#, c-format -msgid "Compiling highlights (%d CSG Trees)..." -msgstr "" - -#: src/mainwin.cc:848 -#, c-format -msgid "Compiling background (%d CSG Trees)..." -msgstr "" - -#: src/mainwin.cc:861 -#, c-format -msgid "WARNING: Normalized tree has %d elements!" -msgstr "" - -#: src/mainwin.cc:862 -msgid "WARNING: OpenCSG rendering has been disabled." -msgstr "" - -#: src/mainwin.cc:875 -msgid "CSG generation finished." -msgstr "" - -#: src/mainwin.cc:877 src/mainwin.cc:1315 -#, c-format -msgid "Total rendering time: %d hours, %d minutes, %d seconds" -msgstr "" - -#: src/mainwin.cc:904 -msgid "Open File" -msgstr "" - -#: src/mainwin.cc:905 -msgid "OpenSCAD Designs (*.scad *.csg)" -msgstr "" - -#: src/mainwin.cc:999 -#, c-format -msgid "Failed to open file for writing: %s (%s)" -msgstr "" - -#: src/mainwin.cc:1000 -msgid "" -"Failed to open file for writing:\n" -" %1 (%2)" -msgstr "" - -#: src/mainwin.cc:1007 -#, c-format -msgid "Saved design '%s'." -msgstr "" - -#: src/mainwin.cc:1017 -msgid "Save File" -msgstr "" - -#: src/mainwin.cc:1018 -msgid "Untitled.scad" -msgstr "" - -#: src/mainwin.cc:1019 -msgid "OpenSCAD Designs (*.scad)" -msgstr "" - -#: src/mainwin.cc:1029 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" - -#: src/mainwin.cc:1044 -#, c-format -msgid "WARNING: Library path %s doesn't exist. Creating" -msgstr "" - -#: src/mainwin.cc:1046 -#, c-format -msgid "ERROR: Cannot create library path: %s" -msgstr "" - -#: src/mainwin.cc:1181 src/mainwin.cc:1846 -msgid "Application" -msgstr "" - -#: src/mainwin.cc:1182 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" - -#: src/mainwin.cc:1232 src/mainwin.cc:1276 -msgid "Parsing design (AST generation)..." -msgstr "" - -#: src/mainwin.cc:1260 -#, c-format -msgid "frame%05d.png" -msgstr "" - -#: src/mainwin.cc:1294 -msgid "Rendering Polygon Mesh using CGAL..." -msgstr "" - -#: src/mainwin.cc:1320 src/mainwin.cc:1334 -msgid " Top level object is a 3D object:" -msgstr "" - -#: src/mainwin.cc:1321 -#, c-format -msgid " Simple: %6s" -msgstr "" - -#: src/mainwin.cc:1321 src/mainwin.cc:1322 -msgid "yes" -msgstr "" - -#: src/mainwin.cc:1321 src/mainwin.cc:1322 -msgid "no" -msgstr "" - -#: src/mainwin.cc:1322 -#, c-format -msgid " Valid: %6s" -msgstr "" - -#: src/mainwin.cc:1323 -#, c-format -msgid " Vertices: %6d" -msgstr "" - -#: src/mainwin.cc:1324 -#, c-format -msgid " Halfedges: %6d" -msgstr "" - -#: src/mainwin.cc:1325 -#, c-format -msgid " Edges: %6d" -msgstr "" - -#: src/mainwin.cc:1326 -#, c-format -msgid " Halffacets: %6d" -msgstr "" - -#: src/mainwin.cc:1327 src/mainwin.cc:1335 -#, c-format -msgid " Facets: %6d" -msgstr "" - -#: src/mainwin.cc:1328 -#, c-format -msgid " Volumes: %6d" -msgstr "" - -#: src/mainwin.cc:1337 -msgid " Top level object is a 2D object:" -msgstr "" - -#: src/mainwin.cc:1338 -#, c-format -msgid " Contours: %6d" -msgstr "" - -#: src/mainwin.cc:1340 -msgid "Unknown geometry type" -msgstr "" - -#: src/mainwin.cc:1342 -msgid "Rendering finished." -msgstr "" - -#: src/mainwin.cc:1351 -msgid "WARNING: No top level geometry to render" -msgstr "" - -#: src/mainwin.cc:1368 -msgid "AST Dump" -msgstr "" - -#: src/mainwin.cc:1373 -msgid "No AST to dump. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1386 -msgid "CSG Tree Dump" -msgstr "" - -#: src/mainwin.cc:1391 -msgid "No CSG to dump. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1404 -msgid "CSG Products Dump" -msgstr "" - -#: src/mainwin.cc:1406 -msgid "" -"\n" -"CSG before normalization:\n" -"%1\n" -"\n" -"\n" -"CSG after normalization:\n" -"%2\n" -"\n" -"\n" -"CSG rendering chain:\n" -"%3\n" -"\n" -"\n" -"Highlights CSG rendering chain:\n" -"%4\n" -"\n" -"\n" -"Background CSG rendering chain:\n" -"%5\n" -msgstr "" - -#: src/mainwin.cc:1429 src/mainwin.cc:1490 -msgid "Nothing to export! Try building first (press F6)." -msgstr "" - -#: src/mainwin.cc:1435 -msgid "Current top level object is not a 3D object." -msgstr "" - -#: src/mainwin.cc:1442 -msgid "" -"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." -"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" -msgstr "" - -#: src/mainwin.cc:1449 -msgid "Export STL File" -msgstr "" - -#: src/mainwin.cc:1449 -msgid "Export OFF File" -msgstr "" - -#: src/mainwin.cc:1451 -msgid "STL Files (*.stl)" -msgstr "" - -#: src/mainwin.cc:1451 -msgid "OFF Files (*.off)" -msgstr "" - -#: src/mainwin.cc:1453 -#, c-format -msgid "No filename specified. %s export aborted." -msgstr "" - -#: src/mainwin.cc:1460 src/mainwin.cc:1513 src/mainwin.cc:1546 -#: src/openscad.cc:313 src/openscad.cc:325 src/openscad.cc:343 -#: src/openscad.cc:391 src/openscad.cc:406 src/openscad.cc:421 -#: src/openscad.cc:432 -#, c-format -msgid "Can't open file \"%s\" for export" -msgstr "" - -#: src/mainwin.cc:1467 -#, c-format -msgid "%s export finished." -msgstr "" - -#: src/mainwin.cc:1496 -msgid "Current top level object is not a 2D object." -msgstr "" - -#: src/mainwin.cc:1502 -msgid "Export DXF File" -msgstr "" - -#: src/mainwin.cc:1503 -msgid "Untitled.dxf" -msgstr "" - -#: src/mainwin.cc:1504 -msgid "DXF Files (*.dxf)" -msgstr "" - -#: src/mainwin.cc:1506 -msgid "No filename specified. DXF export aborted." -msgstr "" - -#: src/mainwin.cc:1518 -msgid "DXF export finished." -msgstr "" - -#: src/mainwin.cc:1530 -msgid "Nothing to export. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1535 -msgid "Export CSG File" -msgstr "" - -#: src/mainwin.cc:1536 -msgid "Untitled.csg" -msgstr "" - -#: src/mainwin.cc:1537 -msgid "CSG Files (*.csg)" -msgstr "" - -#: src/mainwin.cc:1539 -msgid "No filename specified. CSG export aborted." -msgstr "" - -#: src/mainwin.cc:1551 -msgid "CSG export finished." -msgstr "" - -#: src/mainwin.cc:1562 -msgid "Export Image" -msgstr "" - -#: src/mainwin.cc:1562 -msgid "PNG Files (*.png)" -msgstr "" - -#: src/mainwin.cc:1564 -msgid "No filename specified. Image export aborted." -msgstr "" - -#: src/mainwin.cc:1816 -msgid "http://openscad.org/" -msgstr "" - -#: src/mainwin.cc:1822 -msgid "http://www.openscad.org/documentation.html" -msgstr "" - -#: src/mainwin.cc:1831 -msgid "OpenGL Info" -msgstr "" - -#: src/mainwin.cc:1831 +#: objects/ui_LibraryInfoDialog.h:76 msgid "OpenSCAD Detailed Library and Build Information" msgstr "" -#: src/mainwin.cc:1847 +#: objects/ui_MainWindow.h:732 +msgid "&New" +msgstr "" + +#: objects/ui_MainWindow.h:733 +msgid "Ctrl+N" +msgstr "" + +#: objects/ui_MainWindow.h:734 +msgid "&Open..." +msgstr "" + +#: objects/ui_MainWindow.h:735 +msgid "Ctrl+O" +msgstr "" + +#: objects/ui_MainWindow.h:736 +msgid "&Save" +msgstr "" + +#: objects/ui_MainWindow.h:737 +msgid "Ctrl+S" +msgstr "" + +#: objects/ui_MainWindow.h:738 +msgid "Save &As..." +msgstr "" + +#: objects/ui_MainWindow.h:739 +msgid "Ctrl+Shift+S" +msgstr "" + +#: objects/ui_MainWindow.h:740 +msgid "&Reload" +msgstr "" + +#: objects/ui_MainWindow.h:741 +msgid "Ctrl+R" +msgstr "" + +#: objects/ui_MainWindow.h:742 +msgid "&Quit" +msgstr "" + +#: objects/ui_MainWindow.h:743 +msgid "Ctrl+Q" +msgstr "" + +#: objects/ui_MainWindow.h:744 +msgid "&Undo" +msgstr "" + +#: objects/ui_MainWindow.h:745 +msgid "Ctrl+Z" +msgstr "" + +#: objects/ui_MainWindow.h:746 +msgid "&Redo" +msgstr "" + +#: objects/ui_MainWindow.h:747 +msgid "Ctrl+Shift+Z" +msgstr "" + +#: objects/ui_MainWindow.h:748 +msgid "Cu&t" +msgstr "" + +#: objects/ui_MainWindow.h:749 +msgid "Ctrl+X" +msgstr "" + +#: objects/ui_MainWindow.h:750 +msgid "&Copy" +msgstr "" + +#: objects/ui_MainWindow.h:751 +msgid "Ctrl+C" +msgstr "" + +#: objects/ui_MainWindow.h:752 +msgid "&Paste" +msgstr "" + +#: objects/ui_MainWindow.h:753 +msgid "Ctrl+V" +msgstr "" + +#: objects/ui_MainWindow.h:754 +msgid "&Indent" +msgstr "" + +#: objects/ui_MainWindow.h:755 +msgid "Ctrl+I" +msgstr "" + +#: objects/ui_MainWindow.h:756 +msgid "U&nindent" +msgstr "" + +#: objects/ui_MainWindow.h:757 +msgid "Ctrl+Shift+I" +msgstr "" + +#: objects/ui_MainWindow.h:758 +msgid "C&omment" +msgstr "" + +#: objects/ui_MainWindow.h:759 +msgid "Ctrl+D" +msgstr "" + +#: objects/ui_MainWindow.h:760 +msgid "Unco&mment" +msgstr "" + +#: objects/ui_MainWindow.h:761 +msgid "Ctrl+Shift+D" +msgstr "" + +#: objects/ui_MainWindow.h:762 +msgid "Paste viewport translation" +msgstr "" + +#: objects/ui_MainWindow.h:763 +msgid "Ctrl+T" +msgstr "" + +#: objects/ui_MainWindow.h:764 +msgid "Paste viewport rotation" +msgstr "" + +#: objects/ui_MainWindow.h:765 objects/ui_MainWindow.h:844 +msgid "Zoom In" +msgstr "" + +#: objects/ui_MainWindow.h:766 +msgid "Ctrl++" +msgstr "" + +#: objects/ui_MainWindow.h:767 objects/ui_MainWindow.h:846 +msgid "Zoom Out" +msgstr "" + +#: objects/ui_MainWindow.h:768 +msgid "Ctrl+-" +msgstr "" + +#: objects/ui_MainWindow.h:769 +msgid "Hide editor" +msgstr "" + +#: objects/ui_MainWindow.h:770 +msgid "&Reload and Preview" +msgstr "" + +#: objects/ui_MainWindow.h:771 +msgid "F4" +msgstr "" + +#: objects/ui_MainWindow.h:772 +msgid "&Preview" +msgstr "" + +#: objects/ui_MainWindow.h:773 +msgid "F5" +msgstr "" + +#: objects/ui_MainWindow.h:774 +msgid "&Render" +msgstr "" + +#: objects/ui_MainWindow.h:775 +msgid "F6" +msgstr "" + +#: objects/ui_MainWindow.h:776 +msgid "Check Validity" +msgstr "" + +#: objects/ui_MainWindow.h:777 +msgid "Display &AST..." +msgstr "" + +#: objects/ui_MainWindow.h:778 +msgid "Display CSG &Tree..." +msgstr "" + +#: objects/ui_MainWindow.h:779 +msgid "Display CSG &Products..." +msgstr "" + +#: objects/ui_MainWindow.h:780 +msgid "Export as &STL..." +msgstr "" + +#: objects/ui_MainWindow.h:781 +msgid "Export as &OFF..." +msgstr "" + +#: objects/ui_MainWindow.h:782 +msgid "Preview" +msgstr "" + +#: objects/ui_MainWindow.h:783 +msgid "F9" +msgstr "" + +#: objects/ui_MainWindow.h:784 +msgid "Surfaces" +msgstr "" + +#: objects/ui_MainWindow.h:785 +msgid "F10" +msgstr "" + +#: objects/ui_MainWindow.h:786 +msgid "Wireframe" +msgstr "" + +#: objects/ui_MainWindow.h:787 +msgid "F11" +msgstr "" + +#: objects/ui_MainWindow.h:788 +msgid "Thrown Together" +msgstr "" + +#: objects/ui_MainWindow.h:789 +msgid "F12" +msgstr "" + +#: objects/ui_MainWindow.h:790 +msgid "Show Edges" +msgstr "" + +#: objects/ui_MainWindow.h:791 +msgid "Ctrl+1" +msgstr "" + +#: objects/ui_MainWindow.h:792 +msgid "Show Axes" +msgstr "" + +#: objects/ui_MainWindow.h:793 +msgid "Ctrl+2" +msgstr "" + +#: objects/ui_MainWindow.h:794 +msgid "Show Crosshairs" +msgstr "" + +#: objects/ui_MainWindow.h:795 +msgid "Ctrl+3" +msgstr "" + +#: objects/ui_MainWindow.h:796 +msgid "Animate" +msgstr "" + +#: objects/ui_MainWindow.h:797 +msgid "Top" +msgstr "" + +#: objects/ui_MainWindow.h:798 +msgid "Ctrl+4" +msgstr "" + +#: objects/ui_MainWindow.h:799 +msgid "Bottom" +msgstr "" + +#: objects/ui_MainWindow.h:800 +msgid "Ctrl+5" +msgstr "" + +#: objects/ui_MainWindow.h:801 +msgid "Left" +msgstr "" + +#: objects/ui_MainWindow.h:802 +msgid "Ctrl+6" +msgstr "" + +#: objects/ui_MainWindow.h:803 +msgid "Right" +msgstr "" + +#: objects/ui_MainWindow.h:804 +msgid "Ctrl+7" +msgstr "" + +#: objects/ui_MainWindow.h:805 +msgid "Front" +msgstr "" + +#: objects/ui_MainWindow.h:806 +msgid "Ctrl+8" +msgstr "" + +#: objects/ui_MainWindow.h:807 +msgid "Back" +msgstr "" + +#: objects/ui_MainWindow.h:808 +msgid "Ctrl+9" +msgstr "" + +#: objects/ui_MainWindow.h:809 +msgid "Diagonal" +msgstr "" + +#: objects/ui_MainWindow.h:810 +msgid "Ctrl+0" +msgstr "" + +#: objects/ui_MainWindow.h:811 +msgid "Center" +msgstr "" + +#: objects/ui_MainWindow.h:812 +msgid "Perspective" +msgstr "" + +#: objects/ui_MainWindow.h:813 +msgid "Orthogonal" +msgstr "" + +#: objects/ui_MainWindow.h:814 +msgid "Hide console" +msgstr "" + +#: objects/ui_MainWindow.h:815 +msgid "About" +msgstr "" + +#: objects/ui_MainWindow.h:816 +msgid "Documentation" +msgstr "" + +#: objects/ui_MainWindow.h:817 +msgid "Clear Recent" +msgstr "" + +#: objects/ui_MainWindow.h:818 +msgid "Export as DXF..." +msgstr "" + +#: objects/ui_MainWindow.h:819 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "" + +#: objects/ui_MainWindow.h:820 +msgid "Ctrl+W" +msgstr "" + +#: objects/ui_MainWindow.h:821 objects/ui_Preferences.h:609 +msgid "Preferences" +msgstr "" + +#: objects/ui_MainWindow.h:822 +msgid "Find..." +msgstr "" + +#: objects/ui_MainWindow.h:823 +msgid "Ctrl+F" +msgstr "" + +#: objects/ui_MainWindow.h:824 +msgid "Find and Replace..." +msgstr "" + +#: objects/ui_MainWindow.h:825 +msgid "Ctrl+Alt+F" +msgstr "" + +#: objects/ui_MainWindow.h:826 +msgid "Find Next" +msgstr "" + +#: objects/ui_MainWindow.h:827 +msgid "Ctrl+G" +msgstr "" + +#: objects/ui_MainWindow.h:828 +msgid "Find Previous" +msgstr "" + +#: objects/ui_MainWindow.h:829 +msgid "Ctrl+Shift+G" +msgstr "" + +#: objects/ui_MainWindow.h:830 +msgid "Use Selection for Find" +msgstr "" + +#: objects/ui_MainWindow.h:831 +msgid "Ctrl+E" +msgstr "" + +#: objects/ui_MainWindow.h:832 +msgid "Flush Caches" +msgstr "" + +#: objects/ui_MainWindow.h:833 +msgid "OpenSCAD Homepage" +msgstr "" + +#: objects/ui_MainWindow.h:834 +msgid "Automatic Reload and Preview" +msgstr "" + +#: objects/ui_MainWindow.h:835 +msgid "Export as Image..." +msgstr "" + +#: objects/ui_MainWindow.h:836 +msgid "Export as CSG..." +msgstr "" + +#: objects/ui_MainWindow.h:837 +msgid "Library info" +msgstr "" + +#: objects/ui_MainWindow.h:838 +msgid "Check for Update.." +msgstr "" + +#: objects/ui_MainWindow.h:839 +msgid "Show Library Folder..." +msgstr "" + +#: objects/ui_MainWindow.h:840 +msgid "Reset View" +msgstr "" + +#: objects/ui_MainWindow.h:841 +msgid "Font List" +msgstr "" + +#: objects/ui_MainWindow.h:842 +msgid "Export as SVG..." +msgstr "" + +#: objects/ui_MainWindow.h:843 +msgid "Export as AMF..." +msgstr "" + +#: objects/ui_MainWindow.h:845 +msgid "Ctrl+]" +msgstr "" + +#: objects/ui_MainWindow.h:847 +msgid "Ctrl+[" +msgstr "" + +#: objects/ui_MainWindow.h:848 +msgid "View All" +msgstr "" + +#: objects/ui_MainWindow.h:849 +msgid "Convert Tabs to Spaces" +msgstr "" + +#: objects/ui_MainWindow.h:850 +msgid "Hide toolbars" +msgstr "" + +#: objects/ui_MainWindow.h:851 +msgid "Time:" +msgstr "" + +#: objects/ui_MainWindow.h:852 +msgid "FPS:" +msgstr "" + +#: objects/ui_MainWindow.h:853 +msgid "Steps:" +msgstr "" + +#: objects/ui_MainWindow.h:854 +msgid "Dump Pictures" +msgstr "" + +#: objects/ui_MainWindow.h:855 +msgid "&File" +msgstr "" + +#: objects/ui_MainWindow.h:856 +msgid "Recent Files" +msgstr "" + +#: objects/ui_MainWindow.h:857 objects/ui_launchingscreen.h:282 +#: objects/ui_launchingscreen.h:284 +msgid "Examples" +msgstr "" + +#: objects/ui_MainWindow.h:858 +msgid "Export" +msgstr "" + +#: objects/ui_MainWindow.h:859 +msgid "&Edit" +msgstr "" + +#: objects/ui_MainWindow.h:860 +msgid "&Design" +msgstr "" + +#: objects/ui_MainWindow.h:861 +msgid "&View" +msgstr "" + +#: objects/ui_MainWindow.h:862 +msgid "&Help" +msgstr "" + +#: objects/ui_MainWindow.h:865 +msgid "Find" +msgstr "" + +#: objects/ui_MainWindow.h:866 objects/ui_MainWindow.h:873 +msgid "Replace" +msgstr "" + +#: objects/ui_MainWindow.h:868 +msgid "Search string" +msgstr "" + +#: objects/ui_MainWindow.h:869 +msgid "<" +msgstr "" + +#: objects/ui_MainWindow.h:870 +msgid ">" +msgstr "" + +#: objects/ui_MainWindow.h:871 +msgid "Done" +msgstr "" + +#: objects/ui_MainWindow.h:872 +msgid "Replacement string" +msgstr "" + +#: objects/ui_MainWindow.h:874 +msgid "All" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:87 msgid "" -"The document has been modified.\n" -"Do you want to save your changes?" +"\n" +"\n" +"

" msgstr "" -#: src/modcontext.cc:100 -#, c-format -msgid "WARNING: Experimental builtin function '%s' is not enabled." +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" msgstr "" -#: src/modcontext.cc:113 -#, c-format -msgid "WARNING: Experimental builtin module '%s' is not enabled." +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" msgstr "" -#: src/modcontext.cc:118 -#, c-format -msgid "" -"DEPRECATED: The %s() module will be removed in future releases. Use %s() " -"instead." -msgstr "" - -#: src/modcontext.cc:145 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p) " -msgstr "" - -#: src/modcontext.cc:147 -#, c-format -msgid "ModuleContext: %p (%p)" -msgstr "" - -#: src/modcontext.cc:193 -#, c-format -msgid "New lib Context for %s func:" -msgstr "" - -#: src/modcontext.cc:217 -msgid "New file Context:" -msgstr "" - -#: src/ModuleCache.cc:70 -#, c-format -msgid "Recompiling cached library: %s (%s)" -msgstr "" - -#: src/ModuleCache.cc:73 -#, c-format -msgid "Compiling library '%s'." -msgstr "" - -#: src/ModuleCache.cc:81 -#, c-format -msgid "WARNING: Can't open library file '%s'\n" -msgstr "" - -#: src/ModuleCache.cc:99 -#, c-format -msgid " compiled module: %p" -msgstr "" - -#: src/module.cc:139 -msgid "New eval ctx:" -msgstr "" - -#: src/module.cc:180 -#, c-format -msgid "ERROR: Recursion detected calling module '%s'" -msgstr "" - -#: src/module.cc:298 -#, c-format -msgid "WARNING: Failed to compile library '%s'." -msgstr "" - -#: src/OffscreenView.cc:27 -msgid "OpenSCAD recommended OpenGL version is 2.0." -msgstr "" - -#: src/openscad.cc:107 -msgid "" -"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" -"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" -"%2%[ --version ] [ --info ] \\\n" -"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" -"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" -"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" -"%2%[ --render | --preview[=throwntogether] ] \\\n" -"%2%[ --enable= ] \\\n" -"%2%filename\n" -msgstr "" - -#: src/openscad.cc:124 -#, c-format -msgid "OpenSCAD version %s\n" -msgstr "" - -#: src/openscad.cc:136 -#, c-format -msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" -msgstr "" - -#: src/openscad.cc:180 -msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" -msgstr "" - -#: src/openscad.cc:181 -msgid "or 6 numbers for Vector Camera\n" -msgstr "" - -#: src/openscad.cc:197 -msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" -msgstr "" - -#: src/openscad.cc:208 -msgid "Need 2 numbers for imgsize\n" -msgstr "" - -#: src/openscad.cc:257 -#, c-format -msgid "Unknown suffix for output file %s\n" -msgstr "" - -#: src/openscad.cc:281 -#, c-format -msgid "Can't open input file '%s'!\n" -msgstr "" - -#: src/openscad.cc:290 -#, c-format -msgid "Can't parse file '%s'!\n" -msgstr "" - -#: src/openscad.cc:373 -#, c-format -msgid "Output file:%s\n" -msgstr "" - -#: src/openscad.cc:374 -msgid "Sorry, don't know how to write deps for that file type. Exiting\n" -msgstr "" - -#: src/openscad.cc:379 -msgid "error writing deps" -msgstr "" - -#: src/openscad.cc:386 src/openscad.cc:401 -msgid "Current top level object is not a 3D object.\n" -msgstr "" - -#: src/openscad.cc:416 -msgid "Current top level object is not a 2D object.\n" -msgstr "" - -#: src/openscad.cc:594 -msgid "Allowed options" -msgstr "" - -#: src/openscad.cc:596 -msgid "help message" -msgstr "" - -#: src/openscad.cc:597 -msgid "print the version" -msgstr "" - -#: src/openscad.cc:598 -msgid "print information about the building process" -msgstr "" - -#: src/openscad.cc:599 -msgid "if exporting a png image, do a full CGAL render" -msgstr "" - -#: src/openscad.cc:600 -msgid "" -"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" -msgstr "" - -#: src/openscad.cc:601 -msgid "parameters for camera when exporting png" -msgstr "" - -#: src/openscad.cc:602 -msgid "=width,height for exporting png" -msgstr "" - -#: src/openscad.cc:603 -msgid "(o)rtho or (p)erspective when exporting png" -msgstr "" - -#: src/openscad.cc:604 -msgid "out-file" -msgstr "" - -#: src/openscad.cc:605 -msgid "stl-file" -msgstr "" - -#: src/openscad.cc:606 -msgid "dxf-file" -msgstr "" - -#: src/openscad.cc:607 -msgid "deps-file" -msgstr "" - -#: src/openscad.cc:608 -msgid "makefile" -msgstr "" - -#: src/openscad.cc:609 -msgid "var=val" -msgstr "" - -#: src/openscad.cc:610 -msgid "enable experimental features" -msgstr "" - -#: src/openscad.cc:612 -msgid "Hidden options" -msgstr "" - -#: src/openscad.cc:614 -msgid "input file" -msgstr "" - -#: src/openscad.cc:648 -msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" -msgstr "" - -#: src/openscad.cc:653 -msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" -msgstr "" - -#: src/openscad.cc:710 -msgid "Requested GUI mode but can't open display!\n" -msgstr "" - -#: src/PlatformUtils.cc:16 -#, c-format -msgid "ERROR: Cannot create %s" -msgstr "" - -#: src/polyset.cc:63 -msgid "PolySet:" -msgstr "" - -#: src/polyset.cc:64 +#: objects/ui_Preferences.h:610 +msgid "3D View" +msgstr "" + +#: objects/ui_Preferences.h:611 src/UIUtils.cc:85 +msgid "Advanced" +msgstr "" + +#: objects/ui_Preferences.h:612 src/mainwin.cc:2292 +msgid "Editor" +msgstr "" + +#: objects/ui_Preferences.h:613 +msgid "Update" +msgstr "" + +#: objects/ui_Preferences.h:614 objects/ui_Preferences.h:661 +msgid "Features" +msgstr "" + +#: objects/ui_Preferences.h:616 +msgid "Enable/Disable experimental features" +msgstr "" + +#: objects/ui_Preferences.h:618 +msgid "Color scheme:" +msgstr "" + +#: objects/ui_Preferences.h:623 +msgid "Cornfield" +msgstr "" + +#: objects/ui_Preferences.h:625 +msgid "Metallic" +msgstr "" + +#: objects/ui_Preferences.h:627 +msgid "Sunset" +msgstr "" + +#: objects/ui_Preferences.h:629 +msgid "Starnight" +msgstr "" + +#: objects/ui_Preferences.h:631 +msgid "BeforeDawn" +msgstr "" + +#: objects/ui_Preferences.h:633 +msgid "Nature" +msgstr "" + +#: objects/ui_Preferences.h:635 +msgid "DeepOcean" +msgstr "" + +#: objects/ui_Preferences.h:638 +msgid "Editor Type" +msgstr "" + +#: objects/ui_Preferences.h:641 +msgid "Simple Editor" +msgstr "" + +#: objects/ui_Preferences.h:642 +msgid "QScintilla Editor" +msgstr "" + +#: objects/ui_Preferences.h:644 +msgid "(requires restart)" +msgstr "" + +#: objects/ui_Preferences.h:645 +msgid "Font" +msgstr "" + +#: objects/ui_Preferences.h:646 +msgid "Color syntax highlighting" +msgstr "" + +#: objects/ui_Preferences.h:649 +msgid "For Light Background" +msgstr "" + +#: objects/ui_Preferences.h:650 +msgid "For Dark Background" +msgstr "" + +#: objects/ui_Preferences.h:651 +msgid "Monokai" +msgstr "" + +#: objects/ui_Preferences.h:652 +msgid "Solarized" +msgstr "" + +#: objects/ui_Preferences.h:653 +msgid "Off" +msgstr "" + +#: objects/ui_Preferences.h:655 +msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" +msgstr "" + +#: objects/ui_Preferences.h:657 +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:658 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:659 +msgid "Check Now" +msgstr "" + +#: objects/ui_Preferences.h:660 +msgid "Last checked: " +msgstr "" + +#: objects/ui_Preferences.h:662 +msgid "OpenCSG" +msgstr "" + +#: objects/ui_Preferences.h:663 +msgid "Show capability warning" +msgstr "" + +#: objects/ui_Preferences.h:664 +msgid "Enable for OpenGL 1.x" +msgstr "" + +#: objects/ui_Preferences.h:665 +msgid "Turn off rendering at " +msgstr "" + +#: objects/ui_Preferences.h:666 +msgid "elements" +msgstr "" + +#: objects/ui_Preferences.h:667 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:668 +msgid "CGAL Cache size" +msgstr "" + +#: objects/ui_Preferences.h:669 objects/ui_Preferences.h:671 +msgid "bytes" +msgstr "" + +#: objects/ui_Preferences.h:670 +msgid "PolySet Cache size" +msgstr "" + +#: objects/ui_Preferences.h:672 +msgid "Allow to open multiple documents" +msgstr "" + +#: objects/ui_Preferences.h:673 +msgid "Enable undocking of Editor and Console" +msgstr "" + +#: objects/ui_Preferences.h:674 +msgid "Show Welcome Screen" +msgstr "" + +#: objects/ui_Preferences.h:675 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" + +#: objects/ui_Preferences.h:676 +msgid "toolBar" +msgstr "" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "" + +#: objects/ui_launchingscreen.h:277 +msgid "New" +msgstr "" + +#: objects/ui_launchingscreen.h:278 +msgid "Open" +msgstr "" + +#: objects/ui_launchingscreen.h:279 +msgid "Help" +msgstr "" + +#: objects/ui_launchingscreen.h:280 +msgid "Recents" +msgstr "" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "" + +#: objects/ui_launchingscreen.h:285 +msgid "Open Example" +msgstr "" + +#: objects/ui_launchingscreen.h:287 msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" "\n" -" dimensions:" -msgstr "" - -#: src/polyset.cc:65 -msgid "" "\n" -" convexity:" msgstr "" -#: src/polyset.cc:66 -msgid "" -"\n" -" num polygons: " +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" msgstr "" -#: src/polyset.cc:67 -msgid "" -"\n" -" num outlines: " +#: src/AboutDialog.h:15 +msgid "About OpenSCAD " msgstr "" -#: src/polyset.cc:68 -msgid "" -"\n" -" polygons data:" -msgstr "" - -#: src/polyset.cc:70 -msgid "" -"\n" -" polygon begin:" -msgstr "" - -#: src/polyset.cc:74 -msgid "" -"\n" -" vertex:" -msgstr "" - -#: src/polyset.cc:77 -msgid "" -"\n" -" outlines data:" -msgstr "" - -#: src/polyset.cc:79 -msgid "" -"\n" -"PolySet end" -msgstr "" - -#: src/primitives.cc:134 -#, c-format -msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." -msgstr "" - -#: src/primitives.cc:187 -#, c-format -msgid "WARNING: $fs too small - clamping to %f" -msgstr "" - -#: src/primitives.cc:191 -#, c-format -msgid "WARNING: $fa too small - clamping to %f" -msgstr "" - -#: src/primitives.cc:248 -msgid "" -"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " -"polyhedron(faces=[]) instead." -msgstr "" - -#: src/primitives.cc:515 -#, c-format -msgid "ERROR: Unable to convert point at index %d to a vec3 of numbers" -msgstr "" - -#: src/primitives.cc:575 -#, c-format -msgid "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" -msgstr "" - -#: src/QGLView.cc:105 +#: src/QGLView.cc:114 msgid "" "\n" "Using QGLWidget\n" "\n" msgstr "" -#: src/QGLView.cc:122 +#: src/QGLView.cc:131 msgid "" "Warning: You may experience OpenCSG rendering errors.\n" "\n" msgstr "" -#: src/QGLView.cc:125 +#: src/QGLView.cc:134 msgid "" "Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " "disabled.\n" "\n" msgstr "" -#: src/QGLView.cc:128 +#: src/QGLView.cc:137 msgid "" "It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " "later.\n" "Your renderer information is as follows:\n" msgstr "" -#: src/QGLView.cc:132 +#: src/QGLView.cc:141 #, c-format msgid "" "GLEW version %s\n" @@ -1902,31 +906,97 @@ msgid "" "OpenGL version %s\n" msgstr "" -#: src/QGLView.cc:163 +#: src/QGLView.cc:171 #, c-format msgid "" "Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " "distance = %.2f" msgstr "" -#: src/rotateextrude.cc:71 +#: src/UIUtils.cc:85 +msgid "Basics" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Shapes" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Extrusion" +msgstr "" + +#: src/mainwin.cc:728 src/mainwin.cc:1269 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1268 +msgid "Save File" +msgstr "" + +#: src/mainwin.cc:1270 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1280 msgid "" -"DEPRECATED: Support for reading files in rotate_extrude will be removed in " -"future releases. Use a child import() instead." +"%1 already exists.\n" +"Do you want to replace it?" msgstr "" -#: src/surface.cc:107 -#, c-format -msgid "WARNING: Can't open DAT file '%s'." +#: src/mainwin.cc:1608 +msgid "Application" msgstr "" -#: src/surface.cc:139 -#, c-format -msgid "WARNING: Illegal value in '%s': %s" -msgstr "" - -#: src/value.cc:644 +#: src/mainwin.cc:1609 msgid "" -"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " -"than the end value is deprecated." +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1907 src/mainwin.cc:1964 +msgid "Export %1 File" +msgstr "" + +#: src/mainwin.cc:1908 src/mainwin.cc:1968 +msgid "%1 Files (*%2)" +msgstr "" + +#: src/mainwin.cc:1909 +msgid "Untitled" +msgstr "" + +#: src/mainwin.cc:1966 +msgid "Untitled%1" +msgstr "" + +#: src/mainwin.cc:2017 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:2018 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:2019 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:2045 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:2045 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:2297 +msgid "Console" +msgstr "" + +#: src/mainwin.cc:2420 +msgid "The document has been modified." +msgstr "" + +#: src/mainwin.cc:2421 +msgid "Do you want to save your changes?" msgstr "" From ca3672b19c2a78b7fb84733319004b3a6572b10a Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 13 Nov 2014 00:20:01 +0100 Subject: [PATCH 031/263] Move translation files to locale folder instead of po. While this is not the standard name for the files, this makes the resource handling easier as the PlatformUtils code already handles lookup for both installed and dev layouts. At least for Linux the installed name would be /usr/share/locale, so we use that in source too for now. --- {po => locale}/LINGUAS | 0 locale/POTFILES | 228 ++++ {po => locale}/cs.po | 665 ++++++----- {po => locale}/de.po | 688 ++++++------ locale/fr.po | 971 ++++++++++++++++ {po => locale}/openscad.pot | 648 +++++------ locale/ru.po | 1009 +++++++++++++++++ openscad.pro | 6 +- po/fr.po | 1938 -------------------------------- po/ru.po | 1950 --------------------------------- scripts/translation-make.sh | 4 +- scripts/translation-update.sh | 20 +- src/PlatformUtils.cc | 4 - src/colormap.cc | 2 +- src/scintillaeditor.cpp | 3 +- 15 files changed, 3185 insertions(+), 4951 deletions(-) rename {po => locale}/LINGUAS (100%) create mode 100644 locale/POTFILES rename {po => locale}/cs.po (87%) rename {po => locale}/de.po (94%) create mode 100644 locale/fr.po rename {po => locale}/openscad.pot (84%) create mode 100644 locale/ru.po delete mode 100644 po/fr.po delete mode 100644 po/ru.po diff --git a/po/LINGUAS b/locale/LINGUAS similarity index 100% rename from po/LINGUAS rename to locale/LINGUAS diff --git a/locale/POTFILES b/locale/POTFILES new file mode 100644 index 00000000..b412c7f0 --- /dev/null +++ b/locale/POTFILES @@ -0,0 +1,228 @@ +./objects/ui_AboutDialog.h +./objects/ui_FontListDialog.h +./objects/ui_launchingscreen.h +./objects/ui_LibraryInfoDialog.h +./objects/ui_MainWindow.h +./objects/ui_OpenCSGWarningDialog.h +./objects/ui_Preferences.h +./objects/ui_ProgressWidget.h +src/AboutDialog.h +src/AppleEvents.h +src/AutoUpdater.h +src/boost-utils.h +src/boosty.h +src/builtin.h +src/cache.h +src/calc.h +src/Camera.h +src/cgaladvnode.h +src/CGALCache.h +src/cgalfwd.h +src/cgal.h +src/CGAL_Nef3_workaround.h +src/CGAL_Nef_polyhedron.h +src/CGAL_OGL_Polyhedron.h +src/CGALRenderer.h +src/cgalutils.h +src/CGAL_workaround_Mark_bounded_volumes.h +src/cgalworker.h +src/clipper-utils.h +src/CocoaUtils.h +src/colormap.h +src/colornode.h +src/context.h +src/CsgInfo.h +src/csgnode.h +src/CSGTermEvaluator.h +src/csgterm.h +src/csgtermnormalizer.h +src/Dock.h +src/DrawingCallback.h +src/dxfdata.h +src/dxfdim.h +src/editor.h +src/enums.h +src/evalcontext.h +src/EventFilter.h +src/export.h +src/expression.h +src/fbo.h +src/feature.h +src/fileutils.h +src/FontCache.h +src/FontListDialog.h +src/FreetypeRenderer.h +src/function.h +src/GeometryCache.h +src/GeometryEvaluator.h +src/Geometry.h +src/GLView.h +src/grid.h +src/handle_dep.h +src/highlighter.h +src/imageutils.h +src/importnode.h +src/launchingscreen.h +src/legacyeditor.h +src/LibraryInfoDialog.h +src/LibraryInfo.h +src/linalg.h +src/linearextrudenode.h +src/localscope.h +src/lodepng.h +src/MainWindow.h +src/mathc99.h +src/memory.h +src/modcontext.h +src/ModuleCache.h +src/module.h +src/nodecache.h +src/nodedumper.h +src/node.h +src/OffscreenContext.h +src/OffscreenView.h +src/offsetnode.h +src/OGL_helper.h +src/OpenCSGRenderer.h +src/OpenCSGWarningDialog.h +src/openscad.h +src/parsersettings.h +src/parser_yacc.h +src/PlatformUtils.h +src/Polygon2d-CGAL.h +src/Polygon2d.h +src/polyset.h +src/polyset-utils.h +src/Preferences.h +src/printutils.h +src/progress.h +src/ProgressWidget.h +src/projectionnode.h +src/QGLView.h +src/qtgettext.h +src/Reindexer.h +src/renderer.h +src/rendernode.h +src/rendersettings.h +src/rotateextrudenode.h +src/scadlexer.h +src/scintillaeditor.h +src/SparkleAutoUpdater.h +src/state.h +src/stl-utils.h +src/svg.h +src/system-gl.h +src/textnode.h +src/ThrownTogetherRenderer.h +src/transformnode.h +src/traverser.h +src/Tree.h +src/typedefs.h +src/UIUtils.h +src/value.h +src/version_check.h +src/visitor.h +src/AppleEvents.cc +src/AutoUpdater.cc +src/boost-utils.cc +src/builtin.cc +src/calc.cc +src/Camera.cc +src/cgaladv.cc +src/CGALCache.cc +src/CGAL_Nef_polyhedron.cc +src/CGAL_Nef_polyhedron_DxfData.cc +src/CGALRenderer.cc +src/cgalutils.cc +src/cgalutils-tess.cc +src/cgalworker.cc +src/clipper-utils.cc +src/color.cc +src/colormap.cc +src/context.cc +src/control.cc +src/csgops.cc +src/csgterm.cc +src/CSGTermEvaluator.cc +src/csgtermnormalizer.cc +src/Dock.cc +src/DrawingCallback.cc +src/dxfdata.cc +src/dxfdim.cc +src/editor.cc +src/evalcontext.cc +src/export.cc +src/export_png.cc +src/expr.cc +src/fbo.cc +src/feature.cc +src/fileutils.cc +src/FontCache.cc +src/FontListDialog.cc +src/FreetypeRenderer.cc +src/func.cc +src/GeometryCache.cc +src/Geometry.cc +src/GeometryEvaluator.cc +src/GLView.cc +src/handle_dep.cc +src/highlighter.cc +src/imageutils.cc +src/imageutils-lodepng.cc +src/imageutils-macosx.cc +src/import.cc +src/launchingscreen.cc +src/legacyeditor.cc +src/LibraryInfo.cc +src/LibraryInfoDialog.cc +src/linalg.cc +src/linearextrude.cc +src/localscope.cc +src/mainwin.cc +src/mathc99.cc +src/modcontext.cc +src/ModuleCache.cc +src/module.cc +src/node.cc +src/nodedumper.cc +src/NULLGL.cc +src/OffscreenContextGLX.cc +src/OffscreenContextNULL.cc +src/OffscreenContextWGL.cc +src/OffscreenView.cc +src/offset.cc +src/OpenCSGRenderer.cc +src/OpenCSGWarningDialog.cc +src/openscad.cc +src/parsersettings.cc +src/PlatformUtils.cc +src/PlatformUtils-posix.cc +src/PlatformUtils-win.cc +src/Polygon2d.cc +src/Polygon2d-CGAL.cc +src/polyset.cc +src/polyset-utils.cc +src/polyset-utils-old.cc +src/Preferences.cc +src/primitives.cc +src/printutils.cc +src/progress.cc +src/ProgressWidget.cc +src/projection.cc +src/QGLView.cc +src/render.cc +src/renderer.cc +src/rendersettings.cc +src/rotateextrude.cc +src/stl-utils.cc +src/surface.cc +src/svg.cc +src/system-gl.cc +src/text.cc +src/ThrownTogetherRenderer.cc +src/transform.cc +src/traverser.cc +src/Tree.cc +src/UIUtils.cc +src/value.cc +src/version_check.cc diff --git a/po/cs.po b/locale/cs.po similarity index 87% rename from po/cs.po rename to locale/cs.po index 64dab28b..016b186f 100644 --- a/po/cs.po +++ b/locale/cs.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2013.02.24\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-10-19 18:27+0200\n" +"POT-Creation-Date: 2014-11-13 00:22+0100\n" "PO-Revision-Date: 2014-01-29 18:32+0100\n" "Last-Translator: Miro Hrončok \n" "Language-Team: Czech \n" @@ -20,8 +20,9 @@ msgstr "" "X-Poedit-SourceCharset: UTF-8\n" #: objects/ui_AboutDialog.h:51 +#, fuzzy msgid "About OpenSCAD" -msgstr "" +msgstr "Manuál k OpenSCADu (anglicky)" #: objects/ui_FontListDialog.h:102 #, fuzzy @@ -57,6 +58,63 @@ msgid "" ""Liberation Sans:style=Italic");
" msgstr "" +#: objects/ui_launchingscreen.h:276 +#, fuzzy +msgid "Welcome to OpenSCAD" +msgstr "Manuál k OpenSCADu (anglicky)" + +#: objects/ui_launchingscreen.h:277 +#, fuzzy +msgid "New" +msgstr "&Nový" + +#: objects/ui_launchingscreen.h:278 +#, fuzzy +msgid "Open" +msgstr "OpenCSG" + +#: objects/ui_launchingscreen.h:279 +#, fuzzy +msgid "Help" +msgstr "&Nápověda" + +#: objects/ui_launchingscreen.h:280 +#, fuzzy +msgid "Recents" +msgstr "Nedávné soubory" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "Nedávné soubory" + +#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 +#: objects/ui_MainWindow.h:858 +msgid "Examples" +msgstr "Příklady" + +#: objects/ui_launchingscreen.h:285 +#, fuzzy +msgid "Open Example" +msgstr "Příklady" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "" + #: objects/ui_LibraryInfoDialog.h:75 msgid "Lib & Build Info" msgstr "" @@ -65,561 +123,556 @@ msgstr "" msgid "OpenSCAD Detailed Library and Build Information" msgstr "" -#: objects/ui_MainWindow.h:732 +#: objects/ui_MainWindow.h:733 msgid "&New" msgstr "&Nový" -#: objects/ui_MainWindow.h:733 +#: objects/ui_MainWindow.h:734 msgid "Ctrl+N" msgstr "" -#: objects/ui_MainWindow.h:734 +#: objects/ui_MainWindow.h:735 msgid "&Open..." msgstr "&Otevřít..." -#: objects/ui_MainWindow.h:735 +#: objects/ui_MainWindow.h:736 msgid "Ctrl+O" msgstr "" -#: objects/ui_MainWindow.h:736 +#: objects/ui_MainWindow.h:737 msgid "&Save" msgstr "&Uložit" -#: objects/ui_MainWindow.h:737 +#: objects/ui_MainWindow.h:738 msgid "Ctrl+S" msgstr "" -#: objects/ui_MainWindow.h:738 +#: objects/ui_MainWindow.h:739 msgid "Save &As..." msgstr "Uložit &jako..." -#: objects/ui_MainWindow.h:739 +#: objects/ui_MainWindow.h:740 msgid "Ctrl+Shift+S" msgstr "" -#: objects/ui_MainWindow.h:740 +#: objects/ui_MainWindow.h:741 msgid "&Reload" msgstr "&Znovu načíst" -#: objects/ui_MainWindow.h:741 +#: objects/ui_MainWindow.h:742 msgid "Ctrl+R" msgstr "" -#: objects/ui_MainWindow.h:742 +#: objects/ui_MainWindow.h:743 msgid "&Quit" msgstr "U&končit" -#: objects/ui_MainWindow.h:743 +#: objects/ui_MainWindow.h:744 msgid "Ctrl+Q" msgstr "" -#: objects/ui_MainWindow.h:744 +#: objects/ui_MainWindow.h:745 msgid "&Undo" msgstr "&Zpět" -#: objects/ui_MainWindow.h:745 +#: objects/ui_MainWindow.h:746 msgid "Ctrl+Z" msgstr "" -#: objects/ui_MainWindow.h:746 +#: objects/ui_MainWindow.h:747 msgid "&Redo" msgstr "Zn&ovu" -#: objects/ui_MainWindow.h:747 +#: objects/ui_MainWindow.h:748 msgid "Ctrl+Shift+Z" msgstr "" -#: objects/ui_MainWindow.h:748 +#: objects/ui_MainWindow.h:749 msgid "Cu&t" msgstr "&Vyjmout" -#: objects/ui_MainWindow.h:749 +#: objects/ui_MainWindow.h:750 msgid "Ctrl+X" msgstr "" -#: objects/ui_MainWindow.h:750 +#: objects/ui_MainWindow.h:751 msgid "&Copy" msgstr "&Kopírovat" -#: objects/ui_MainWindow.h:751 +#: objects/ui_MainWindow.h:752 msgid "Ctrl+C" msgstr "" -#: objects/ui_MainWindow.h:752 +#: objects/ui_MainWindow.h:753 msgid "&Paste" msgstr "V&ložit" -#: objects/ui_MainWindow.h:753 +#: objects/ui_MainWindow.h:754 msgid "Ctrl+V" msgstr "" -#: objects/ui_MainWindow.h:754 +#: objects/ui_MainWindow.h:755 msgid "&Indent" msgstr "Odsad&it" -#: objects/ui_MainWindow.h:755 +#: objects/ui_MainWindow.h:756 msgid "Ctrl+I" msgstr "" -#: objects/ui_MainWindow.h:756 +#: objects/ui_MainWindow.h:757 msgid "U&nindent" msgstr "Z&rušit odsazení" -#: objects/ui_MainWindow.h:757 +#: objects/ui_MainWindow.h:758 msgid "Ctrl+Shift+I" msgstr "" -#: objects/ui_MainWindow.h:758 +#: objects/ui_MainWindow.h:759 msgid "C&omment" msgstr "&Zakomentovat" -#: objects/ui_MainWindow.h:759 +#: objects/ui_MainWindow.h:760 msgid "Ctrl+D" msgstr "" -#: objects/ui_MainWindow.h:760 +#: objects/ui_MainWindow.h:761 msgid "Unco&mment" msgstr "&Odkomentovat" -#: objects/ui_MainWindow.h:761 +#: objects/ui_MainWindow.h:762 msgid "Ctrl+Shift+D" msgstr "" -#: objects/ui_MainWindow.h:762 +#: objects/ui_MainWindow.h:763 msgid "Paste viewport translation" msgstr "Vložit posun pohledu" -#: objects/ui_MainWindow.h:763 +#: objects/ui_MainWindow.h:764 msgid "Ctrl+T" msgstr "" -#: objects/ui_MainWindow.h:764 +#: objects/ui_MainWindow.h:765 msgid "Paste viewport rotation" msgstr "Vložit rotaci pohledu" -#: objects/ui_MainWindow.h:765 objects/ui_MainWindow.h:844 +#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 msgid "Zoom In" msgstr "Přiblížit" -#: objects/ui_MainWindow.h:766 +#: objects/ui_MainWindow.h:767 msgid "Ctrl++" msgstr "" -#: objects/ui_MainWindow.h:767 objects/ui_MainWindow.h:846 +#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 msgid "Zoom Out" msgstr "Oddálit" -#: objects/ui_MainWindow.h:768 +#: objects/ui_MainWindow.h:769 msgid "Ctrl+-" msgstr "" -#: objects/ui_MainWindow.h:769 +#: objects/ui_MainWindow.h:770 msgid "Hide editor" msgstr "Skrýt editor" -#: objects/ui_MainWindow.h:770 +#: objects/ui_MainWindow.h:771 #, fuzzy msgid "&Reload and Preview" msgstr "Znovu &načíst a zkompilovat" -#: objects/ui_MainWindow.h:771 +#: objects/ui_MainWindow.h:772 msgid "F4" msgstr "" -#: objects/ui_MainWindow.h:772 +#: objects/ui_MainWindow.h:773 msgid "&Preview" msgstr "" -#: objects/ui_MainWindow.h:773 +#: objects/ui_MainWindow.h:774 msgid "F5" msgstr "" -#: objects/ui_MainWindow.h:774 +#: objects/ui_MainWindow.h:775 msgid "&Render" msgstr "" -#: objects/ui_MainWindow.h:775 +#: objects/ui_MainWindow.h:776 msgid "F6" msgstr "" -#: objects/ui_MainWindow.h:776 +#: objects/ui_MainWindow.h:777 msgid "Check Validity" msgstr "" -#: objects/ui_MainWindow.h:777 +#: objects/ui_MainWindow.h:778 msgid "Display &AST..." msgstr "Ukázat &ATS..." -#: objects/ui_MainWindow.h:778 +#: objects/ui_MainWindow.h:779 msgid "Display CSG &Tree..." msgstr "Ukázat CSG s&trom..." -#: objects/ui_MainWindow.h:779 +#: objects/ui_MainWindow.h:780 msgid "Display CSG &Products..." msgstr "Ukázat CSG &produkty..." -#: objects/ui_MainWindow.h:780 +#: objects/ui_MainWindow.h:781 msgid "Export as &STL..." msgstr "Exportovat jako &STL..." -#: objects/ui_MainWindow.h:781 +#: objects/ui_MainWindow.h:782 msgid "Export as &OFF..." msgstr "Exportovat jako &OFF..." -#: objects/ui_MainWindow.h:782 +#: objects/ui_MainWindow.h:783 msgid "Preview" msgstr "" -#: objects/ui_MainWindow.h:783 +#: objects/ui_MainWindow.h:784 msgid "F9" msgstr "" -#: objects/ui_MainWindow.h:784 +#: objects/ui_MainWindow.h:785 #, fuzzy msgid "Surfaces" msgstr "CGAL povrch" -#: objects/ui_MainWindow.h:785 +#: objects/ui_MainWindow.h:786 msgid "F10" msgstr "" -#: objects/ui_MainWindow.h:786 +#: objects/ui_MainWindow.h:787 msgid "Wireframe" msgstr "" -#: objects/ui_MainWindow.h:787 +#: objects/ui_MainWindow.h:788 msgid "F11" msgstr "" -#: objects/ui_MainWindow.h:788 +#: objects/ui_MainWindow.h:789 msgid "Thrown Together" msgstr "Vše společně" -#: objects/ui_MainWindow.h:789 +#: objects/ui_MainWindow.h:790 msgid "F12" msgstr "" -#: objects/ui_MainWindow.h:790 +#: objects/ui_MainWindow.h:791 msgid "Show Edges" msgstr "Zobrazit hrany" -#: objects/ui_MainWindow.h:791 +#: objects/ui_MainWindow.h:792 msgid "Ctrl+1" msgstr "" -#: objects/ui_MainWindow.h:792 +#: objects/ui_MainWindow.h:793 msgid "Show Axes" msgstr "Zobrazit osy" -#: objects/ui_MainWindow.h:793 +#: objects/ui_MainWindow.h:794 msgid "Ctrl+2" msgstr "" -#: objects/ui_MainWindow.h:794 +#: objects/ui_MainWindow.h:795 msgid "Show Crosshairs" msgstr "Zobrazit zaměřovač" -#: objects/ui_MainWindow.h:795 +#: objects/ui_MainWindow.h:796 msgid "Ctrl+3" msgstr "" -#: objects/ui_MainWindow.h:796 +#: objects/ui_MainWindow.h:797 msgid "Animate" msgstr "Animovat" -#: objects/ui_MainWindow.h:797 +#: objects/ui_MainWindow.h:798 msgid "Top" msgstr "Shora" -#: objects/ui_MainWindow.h:798 +#: objects/ui_MainWindow.h:799 msgid "Ctrl+4" msgstr "" -#: objects/ui_MainWindow.h:799 +#: objects/ui_MainWindow.h:800 msgid "Bottom" msgstr "Zespoda" -#: objects/ui_MainWindow.h:800 +#: objects/ui_MainWindow.h:801 msgid "Ctrl+5" msgstr "" -#: objects/ui_MainWindow.h:801 +#: objects/ui_MainWindow.h:802 msgid "Left" msgstr "Zleva" -#: objects/ui_MainWindow.h:802 +#: objects/ui_MainWindow.h:803 msgid "Ctrl+6" msgstr "" -#: objects/ui_MainWindow.h:803 +#: objects/ui_MainWindow.h:804 msgid "Right" msgstr "Zprava" -#: objects/ui_MainWindow.h:804 +#: objects/ui_MainWindow.h:805 msgid "Ctrl+7" msgstr "" -#: objects/ui_MainWindow.h:805 +#: objects/ui_MainWindow.h:806 msgid "Front" msgstr "Zepředu" -#: objects/ui_MainWindow.h:806 +#: objects/ui_MainWindow.h:807 msgid "Ctrl+8" msgstr "" -#: objects/ui_MainWindow.h:807 +#: objects/ui_MainWindow.h:808 msgid "Back" msgstr "Zezadu" -#: objects/ui_MainWindow.h:808 +#: objects/ui_MainWindow.h:809 msgid "Ctrl+9" msgstr "" -#: objects/ui_MainWindow.h:809 +#: objects/ui_MainWindow.h:810 msgid "Diagonal" msgstr "Diagonálně" -#: objects/ui_MainWindow.h:810 +#: objects/ui_MainWindow.h:811 msgid "Ctrl+0" msgstr "" -#: objects/ui_MainWindow.h:811 +#: objects/ui_MainWindow.h:812 msgid "Center" msgstr "Vycentrovat" -#: objects/ui_MainWindow.h:812 +#: objects/ui_MainWindow.h:813 msgid "Perspective" msgstr "Perspektivně" -#: objects/ui_MainWindow.h:813 +#: objects/ui_MainWindow.h:814 msgid "Orthogonal" msgstr "Ortogonálně" -#: objects/ui_MainWindow.h:814 +#: objects/ui_MainWindow.h:815 msgid "Hide console" msgstr "Skrýt terminál" -#: objects/ui_MainWindow.h:815 +#: objects/ui_MainWindow.h:816 msgid "About" msgstr "O aplikaci" -#: objects/ui_MainWindow.h:816 +#: objects/ui_MainWindow.h:817 msgid "Documentation" msgstr "" -#: objects/ui_MainWindow.h:817 +#: objects/ui_MainWindow.h:818 msgid "Clear Recent" msgstr "Zapomenout nedávné" -#: objects/ui_MainWindow.h:818 +#: objects/ui_MainWindow.h:819 msgid "Export as DXF..." msgstr "Exportovat jako &DXF" -#: objects/ui_MainWindow.h:819 objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 msgid "Close" msgstr "Zavřít" -#: objects/ui_MainWindow.h:820 +#: objects/ui_MainWindow.h:821 msgid "Ctrl+W" msgstr "" -#: objects/ui_MainWindow.h:821 objects/ui_Preferences.h:609 +#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 msgid "Preferences" msgstr "Předvolby" -#: objects/ui_MainWindow.h:822 +#: objects/ui_MainWindow.h:823 msgid "Find..." msgstr "" -#: objects/ui_MainWindow.h:823 +#: objects/ui_MainWindow.h:824 msgid "Ctrl+F" msgstr "" -#: objects/ui_MainWindow.h:824 +#: objects/ui_MainWindow.h:825 msgid "Find and Replace..." msgstr "" -#: objects/ui_MainWindow.h:825 +#: objects/ui_MainWindow.h:826 msgid "Ctrl+Alt+F" msgstr "" -#: objects/ui_MainWindow.h:826 +#: objects/ui_MainWindow.h:827 msgid "Find Next" msgstr "" -#: objects/ui_MainWindow.h:827 +#: objects/ui_MainWindow.h:828 msgid "Ctrl+G" msgstr "" -#: objects/ui_MainWindow.h:828 +#: objects/ui_MainWindow.h:829 msgid "Find Previous" msgstr "" -#: objects/ui_MainWindow.h:829 +#: objects/ui_MainWindow.h:830 msgid "Ctrl+Shift+G" msgstr "" -#: objects/ui_MainWindow.h:830 +#: objects/ui_MainWindow.h:831 msgid "Use Selection for Find" msgstr "" -#: objects/ui_MainWindow.h:831 +#: objects/ui_MainWindow.h:832 msgid "Ctrl+E" msgstr "" -#: objects/ui_MainWindow.h:832 +#: objects/ui_MainWindow.h:833 msgid "Flush Caches" msgstr "Vyprázdnit mezipaměť" -#: objects/ui_MainWindow.h:833 +#: objects/ui_MainWindow.h:834 msgid "OpenSCAD Homepage" msgstr "Domovská stránka OpenSCADu" -#: objects/ui_MainWindow.h:834 +#: objects/ui_MainWindow.h:835 #, fuzzy msgid "Automatic Reload and Preview" msgstr "Automaticky načítat a kompilovat" -#: objects/ui_MainWindow.h:835 +#: objects/ui_MainWindow.h:836 msgid "Export as Image..." msgstr "Exportovat jako obrázek..." -#: objects/ui_MainWindow.h:836 +#: objects/ui_MainWindow.h:837 msgid "Export as CSG..." msgstr "Exportovat jako CSG..." -#: objects/ui_MainWindow.h:837 +#: objects/ui_MainWindow.h:838 msgid "Library info" msgstr "Informace o knihovnách" -#: objects/ui_MainWindow.h:838 +#: objects/ui_MainWindow.h:839 msgid "Check for Update.." msgstr "" -#: objects/ui_MainWindow.h:839 +#: objects/ui_MainWindow.h:840 msgid "Show Library Folder..." msgstr "" -#: objects/ui_MainWindow.h:840 +#: objects/ui_MainWindow.h:841 msgid "Reset View" msgstr "" -#: objects/ui_MainWindow.h:841 +#: objects/ui_MainWindow.h:842 #, fuzzy msgid "Font List" msgstr "Písmo" -#: objects/ui_MainWindow.h:842 +#: objects/ui_MainWindow.h:843 #, fuzzy msgid "Export as SVG..." msgstr "Exportovat jako CSG..." -#: objects/ui_MainWindow.h:843 +#: objects/ui_MainWindow.h:844 #, fuzzy msgid "Export as AMF..." msgstr "Exportovat jako &DXF" -#: objects/ui_MainWindow.h:845 +#: objects/ui_MainWindow.h:846 msgid "Ctrl+]" msgstr "" -#: objects/ui_MainWindow.h:847 +#: objects/ui_MainWindow.h:848 msgid "Ctrl+[" msgstr "" -#: objects/ui_MainWindow.h:848 +#: objects/ui_MainWindow.h:849 #, fuzzy msgid "View All" msgstr "&Zobrazit" -#: objects/ui_MainWindow.h:849 +#: objects/ui_MainWindow.h:850 msgid "Convert Tabs to Spaces" msgstr "" -#: objects/ui_MainWindow.h:850 +#: objects/ui_MainWindow.h:851 #, fuzzy msgid "Hide toolbars" msgstr "Skrýt editor" -#: objects/ui_MainWindow.h:851 +#: objects/ui_MainWindow.h:852 msgid "Time:" msgstr "Čas:" -#: objects/ui_MainWindow.h:852 +#: objects/ui_MainWindow.h:853 msgid "FPS:" msgstr "FPS:" -#: objects/ui_MainWindow.h:853 +#: objects/ui_MainWindow.h:854 msgid "Steps:" msgstr "Kroky:" -#: objects/ui_MainWindow.h:854 +#: objects/ui_MainWindow.h:855 msgid "Dump Pictures" msgstr "Ukládat obrázky" -#: objects/ui_MainWindow.h:855 +#: objects/ui_MainWindow.h:856 msgid "&File" msgstr "&Soubor" -#: objects/ui_MainWindow.h:856 +#: objects/ui_MainWindow.h:857 msgid "Recent Files" msgstr "" -#: objects/ui_MainWindow.h:857 objects/ui_launchingscreen.h:282 -#: objects/ui_launchingscreen.h:284 -msgid "Examples" -msgstr "Příklady" - -#: objects/ui_MainWindow.h:858 +#: objects/ui_MainWindow.h:859 msgid "Export" msgstr "" -#: objects/ui_MainWindow.h:859 +#: objects/ui_MainWindow.h:860 msgid "&Edit" msgstr "&Upravit" -#: objects/ui_MainWindow.h:860 +#: objects/ui_MainWindow.h:861 msgid "&Design" msgstr "&Design" -#: objects/ui_MainWindow.h:861 +#: objects/ui_MainWindow.h:862 msgid "&View" msgstr "&Zobrazit" -#: objects/ui_MainWindow.h:862 +#: objects/ui_MainWindow.h:863 msgid "&Help" msgstr "&Nápověda" -#: objects/ui_MainWindow.h:865 +#: objects/ui_MainWindow.h:866 msgid "Find" msgstr "" -#: objects/ui_MainWindow.h:866 objects/ui_MainWindow.h:873 +#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 msgid "Replace" msgstr "" -#: objects/ui_MainWindow.h:868 +#: objects/ui_MainWindow.h:869 msgid "Search string" msgstr "" -#: objects/ui_MainWindow.h:869 +#: objects/ui_MainWindow.h:870 msgid "<" msgstr "" -#: objects/ui_MainWindow.h:870 +#: objects/ui_MainWindow.h:871 msgid ">" msgstr "" -#: objects/ui_MainWindow.h:871 +#: objects/ui_MainWindow.h:872 msgid "Done" msgstr "" -#: objects/ui_MainWindow.h:872 +#: objects/ui_MainWindow.h:873 #, fuzzy msgid "Replacement string" msgstr "prvcích" -#: objects/ui_MainWindow.h:874 +#: objects/ui_MainWindow.h:875 msgid "All" msgstr "" @@ -650,181 +703,137 @@ msgstr "Povolit pro OpenGL 1.x" msgid "Show this message again" msgstr "" -#: objects/ui_Preferences.h:610 +#: objects/ui_Preferences.h:609 msgid "3D View" msgstr "3D zobrazení" -#: objects/ui_Preferences.h:611 src/UIUtils.cc:85 +#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 msgid "Advanced" msgstr "Pokročilé" -#: objects/ui_Preferences.h:612 src/mainwin.cc:2292 +#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 msgid "Editor" msgstr "Editor" -#: objects/ui_Preferences.h:613 +#: objects/ui_Preferences.h:612 msgid "Update" msgstr "" -#: objects/ui_Preferences.h:614 objects/ui_Preferences.h:661 +#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 msgid "Features" msgstr "" -#: objects/ui_Preferences.h:616 +#: objects/ui_Preferences.h:615 msgid "Enable/Disable experimental features" msgstr "" -#: objects/ui_Preferences.h:618 +#: objects/ui_Preferences.h:617 msgid "Color scheme:" msgstr "Barevné téma:" -#: objects/ui_Preferences.h:623 -msgid "Cornfield" -msgstr "Kukuřice" - -#: objects/ui_Preferences.h:625 -msgid "Metallic" -msgstr "Kov" - -#: objects/ui_Preferences.h:627 -msgid "Sunset" -msgstr "Západ slunce" - -#: objects/ui_Preferences.h:629 -msgid "Starnight" -msgstr "" - -#: objects/ui_Preferences.h:631 -msgid "BeforeDawn" -msgstr "" - -#: objects/ui_Preferences.h:633 -msgid "Nature" -msgstr "" - -#: objects/ui_Preferences.h:635 -msgid "DeepOcean" -msgstr "" - -#: objects/ui_Preferences.h:638 +#: objects/ui_Preferences.h:618 #, fuzzy msgid "Editor Type" msgstr "Editor" -#: objects/ui_Preferences.h:641 +#: objects/ui_Preferences.h:621 #, fuzzy msgid "Simple Editor" msgstr "Skrýt editor" -#: objects/ui_Preferences.h:642 +#: objects/ui_Preferences.h:622 msgid "QScintilla Editor" msgstr "" -#: objects/ui_Preferences.h:644 +#: objects/ui_Preferences.h:624 msgid "(requires restart)" msgstr "" -#: objects/ui_Preferences.h:645 +#: objects/ui_Preferences.h:625 msgid "Font" msgstr "Písmo" -#: objects/ui_Preferences.h:646 +#: objects/ui_Preferences.h:626 msgid "Color syntax highlighting" msgstr "" -#: objects/ui_Preferences.h:649 -msgid "For Light Background" -msgstr "" - -#: objects/ui_Preferences.h:650 -msgid "For Dark Background" -msgstr "" - -#: objects/ui_Preferences.h:651 -msgid "Monokai" -msgstr "" - -#: objects/ui_Preferences.h:652 -msgid "Solarized" -msgstr "" - -#: objects/ui_Preferences.h:653 -msgid "Off" -msgstr "" - -#: objects/ui_Preferences.h:655 +#: objects/ui_Preferences.h:627 msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" msgstr "" -#: objects/ui_Preferences.h:657 +#: objects/ui_Preferences.h:629 msgid "Automatically check for updates" msgstr "" -#: objects/ui_Preferences.h:658 +#: objects/ui_Preferences.h:630 msgid "Include development snapshots" msgstr "" -#: objects/ui_Preferences.h:659 +#: objects/ui_Preferences.h:631 msgid "Check Now" msgstr "" -#: objects/ui_Preferences.h:660 +#: objects/ui_Preferences.h:632 msgid "Last checked: " msgstr "" -#: objects/ui_Preferences.h:662 +#: objects/ui_Preferences.h:634 msgid "OpenCSG" msgstr "OpenCSG" -#: objects/ui_Preferences.h:663 +#: objects/ui_Preferences.h:635 msgid "Show capability warning" msgstr "Zobrazovat varování o vlastnostech" -#: objects/ui_Preferences.h:664 +#: objects/ui_Preferences.h:636 msgid "Enable for OpenGL 1.x" msgstr "Povolit pro OpenGL 1.x" -#: objects/ui_Preferences.h:665 +#: objects/ui_Preferences.h:637 msgid "Turn off rendering at " msgstr "Vypnout renderování při" -#: objects/ui_Preferences.h:666 +#: objects/ui_Preferences.h:638 msgid "elements" msgstr "prvcích" -#: objects/ui_Preferences.h:667 +#: objects/ui_Preferences.h:639 msgid "Force Goldfeather" msgstr "Vynutit Goldfeathera" -#: objects/ui_Preferences.h:668 +#: objects/ui_Preferences.h:640 msgid "CGAL Cache size" msgstr "Velikost CGAL cache" -#: objects/ui_Preferences.h:669 objects/ui_Preferences.h:671 +#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 msgid "bytes" msgstr "bytů" -#: objects/ui_Preferences.h:670 +#: objects/ui_Preferences.h:642 msgid "PolySet Cache size" msgstr "Velikost PolySet cache" -#: objects/ui_Preferences.h:672 +#: objects/ui_Preferences.h:644 msgid "Allow to open multiple documents" msgstr "" -#: objects/ui_Preferences.h:673 -msgid "Enable undocking of Editor and Console" +#: objects/ui_Preferences.h:645 +msgid "Enable docking of Editor and Console in different places" msgstr "" -#: objects/ui_Preferences.h:674 +#: objects/ui_Preferences.h:646 +msgid "Enable undocking of Editor and Console to separate windows" +msgstr "" + +#: objects/ui_Preferences.h:647 msgid "Show Welcome Screen" msgstr "" -#: objects/ui_Preferences.h:675 +#: objects/ui_Preferences.h:648 msgid "Enable user interface localization (requires restart of OpenSCAD)" msgstr "" -#: objects/ui_Preferences.h:676 +#: objects/ui_Preferences.h:649 msgid "toolBar" msgstr "" @@ -836,62 +845,88 @@ msgstr "" msgid "%v / %m" msgstr "" -#: objects/ui_launchingscreen.h:276 -msgid "Welcome to OpenSCAD" -msgstr "" - -#: objects/ui_launchingscreen.h:277 -#, fuzzy -msgid "New" -msgstr "&Nový" - -#: objects/ui_launchingscreen.h:278 -#, fuzzy -msgid "Open" -msgstr "OpenCSG" - -#: objects/ui_launchingscreen.h:279 -#, fuzzy -msgid "Help" -msgstr "&Nápověda" - -#: objects/ui_launchingscreen.h:280 -#, fuzzy -msgid "Recents" -msgstr "Nedávné soubory" - -#: objects/ui_launchingscreen.h:281 -msgid "Open Recent" -msgstr "Nedávné soubory" - -#: objects/ui_launchingscreen.h:285 -#, fuzzy -msgid "Open Example" -msgstr "Příklady" - -#: objects/ui_launchingscreen.h:287 -msgid "" -"\n" -"

OpenSCAD

\n" -"

The Programmers Solid 3D CAD Modeller

\n" -"\n" -"\n" -"\n" -msgstr "" - -#: objects/ui_launchingscreen.h:294 -msgid "Don't show again" -msgstr "" - #: src/AboutDialog.h:15 #, fuzzy msgid "About OpenSCAD " msgstr "Manuál k OpenSCADu (anglicky)" +#: src/mainwin.cc:773 src/mainwin.cc:1315 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1314 +msgid "Save File" +msgstr "" + +#: src/mainwin.cc:1316 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1326 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1654 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1655 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1966 src/mainwin.cc:2023 +#, fuzzy +msgid "Export %1 File" +msgstr "Exportovat STL soubor" + +#: src/mainwin.cc:1967 src/mainwin.cc:2027 +msgid "%1 Files (*%2)" +msgstr "" + +#: src/mainwin.cc:1968 +msgid "Untitled" +msgstr "" + +#: src/mainwin.cc:2025 +msgid "Untitled%1" +msgstr "" + +#: src/mainwin.cc:2076 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:2077 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:2078 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:2344 +msgid "Console" +msgstr "Terminál" + +#: src/mainwin.cc:2471 +msgid "The document has been modified." +msgstr "" + +#: src/mainwin.cc:2472 +msgid "Do you want to save your changes?" +msgstr "" + #: src/QGLView.cc:114 msgid "" "\n" @@ -946,82 +981,14 @@ msgstr "" msgid "Extrusion" msgstr "" -#: src/mainwin.cc:728 src/mainwin.cc:1269 -msgid "Untitled.scad" -msgstr "" +#~ msgid "Cornfield" +#~ msgstr "Kukuřice" -#: src/mainwin.cc:1268 -msgid "Save File" -msgstr "" +#~ msgid "Metallic" +#~ msgstr "Kov" -#: src/mainwin.cc:1270 -msgid "OpenSCAD Designs (*.scad)" -msgstr "" - -#: src/mainwin.cc:1280 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" - -#: src/mainwin.cc:1608 -msgid "Application" -msgstr "" - -#: src/mainwin.cc:1609 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" - -#: src/mainwin.cc:1907 src/mainwin.cc:1964 -#, fuzzy -msgid "Export %1 File" -msgstr "Exportovat STL soubor" - -#: src/mainwin.cc:1908 src/mainwin.cc:1968 -msgid "%1 Files (*%2)" -msgstr "" - -#: src/mainwin.cc:1909 -msgid "Untitled" -msgstr "" - -#: src/mainwin.cc:1966 -msgid "Untitled%1" -msgstr "" - -#: src/mainwin.cc:2017 -msgid "Export CSG File" -msgstr "" - -#: src/mainwin.cc:2018 -msgid "Untitled.csg" -msgstr "" - -#: src/mainwin.cc:2019 -msgid "CSG Files (*.csg)" -msgstr "" - -#: src/mainwin.cc:2045 -msgid "Export Image" -msgstr "" - -#: src/mainwin.cc:2045 -msgid "PNG Files (*.png)" -msgstr "" - -#: src/mainwin.cc:2297 -msgid "Console" -msgstr "Terminál" - -#: src/mainwin.cc:2420 -msgid "The document has been modified." -msgstr "" - -#: src/mainwin.cc:2421 -msgid "Do you want to save your changes?" -msgstr "" +#~ msgid "Sunset" +#~ msgstr "Západ slunce" #~ msgid "&Compile" #~ msgstr "Z&kompilovat" diff --git a/po/de.po b/locale/de.po similarity index 94% rename from po/de.po rename to locale/de.po index 96014e73..1e2d77e4 100644 --- a/po/de.po +++ b/locale/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2014.01.05\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-10-19 00:48+0200\n" +"POT-Creation-Date: 2014-11-13 00:22+0100\n" "PO-Revision-Date: 2014-10-21 00:00+0100\n" "Last-Translator: Torsten Paul \n" "Language-Team: German\n" @@ -64,6 +64,67 @@ msgstr "" "family:'Courier New,courier';\"> text(t = "OpenSCAD", font = " ""Liberation Sans:style=Italic");
" +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "Willkommen zu OpenSCAD" + +#: objects/ui_launchingscreen.h:277 +msgid "New" +msgstr "Neu" + +#: objects/ui_launchingscreen.h:278 +msgid "Open" +msgstr "Öffnen" + +#: objects/ui_launchingscreen.h:279 +msgid "Help" +msgstr "Hilfe" + +#: objects/ui_launchingscreen.h:280 +msgid "Recents" +msgstr "Zuletzt benutze Dateien" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "Datei öffnen" + +#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 +#: objects/ui_MainWindow.h:858 +msgid "Examples" +msgstr "Beispiele" + +#: objects/ui_launchingscreen.h:285 +msgid "Open Example" +msgstr "Beispiel öffnen" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "Dialog nicht wieder anzeigen" + #: objects/ui_LibraryInfoDialog.h:75 msgid "Lib & Build Info" msgstr "Lib & Build Info" @@ -72,552 +133,547 @@ msgstr "Lib & Build Info" msgid "OpenSCAD Detailed Library and Build Information" msgstr "" -#: objects/ui_MainWindow.h:732 +#: objects/ui_MainWindow.h:733 msgid "&New" msgstr "&Neu" -#: objects/ui_MainWindow.h:733 +#: objects/ui_MainWindow.h:734 msgid "Ctrl+N" msgstr "Ctrl+N" -#: objects/ui_MainWindow.h:734 +#: objects/ui_MainWindow.h:735 msgid "&Open..." msgstr "Ö&ffnen" -#: objects/ui_MainWindow.h:735 +#: objects/ui_MainWindow.h:736 msgid "Ctrl+O" msgstr "Ctrl+O" -#: objects/ui_MainWindow.h:736 +#: objects/ui_MainWindow.h:737 msgid "&Save" msgstr "&Speichern" -#: objects/ui_MainWindow.h:737 +#: objects/ui_MainWindow.h:738 msgid "Ctrl+S" msgstr "Ctrl+S" -#: objects/ui_MainWindow.h:738 +#: objects/ui_MainWindow.h:739 msgid "Save &As..." msgstr "Speichern &Unter..." -#: objects/ui_MainWindow.h:739 +#: objects/ui_MainWindow.h:740 msgid "Ctrl+Shift+S" msgstr "Ctrl+Shift+S" -#: objects/ui_MainWindow.h:740 +#: objects/ui_MainWindow.h:741 msgid "&Reload" msgstr "Neu &laden" -#: objects/ui_MainWindow.h:741 +#: objects/ui_MainWindow.h:742 msgid "Ctrl+R" msgstr "Ctrl+R" -#: objects/ui_MainWindow.h:742 +#: objects/ui_MainWindow.h:743 msgid "&Quit" msgstr "&Beenden" -#: objects/ui_MainWindow.h:743 +#: objects/ui_MainWindow.h:744 msgid "Ctrl+Q" msgstr "Ctrl+Q" -#: objects/ui_MainWindow.h:744 +#: objects/ui_MainWindow.h:745 msgid "&Undo" msgstr "&Rückgängig" -#: objects/ui_MainWindow.h:745 +#: objects/ui_MainWindow.h:746 msgid "Ctrl+Z" msgstr "Ctrl+Z" -#: objects/ui_MainWindow.h:746 +#: objects/ui_MainWindow.h:747 msgid "&Redo" msgstr "&Wiederholen" -#: objects/ui_MainWindow.h:747 +#: objects/ui_MainWindow.h:748 msgid "Ctrl+Shift+Z" msgstr "Ctrl+Shift+Z" -#: objects/ui_MainWindow.h:748 +#: objects/ui_MainWindow.h:749 msgid "Cu&t" msgstr "Ausschneiden" -#: objects/ui_MainWindow.h:749 +#: objects/ui_MainWindow.h:750 msgid "Ctrl+X" msgstr "Ctrl+X" -#: objects/ui_MainWindow.h:750 +#: objects/ui_MainWindow.h:751 msgid "&Copy" msgstr "Kopieren" -#: objects/ui_MainWindow.h:751 +#: objects/ui_MainWindow.h:752 msgid "Ctrl+C" msgstr "Ctrl+C" -#: objects/ui_MainWindow.h:752 +#: objects/ui_MainWindow.h:753 msgid "&Paste" msgstr "Einfügen" -#: objects/ui_MainWindow.h:753 +#: objects/ui_MainWindow.h:754 msgid "Ctrl+V" msgstr "Ctrl+V" -#: objects/ui_MainWindow.h:754 +#: objects/ui_MainWindow.h:755 msgid "&Indent" msgstr "Einzug erhöhen" -#: objects/ui_MainWindow.h:755 +#: objects/ui_MainWindow.h:756 msgid "Ctrl+I" msgstr "Ctrl+I" -#: objects/ui_MainWindow.h:756 +#: objects/ui_MainWindow.h:757 msgid "U&nindent" msgstr "Einzug vermindern" -#: objects/ui_MainWindow.h:757 +#: objects/ui_MainWindow.h:758 msgid "Ctrl+Shift+I" msgstr "Ctrl+Shift+I" -#: objects/ui_MainWindow.h:758 +#: objects/ui_MainWindow.h:759 msgid "C&omment" msgstr "K&ommentieren" -#: objects/ui_MainWindow.h:759 +#: objects/ui_MainWindow.h:760 msgid "Ctrl+D" msgstr "Ctrl+D" -#: objects/ui_MainWindow.h:760 +#: objects/ui_MainWindow.h:761 msgid "Unco&mment" msgstr "Kommentar entfernen" -#: objects/ui_MainWindow.h:761 +#: objects/ui_MainWindow.h:762 msgid "Ctrl+Shift+D" msgstr "Ctrl+Shift+D" -#: objects/ui_MainWindow.h:762 +#: objects/ui_MainWindow.h:763 msgid "Paste viewport translation" msgstr "Aktuelle Verschiebung einfügen" -#: objects/ui_MainWindow.h:763 +#: objects/ui_MainWindow.h:764 msgid "Ctrl+T" msgstr "Ctrl+T" -#: objects/ui_MainWindow.h:764 +#: objects/ui_MainWindow.h:765 msgid "Paste viewport rotation" msgstr "Aktuelle Rotation einfügen" -#: objects/ui_MainWindow.h:765 objects/ui_MainWindow.h:844 +#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 msgid "Zoom In" msgstr "Vergrößern" -#: objects/ui_MainWindow.h:766 +#: objects/ui_MainWindow.h:767 msgid "Ctrl++" msgstr "Ctrl++" -#: objects/ui_MainWindow.h:767 objects/ui_MainWindow.h:846 +#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 msgid "Zoom Out" msgstr "Verkleinern" -#: objects/ui_MainWindow.h:768 +#: objects/ui_MainWindow.h:769 msgid "Ctrl+-" msgstr "Ctrl+-" -#: objects/ui_MainWindow.h:769 +#: objects/ui_MainWindow.h:770 msgid "Hide editor" msgstr "Editor verstecken" -#: objects/ui_MainWindow.h:770 +#: objects/ui_MainWindow.h:771 msgid "&Reload and Preview" msgstr "Neu laden und Vorschau" -#: objects/ui_MainWindow.h:771 +#: objects/ui_MainWindow.h:772 msgid "F4" msgstr "F4" -#: objects/ui_MainWindow.h:772 +#: objects/ui_MainWindow.h:773 msgid "&Preview" msgstr "Vorschau" -#: objects/ui_MainWindow.h:773 +#: objects/ui_MainWindow.h:774 msgid "F5" msgstr "F5" -#: objects/ui_MainWindow.h:774 +#: objects/ui_MainWindow.h:775 msgid "&Render" msgstr "Rendern" -#: objects/ui_MainWindow.h:775 +#: objects/ui_MainWindow.h:776 msgid "F6" msgstr "F6" -#: objects/ui_MainWindow.h:776 +#: objects/ui_MainWindow.h:777 msgid "Check Validity" msgstr "Design überprüfen" -#: objects/ui_MainWindow.h:777 +#: objects/ui_MainWindow.h:778 msgid "Display &AST..." msgstr "&AST Baum anzeigen..." -#: objects/ui_MainWindow.h:778 +#: objects/ui_MainWindow.h:779 msgid "Display CSG &Tree..." msgstr "CSG Baum anzeigen..." -#: objects/ui_MainWindow.h:779 +#: objects/ui_MainWindow.h:780 msgid "Display CSG &Products..." msgstr "CSG Gleichungen anzeigen..." -#: objects/ui_MainWindow.h:780 +#: objects/ui_MainWindow.h:781 msgid "Export as &STL..." msgstr "&STL exportieren..." -#: objects/ui_MainWindow.h:781 +#: objects/ui_MainWindow.h:782 msgid "Export as &OFF..." msgstr "&OFF exportieren..." -#: objects/ui_MainWindow.h:782 +#: objects/ui_MainWindow.h:783 msgid "Preview" msgstr "Vorschau" -#: objects/ui_MainWindow.h:783 +#: objects/ui_MainWindow.h:784 msgid "F9" msgstr "F9" -#: objects/ui_MainWindow.h:784 +#: objects/ui_MainWindow.h:785 msgid "Surfaces" msgstr "Flächen anzeigen" -#: objects/ui_MainWindow.h:785 +#: objects/ui_MainWindow.h:786 msgid "F10" msgstr "F10" -#: objects/ui_MainWindow.h:786 +#: objects/ui_MainWindow.h:787 msgid "Wireframe" msgstr "Gittermodell" -#: objects/ui_MainWindow.h:787 +#: objects/ui_MainWindow.h:788 msgid "F11" msgstr "F11" -#: objects/ui_MainWindow.h:788 +#: objects/ui_MainWindow.h:789 msgid "Thrown Together" msgstr "Kombinierte Anzeige" -#: objects/ui_MainWindow.h:789 +#: objects/ui_MainWindow.h:790 msgid "F12" msgstr "F12" -#: objects/ui_MainWindow.h:790 +#: objects/ui_MainWindow.h:791 msgid "Show Edges" msgstr "Kanten anzeigen" -#: objects/ui_MainWindow.h:791 +#: objects/ui_MainWindow.h:792 msgid "Ctrl+1" msgstr "Ctrl+1" -#: objects/ui_MainWindow.h:792 +#: objects/ui_MainWindow.h:793 msgid "Show Axes" msgstr "Koordinatenachsen anzeigen" -#: objects/ui_MainWindow.h:793 +#: objects/ui_MainWindow.h:794 msgid "Ctrl+2" msgstr "Ctrl+2" -#: objects/ui_MainWindow.h:794 +#: objects/ui_MainWindow.h:795 msgid "Show Crosshairs" msgstr "Diagonalen anzeigen" -#: objects/ui_MainWindow.h:795 +#: objects/ui_MainWindow.h:796 msgid "Ctrl+3" msgstr "Ctrl+3" -#: objects/ui_MainWindow.h:796 +#: objects/ui_MainWindow.h:797 msgid "Animate" msgstr "Animation" -#: objects/ui_MainWindow.h:797 +#: objects/ui_MainWindow.h:798 msgid "Top" msgstr "Oben" -#: objects/ui_MainWindow.h:798 +#: objects/ui_MainWindow.h:799 msgid "Ctrl+4" msgstr "Ctrl+4" -#: objects/ui_MainWindow.h:799 +#: objects/ui_MainWindow.h:800 msgid "Bottom" msgstr "Unten" -#: objects/ui_MainWindow.h:800 +#: objects/ui_MainWindow.h:801 msgid "Ctrl+5" msgstr "Ctrl+5" -#: objects/ui_MainWindow.h:801 +#: objects/ui_MainWindow.h:802 msgid "Left" msgstr "Links" -#: objects/ui_MainWindow.h:802 +#: objects/ui_MainWindow.h:803 msgid "Ctrl+6" msgstr "Ctrl+6" -#: objects/ui_MainWindow.h:803 +#: objects/ui_MainWindow.h:804 msgid "Right" msgstr "Rechts" -#: objects/ui_MainWindow.h:804 +#: objects/ui_MainWindow.h:805 msgid "Ctrl+7" msgstr "Ctrl+7" -#: objects/ui_MainWindow.h:805 +#: objects/ui_MainWindow.h:806 msgid "Front" msgstr "Vorn" -#: objects/ui_MainWindow.h:806 +#: objects/ui_MainWindow.h:807 msgid "Ctrl+8" msgstr "Ctrl+8" -#: objects/ui_MainWindow.h:807 +#: objects/ui_MainWindow.h:808 msgid "Back" msgstr "Hinten" -#: objects/ui_MainWindow.h:808 +#: objects/ui_MainWindow.h:809 msgid "Ctrl+9" msgstr "Ctrl+9" -#: objects/ui_MainWindow.h:809 +#: objects/ui_MainWindow.h:810 msgid "Diagonal" msgstr "Diagonal" -#: objects/ui_MainWindow.h:810 +#: objects/ui_MainWindow.h:811 msgid "Ctrl+0" msgstr "Ctrl+0" -#: objects/ui_MainWindow.h:811 +#: objects/ui_MainWindow.h:812 msgid "Center" msgstr "Zentriert" -#: objects/ui_MainWindow.h:812 +#: objects/ui_MainWindow.h:813 msgid "Perspective" msgstr "Perspektivisch" -#: objects/ui_MainWindow.h:813 +#: objects/ui_MainWindow.h:814 msgid "Orthogonal" msgstr "Orthogonal" -#: objects/ui_MainWindow.h:814 +#: objects/ui_MainWindow.h:815 msgid "Hide console" msgstr "Konsole verstecken" -#: objects/ui_MainWindow.h:815 +#: objects/ui_MainWindow.h:816 msgid "About" msgstr "Über OpenSCAD" -#: objects/ui_MainWindow.h:816 +#: objects/ui_MainWindow.h:817 msgid "Documentation" msgstr "Dokumentation" -#: objects/ui_MainWindow.h:817 +#: objects/ui_MainWindow.h:818 msgid "Clear Recent" msgstr "Zuletzt benutze Dateien löschen" -#: objects/ui_MainWindow.h:818 +#: objects/ui_MainWindow.h:819 msgid "Export as DXF..." msgstr "DXF exportieren..." -#: objects/ui_MainWindow.h:819 objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 msgid "Close" msgstr "Schließen" -#: objects/ui_MainWindow.h:820 +#: objects/ui_MainWindow.h:821 msgid "Ctrl+W" msgstr "Ctrl+W" -#: objects/ui_MainWindow.h:821 objects/ui_Preferences.h:609 +#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 msgid "Preferences" msgstr "Einstellungen" -#: objects/ui_MainWindow.h:822 +#: objects/ui_MainWindow.h:823 msgid "Find..." msgstr "Suchen..." -#: objects/ui_MainWindow.h:823 +#: objects/ui_MainWindow.h:824 msgid "Ctrl+F" msgstr "Ctrl+F" -#: objects/ui_MainWindow.h:824 +#: objects/ui_MainWindow.h:825 msgid "Find and Replace..." msgstr "Suchen und Ersetzen..." -#: objects/ui_MainWindow.h:825 +#: objects/ui_MainWindow.h:826 msgid "Ctrl+Alt+F" msgstr "Ctrl+Alt+F" -#: objects/ui_MainWindow.h:826 +#: objects/ui_MainWindow.h:827 msgid "Find Next" msgstr "Weiter suchen" -#: objects/ui_MainWindow.h:827 +#: objects/ui_MainWindow.h:828 msgid "Ctrl+G" msgstr "Ctrl+G" -#: objects/ui_MainWindow.h:828 +#: objects/ui_MainWindow.h:829 msgid "Find Previous" msgstr "Rückwärts suchen" -#: objects/ui_MainWindow.h:829 +#: objects/ui_MainWindow.h:830 msgid "Ctrl+Shift+G" msgstr "Ctrl+Shift+G" -#: objects/ui_MainWindow.h:830 +#: objects/ui_MainWindow.h:831 msgid "Use Selection for Find" msgstr "Auswahl suchen" -#: objects/ui_MainWindow.h:831 +#: objects/ui_MainWindow.h:832 msgid "Ctrl+E" msgstr "Ctrl+E" -#: objects/ui_MainWindow.h:832 +#: objects/ui_MainWindow.h:833 msgid "Flush Caches" msgstr "Cache leeren" -#: objects/ui_MainWindow.h:833 +#: objects/ui_MainWindow.h:834 msgid "OpenSCAD Homepage" msgstr "OpenSCAD Homepage" -#: objects/ui_MainWindow.h:834 +#: objects/ui_MainWindow.h:835 msgid "Automatic Reload and Preview" msgstr "Automatisch neu Laden und Vorschau" -#: objects/ui_MainWindow.h:835 +#: objects/ui_MainWindow.h:836 msgid "Export as Image..." msgstr "Image exportieren..." -#: objects/ui_MainWindow.h:836 +#: objects/ui_MainWindow.h:837 msgid "Export as CSG..." msgstr "CSG exportieren..." -#: objects/ui_MainWindow.h:837 +#: objects/ui_MainWindow.h:838 msgid "Library info" msgstr "System Informationen" -#: objects/ui_MainWindow.h:838 +#: objects/ui_MainWindow.h:839 msgid "Check for Update.." msgstr "Neue Version suchen..." -#: objects/ui_MainWindow.h:839 +#: objects/ui_MainWindow.h:840 msgid "Show Library Folder..." msgstr "Bibliotheken anzeigen..." -#: objects/ui_MainWindow.h:840 +#: objects/ui_MainWindow.h:841 msgid "Reset View" msgstr "Ansicht zurücksetzen" -#: objects/ui_MainWindow.h:841 +#: objects/ui_MainWindow.h:842 msgid "Font List" msgstr "Font Liste" -#: objects/ui_MainWindow.h:842 +#: objects/ui_MainWindow.h:843 msgid "Export as SVG..." msgstr "SVG exportieren..." -#: objects/ui_MainWindow.h:843 +#: objects/ui_MainWindow.h:844 msgid "Export as AMF..." msgstr "AMF exportieren..." -#: objects/ui_MainWindow.h:845 +#: objects/ui_MainWindow.h:846 msgid "Ctrl+]" msgstr "Ctrl+]" -#: objects/ui_MainWindow.h:847 +#: objects/ui_MainWindow.h:848 msgid "Ctrl+[" msgstr "Ctrl+[" -#: objects/ui_MainWindow.h:848 +#: objects/ui_MainWindow.h:849 msgid "View All" msgstr "Alles anzeigen" -#: objects/ui_MainWindow.h:849 +#: objects/ui_MainWindow.h:850 msgid "Convert Tabs to Spaces" msgstr "Tabs in Leerzeichen konvertieren" -#: objects/ui_MainWindow.h:850 +#: objects/ui_MainWindow.h:851 msgid "Hide toolbars" msgstr "Symbolleisten verstecken" -#: objects/ui_MainWindow.h:851 +#: objects/ui_MainWindow.h:852 msgid "Time:" msgstr "Zeit:" -#: objects/ui_MainWindow.h:852 +#: objects/ui_MainWindow.h:853 msgid "FPS:" msgstr "FPS:" -#: objects/ui_MainWindow.h:853 +#: objects/ui_MainWindow.h:854 msgid "Steps:" msgstr "Schritte:" -#: objects/ui_MainWindow.h:854 +#: objects/ui_MainWindow.h:855 msgid "Dump Pictures" msgstr "Bilder ausgeben" -#: objects/ui_MainWindow.h:855 +#: objects/ui_MainWindow.h:856 msgid "&File" msgstr "&Datei" -#: objects/ui_MainWindow.h:856 +#: objects/ui_MainWindow.h:857 msgid "Recent Files" msgstr "Zuletzt benutze Dateien" -#: objects/ui_MainWindow.h:857 objects/ui_launchingscreen.h:282 -#: objects/ui_launchingscreen.h:284 -msgid "Examples" -msgstr "Beispiele" - -#: objects/ui_MainWindow.h:858 +#: objects/ui_MainWindow.h:859 msgid "Export" msgstr "Exportieren" -#: objects/ui_MainWindow.h:859 +#: objects/ui_MainWindow.h:860 msgid "&Edit" msgstr "&Bearbeiten" -#: objects/ui_MainWindow.h:860 +#: objects/ui_MainWindow.h:861 msgid "&Design" msgstr "D&esign" -#: objects/ui_MainWindow.h:861 +#: objects/ui_MainWindow.h:862 msgid "&View" msgstr "&Ansicht" -#: objects/ui_MainWindow.h:862 +#: objects/ui_MainWindow.h:863 msgid "&Help" msgstr "&Hilfe" -#: objects/ui_MainWindow.h:865 +#: objects/ui_MainWindow.h:866 msgid "Find" msgstr "Suchen" -#: objects/ui_MainWindow.h:866 objects/ui_MainWindow.h:873 +#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 msgid "Replace" msgstr "Ersetzen" -#: objects/ui_MainWindow.h:868 +#: objects/ui_MainWindow.h:869 msgid "Search string" msgstr "Suchtext" -#: objects/ui_MainWindow.h:869 +#: objects/ui_MainWindow.h:870 msgid "<" msgstr "<" -#: objects/ui_MainWindow.h:870 +#: objects/ui_MainWindow.h:871 msgid ">" msgstr ">" -#: objects/ui_MainWindow.h:871 +#: objects/ui_MainWindow.h:872 msgid "Done" msgstr "Fertig" -#: objects/ui_MainWindow.h:872 +#: objects/ui_MainWindow.h:873 msgid "Replacement string" msgstr "Ersetzen mit" -#: objects/ui_MainWindow.h:874 +#: objects/ui_MainWindow.h:875 msgid "All" msgstr "Alles" @@ -657,180 +713,138 @@ msgstr "OpenCSG benutzen" msgid "Show this message again" msgstr "Diesen Dialog wieder anzeigen" -#: objects/ui_Preferences.h:610 +#: objects/ui_Preferences.h:609 msgid "3D View" msgstr "3D Ansicht" -#: objects/ui_Preferences.h:611 src/UIUtils.cc:85 +#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 msgid "Advanced" msgstr "Erweitert" -#: objects/ui_Preferences.h:612 src/mainwin.cc:2292 +#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 msgid "Editor" msgstr "Editor" -#: objects/ui_Preferences.h:613 +#: objects/ui_Preferences.h:612 msgid "Update" msgstr "Aktualisieren" -#: objects/ui_Preferences.h:614 objects/ui_Preferences.h:661 +#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 msgid "Features" msgstr "Funktionen" -#: objects/ui_Preferences.h:616 +#: objects/ui_Preferences.h:615 msgid "Enable/Disable experimental features" msgstr "Experimentelle Erweiterungen ein-/ausschalten" -#: objects/ui_Preferences.h:618 +#: objects/ui_Preferences.h:617 msgid "Color scheme:" msgstr "Farbschema:" -#: objects/ui_Preferences.h:623 -msgid "Cornfield" -msgstr "Cornfield" - -#: objects/ui_Preferences.h:625 -msgid "Metallic" -msgstr "Metallic" - -#: objects/ui_Preferences.h:627 -msgid "Sunset" -msgstr "Sunset" - -#: objects/ui_Preferences.h:629 -msgid "Starnight" -msgstr "Starnight" - -#: objects/ui_Preferences.h:631 -msgid "BeforeDawn" -msgstr "BeforeDawn" - -#: objects/ui_Preferences.h:633 -msgid "Nature" -msgstr "Nature" - -#: objects/ui_Preferences.h:635 -msgid "DeepOcean" -msgstr "DeepOcean" - -#: objects/ui_Preferences.h:638 +#: objects/ui_Preferences.h:618 msgid "Editor Type" msgstr "Editor" -#: objects/ui_Preferences.h:641 +#: objects/ui_Preferences.h:621 msgid "Simple Editor" msgstr "Einfacher Editor" -#: objects/ui_Preferences.h:642 +#: objects/ui_Preferences.h:622 msgid "QScintilla Editor" msgstr "QScintilla Editor" -#: objects/ui_Preferences.h:644 +#: objects/ui_Preferences.h:624 msgid "(requires restart)" msgstr "(Neustart erforderlich)" -#: objects/ui_Preferences.h:645 +#: objects/ui_Preferences.h:625 msgid "Font" msgstr "Font" -#: objects/ui_Preferences.h:646 +#: objects/ui_Preferences.h:626 msgid "Color syntax highlighting" msgstr "Syntaxhervorhebung" -#: objects/ui_Preferences.h:649 -msgid "For Light Background" -msgstr "Für hellen Hintergrund" - -#: objects/ui_Preferences.h:650 -msgid "For Dark Background" -msgstr "Für dunklen Hintergrund" - -#: objects/ui_Preferences.h:651 -msgid "Monokai" -msgstr "Monokai" - -#: objects/ui_Preferences.h:652 -msgid "Solarized" -msgstr "Solarized" - -#: objects/ui_Preferences.h:653 -msgid "Off" -msgstr "Aus" - -#: objects/ui_Preferences.h:655 +#: objects/ui_Preferences.h:627 msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" msgstr "Ctrl/Cmd+Mausrad zum Vergrößern des Textes benutzen" -#: objects/ui_Preferences.h:657 +#: objects/ui_Preferences.h:629 msgid "Automatically check for updates" msgstr "Automatisch nach Aktualisierungen suchen" -#: objects/ui_Preferences.h:658 +#: objects/ui_Preferences.h:630 msgid "Include development snapshots" msgstr "Entwickler-Versionen einschließen" -#: objects/ui_Preferences.h:659 +#: objects/ui_Preferences.h:631 msgid "Check Now" msgstr "Jetzt suchen" -#: objects/ui_Preferences.h:660 +#: objects/ui_Preferences.h:632 msgid "Last checked: " msgstr "Zuletzt gesucht: " -#: objects/ui_Preferences.h:662 +#: objects/ui_Preferences.h:634 msgid "OpenCSG" msgstr "OpenCSG" -#: objects/ui_Preferences.h:663 +#: objects/ui_Preferences.h:635 msgid "Show capability warning" msgstr "Kompatibilitätswarnung anzeigen" -#: objects/ui_Preferences.h:664 +#: objects/ui_Preferences.h:636 msgid "Enable for OpenGL 1.x" msgstr "Aktivieren bei OpenGL 1.x" -#: objects/ui_Preferences.h:665 +#: objects/ui_Preferences.h:637 msgid "Turn off rendering at " msgstr "Rendern abbrechen ab " -#: objects/ui_Preferences.h:666 +#: objects/ui_Preferences.h:638 msgid "elements" msgstr "Elementen" -#: objects/ui_Preferences.h:667 +#: objects/ui_Preferences.h:639 msgid "Force Goldfeather" msgstr "Goldfeather Algorithmus erzwingen" -#: objects/ui_Preferences.h:668 +#: objects/ui_Preferences.h:640 msgid "CGAL Cache size" msgstr "CGAL Cache Größe" -#: objects/ui_Preferences.h:669 objects/ui_Preferences.h:671 +#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 msgid "bytes" msgstr "Byte" -#: objects/ui_Preferences.h:670 +#: objects/ui_Preferences.h:642 msgid "PolySet Cache size" msgstr "PolySet Cache Größe" -#: objects/ui_Preferences.h:672 +#: objects/ui_Preferences.h:644 msgid "Allow to open multiple documents" msgstr "Öffnen von mehreren Dokumenten erlauben" -#: objects/ui_Preferences.h:673 -msgid "Enable undocking of Editor and Console" +#: objects/ui_Preferences.h:645 +#, fuzzy +msgid "Enable docking of Editor and Console in different places" msgstr "Separate Editor und Konsole Fenster erlauben" -#: objects/ui_Preferences.h:674 +#: objects/ui_Preferences.h:646 +#, fuzzy +msgid "Enable undocking of Editor and Console to separate windows" +msgstr "Separate Editor und Konsole Fenster erlauben" + +#: objects/ui_Preferences.h:647 msgid "Show Welcome Screen" msgstr "Startbildschirm anzeigen" -#: objects/ui_Preferences.h:675 +#: objects/ui_Preferences.h:648 msgid "Enable user interface localization (requires restart of OpenSCAD)" msgstr "Lokalisierung der GUI einschalten (benötigt Neustart von OpenSCAD)" # This should not be visible (window title of the ToolBar). -#: objects/ui_Preferences.h:676 +#: objects/ui_Preferences.h:649 msgid "toolBar" msgstr "toolBar" @@ -842,66 +856,90 @@ msgstr "Form" msgid "%v / %m" msgstr "%v / %m" -#: objects/ui_launchingscreen.h:276 -msgid "Welcome to OpenSCAD" -msgstr "Willkommen zu OpenSCAD" - -#: objects/ui_launchingscreen.h:277 -msgid "New" -msgstr "Neu" - -#: objects/ui_launchingscreen.h:278 -msgid "Open" -msgstr "Öffnen" - -#: objects/ui_launchingscreen.h:279 -msgid "Help" -msgstr "Hilfe" - -#: objects/ui_launchingscreen.h:280 -msgid "Recents" -msgstr "Zuletzt benutze Dateien" - -#: objects/ui_launchingscreen.h:281 -msgid "Open Recent" -msgstr "Datei öffnen" - -#: objects/ui_launchingscreen.h:285 -msgid "Open Example" -msgstr "Beispiel öffnen" - -#: objects/ui_launchingscreen.h:287 -msgid "" -"\n" -"

OpenSCAD

\n" -"

The Programmers Solid 3D CAD Modeller

\n" -"\n" -"\n" -"\n" -msgstr "" -"\n" -"

OpenSCAD

\n" -"

The Programmers Solid 3D CAD Modeller

\n" -"\n" -"\n" -"\n" - -#: objects/ui_launchingscreen.h:294 -msgid "Don't show again" -msgstr "Dialog nicht wieder anzeigen" - #: src/AboutDialog.h:15 msgid "About OpenSCAD " msgstr "Über OpenSCAD" +#: src/mainwin.cc:773 src/mainwin.cc:1315 +msgid "Untitled.scad" +msgstr "Unbenannt.scad" + +#: src/mainwin.cc:1314 +msgid "Save File" +msgstr "Save File" + +#: src/mainwin.cc:1316 +msgid "OpenSCAD Designs (*.scad)" +msgstr "OpenSCAD Designs (*.scad)" + +#: src/mainwin.cc:1326 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" +"%1 existiert bereits.\n" +"Mochten Sie die Datei ersetzen?" + +#: src/mainwin.cc:1654 +msgid "Application" +msgstr "Application" + +#: src/mainwin.cc:1655 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" +"Das Dokument ist verändert.\n" +"Möchten Sie die Datei wirklich neu laden?" + +#: src/mainwin.cc:1966 src/mainwin.cc:2023 +msgid "Export %1 File" +msgstr "%1 Datei exportieren" + +#: src/mainwin.cc:1967 src/mainwin.cc:2027 +msgid "%1 Files (*%2)" +msgstr "%1 Dateien (*%2)" + +#: src/mainwin.cc:1968 +msgid "Untitled" +msgstr "Unbenannt" + +#: src/mainwin.cc:2025 +msgid "Untitled%1" +msgstr "Unbenannt%1" + +#: src/mainwin.cc:2076 +msgid "Export CSG File" +msgstr "Export CSG File" + +#: src/mainwin.cc:2077 +msgid "Untitled.csg" +msgstr "Unbenannt.csg" + +#: src/mainwin.cc:2078 +msgid "CSG Files (*.csg)" +msgstr "CSG Dateien (*.csg)" + +#: src/mainwin.cc:2104 +msgid "Export Image" +msgstr "Image exportieren" + +#: src/mainwin.cc:2104 +msgid "PNG Files (*.png)" +msgstr "PNG Dateien (*.png)" + +#: src/mainwin.cc:2344 +msgid "Console" +msgstr "Konsole" + +#: src/mainwin.cc:2471 +msgid "The document has been modified." +msgstr "Das Dokument ist verändert." + +#: src/mainwin.cc:2472 +msgid "Do you want to save your changes?" +msgstr "Möchten Sie die Änderungen speichern?" + #: src/QGLView.cc:114 msgid "" "\n" @@ -961,85 +999,41 @@ msgstr "Formen" msgid "Extrusion" msgstr "Extrusion" -#: src/mainwin.cc:728 src/mainwin.cc:1269 -msgid "Untitled.scad" -msgstr "Unbenannt.scad" +#~ msgid "Cornfield" +#~ msgstr "Cornfield" -#: src/mainwin.cc:1268 -msgid "Save File" -msgstr "Save File" +#~ msgid "Metallic" +#~ msgstr "Metallic" -#: src/mainwin.cc:1270 -msgid "OpenSCAD Designs (*.scad)" -msgstr "OpenSCAD Designs (*.scad)" +#~ msgid "Sunset" +#~ msgstr "Sunset" -#: src/mainwin.cc:1280 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" -"%1 existiert bereits.\n" -"Mochten Sie die Datei ersetzen?" +#~ msgid "Starnight" +#~ msgstr "Starnight" -#: src/mainwin.cc:1608 -msgid "Application" -msgstr "Application" +#~ msgid "BeforeDawn" +#~ msgstr "BeforeDawn" -#: src/mainwin.cc:1609 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" -"Das Dokument ist verändert.\n" -"Möchten Sie die Datei wirklich neu laden?" +#~ msgid "Nature" +#~ msgstr "Nature" -#: src/mainwin.cc:1907 src/mainwin.cc:1964 -msgid "Export %1 File" -msgstr "%1 Datei exportieren" +#~ msgid "DeepOcean" +#~ msgstr "DeepOcean" -#: src/mainwin.cc:1908 src/mainwin.cc:1968 -msgid "%1 Files (*%2)" -msgstr "%1 Dateien (*%2)" +#~ msgid "For Light Background" +#~ msgstr "Für hellen Hintergrund" -#: src/mainwin.cc:1909 -msgid "Untitled" -msgstr "Unbenannt" +#~ msgid "For Dark Background" +#~ msgstr "Für dunklen Hintergrund" -#: src/mainwin.cc:1966 -msgid "Untitled%1" -msgstr "Unbenannt%1" +#~ msgid "Monokai" +#~ msgstr "Monokai" -#: src/mainwin.cc:2017 -msgid "Export CSG File" -msgstr "Export CSG File" +#~ msgid "Solarized" +#~ msgstr "Solarized" -#: src/mainwin.cc:2018 -msgid "Untitled.csg" -msgstr "Unbenannt.csg" - -#: src/mainwin.cc:2019 -msgid "CSG Files (*.csg)" -msgstr "CSG Dateien (*.csg)" - -#: src/mainwin.cc:2045 -msgid "Export Image" -msgstr "Image exportieren" - -#: src/mainwin.cc:2045 -msgid "PNG Files (*.png)" -msgstr "PNG Dateien (*.png)" - -#: src/mainwin.cc:2297 -msgid "Console" -msgstr "Konsole" - -#: src/mainwin.cc:2420 -msgid "The document has been modified." -msgstr "Das Dokument ist verändert." - -#: src/mainwin.cc:2421 -msgid "Do you want to save your changes?" -msgstr "Möchten Sie die Änderungen speichern?" +#~ msgid "Off" +#~ msgstr "Aus" #~ msgid "MainWindow" #~ msgstr "MainWindow" diff --git a/locale/fr.po b/locale/fr.po new file mode 100644 index 00000000..d9722b2a --- /dev/null +++ b/locale/fr.po @@ -0,0 +1,971 @@ +# French translations for OpenSCAD package. +# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER +# This file is distributed under the same license as the OpenSCAD package. +# don , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2013.02.07\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-13 00:22+0100\n" +"PO-Revision-Date: 2013-02-08 15:06-0600\n" +"Last-Translator: don bright \n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "" + +#: objects/ui_FontListDialog.h:102 +msgid "OpenSCAD Font List" +msgstr "" + +#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 +msgid "&OK" +msgstr "" + +#: objects/ui_FontListDialog.h:105 +msgid "Paste font selector to Editor Window" +msgstr "" + +#: objects/ui_FontListDialog.h:107 +msgid "Copy to Clipboard" +msgstr "" + +#: objects/ui_FontListDialog.h:108 +msgid "Filter:" +msgstr "" + +#: objects/ui_FontListDialog.h:109 +msgid "" +"

This list shows the fonts currently registered with " +"OpenSCAD.

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" +msgstr "" + +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "" + +#: objects/ui_launchingscreen.h:277 +#, fuzzy +msgid "New" +msgstr "&Nouveau" + +#: objects/ui_launchingscreen.h:278 +#, fuzzy +msgid "Open" +msgstr "&Ouvrir..." + +#: objects/ui_launchingscreen.h:279 +#, fuzzy +msgid "Help" +msgstr "&Aide" + +#: objects/ui_launchingscreen.h:280 +#, fuzzy +msgid "Recents" +msgstr "Ouvrir un fichier" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "" + +#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 +#: objects/ui_MainWindow.h:858 +msgid "Examples" +msgstr "&Exemples" + +#: objects/ui_launchingscreen.h:285 +#, fuzzy +msgid "Open Example" +msgstr "&Exemples" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "" + +#: objects/ui_LibraryInfoDialog.h:75 +msgid "Lib & Build Info" +msgstr "" + +#: objects/ui_LibraryInfoDialog.h:76 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "" + +#: objects/ui_MainWindow.h:733 +msgid "&New" +msgstr "&Nouveau" + +#: objects/ui_MainWindow.h:734 +msgid "Ctrl+N" +msgstr "" + +#: objects/ui_MainWindow.h:735 +msgid "&Open..." +msgstr "&Ouvrir..." + +#: objects/ui_MainWindow.h:736 +msgid "Ctrl+O" +msgstr "" + +#: objects/ui_MainWindow.h:737 +msgid "&Save" +msgstr "Enregi&strer" + +#: objects/ui_MainWindow.h:738 +msgid "Ctrl+S" +msgstr "" + +#: objects/ui_MainWindow.h:739 +msgid "Save &As..." +msgstr "Enregistrer &sous..." + +#: objects/ui_MainWindow.h:740 +msgid "Ctrl+Shift+S" +msgstr "" + +#: objects/ui_MainWindow.h:741 +msgid "&Reload" +msgstr "&Recharger" + +#: objects/ui_MainWindow.h:742 +msgid "Ctrl+R" +msgstr "" + +#: objects/ui_MainWindow.h:743 +msgid "&Quit" +msgstr "&Quitter" + +#: objects/ui_MainWindow.h:744 +msgid "Ctrl+Q" +msgstr "" + +#: objects/ui_MainWindow.h:745 +msgid "&Undo" +msgstr "Ann&uler" + +#: objects/ui_MainWindow.h:746 +msgid "Ctrl+Z" +msgstr "" + +#: objects/ui_MainWindow.h:747 +msgid "&Redo" +msgstr "&Refaire" + +#: objects/ui_MainWindow.h:748 +msgid "Ctrl+Shift+Z" +msgstr "" + +#: objects/ui_MainWindow.h:749 +msgid "Cu&t" +msgstr "Co&uper" + +#: objects/ui_MainWindow.h:750 +msgid "Ctrl+X" +msgstr "" + +#: objects/ui_MainWindow.h:751 +msgid "&Copy" +msgstr "&Copier" + +#: objects/ui_MainWindow.h:752 +msgid "Ctrl+C" +msgstr "" + +#: objects/ui_MainWindow.h:753 +msgid "&Paste" +msgstr "&Coller" + +#: objects/ui_MainWindow.h:754 +msgid "Ctrl+V" +msgstr "" + +#: objects/ui_MainWindow.h:755 +msgid "&Indent" +msgstr "&Indenter" + +#: objects/ui_MainWindow.h:756 +msgid "Ctrl+I" +msgstr "" + +#: objects/ui_MainWindow.h:757 +msgid "U&nindent" +msgstr "Dési&ndenter" + +#: objects/ui_MainWindow.h:758 +msgid "Ctrl+Shift+I" +msgstr "" + +#: objects/ui_MainWindow.h:759 +msgid "C&omment" +msgstr "" + +#: objects/ui_MainWindow.h:760 +msgid "Ctrl+D" +msgstr "" + +#: objects/ui_MainWindow.h:761 +msgid "Unco&mment" +msgstr "" + +#: objects/ui_MainWindow.h:762 +msgid "Ctrl+Shift+D" +msgstr "" + +#: objects/ui_MainWindow.h:763 +msgid "Paste viewport translation" +msgstr "" + +#: objects/ui_MainWindow.h:764 +msgid "Ctrl+T" +msgstr "" + +#: objects/ui_MainWindow.h:765 +msgid "Paste viewport rotation" +msgstr "" + +#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 +msgid "Zoom In" +msgstr "Zoom Avant" + +#: objects/ui_MainWindow.h:767 +msgid "Ctrl++" +msgstr "" + +#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 +msgid "Zoom Out" +msgstr "Zoom Arrière" + +#: objects/ui_MainWindow.h:769 +msgid "Ctrl+-" +msgstr "" + +#: objects/ui_MainWindow.h:770 +msgid "Hide editor" +msgstr "" + +#: objects/ui_MainWindow.h:771 +msgid "&Reload and Preview" +msgstr "" + +#: objects/ui_MainWindow.h:772 +msgid "F4" +msgstr "" + +#: objects/ui_MainWindow.h:773 +msgid "&Preview" +msgstr "" + +#: objects/ui_MainWindow.h:774 +msgid "F5" +msgstr "" + +#: objects/ui_MainWindow.h:775 +msgid "&Render" +msgstr "" + +#: objects/ui_MainWindow.h:776 +msgid "F6" +msgstr "" + +#: objects/ui_MainWindow.h:777 +msgid "Check Validity" +msgstr "" + +#: objects/ui_MainWindow.h:778 +msgid "Display &AST..." +msgstr "" + +#: objects/ui_MainWindow.h:779 +msgid "Display CSG &Tree..." +msgstr "" + +#: objects/ui_MainWindow.h:780 +msgid "Display CSG &Products..." +msgstr "" + +#: objects/ui_MainWindow.h:781 +msgid "Export as &STL..." +msgstr "" + +#: objects/ui_MainWindow.h:782 +msgid "Export as &OFF..." +msgstr "" + +#: objects/ui_MainWindow.h:783 +msgid "Preview" +msgstr "" + +#: objects/ui_MainWindow.h:784 +msgid "F9" +msgstr "" + +#: objects/ui_MainWindow.h:785 +msgid "Surfaces" +msgstr "" + +#: objects/ui_MainWindow.h:786 +msgid "F10" +msgstr "" + +#: objects/ui_MainWindow.h:787 +msgid "Wireframe" +msgstr "" + +#: objects/ui_MainWindow.h:788 +msgid "F11" +msgstr "" + +#: objects/ui_MainWindow.h:789 +msgid "Thrown Together" +msgstr "" + +#: objects/ui_MainWindow.h:790 +msgid "F12" +msgstr "" + +#: objects/ui_MainWindow.h:791 +msgid "Show Edges" +msgstr "" + +#: objects/ui_MainWindow.h:792 +msgid "Ctrl+1" +msgstr "" + +#: objects/ui_MainWindow.h:793 +msgid "Show Axes" +msgstr "Afficher les axes" + +#: objects/ui_MainWindow.h:794 +msgid "Ctrl+2" +msgstr "" + +#: objects/ui_MainWindow.h:795 +msgid "Show Crosshairs" +msgstr "" + +#: objects/ui_MainWindow.h:796 +msgid "Ctrl+3" +msgstr "" + +#: objects/ui_MainWindow.h:797 +msgid "Animate" +msgstr "" + +#: objects/ui_MainWindow.h:798 +msgid "Top" +msgstr "Dessus" + +#: objects/ui_MainWindow.h:799 +msgid "Ctrl+4" +msgstr "" + +#: objects/ui_MainWindow.h:800 +msgid "Bottom" +msgstr "Dessous" + +#: objects/ui_MainWindow.h:801 +msgid "Ctrl+5" +msgstr "" + +#: objects/ui_MainWindow.h:802 +msgid "Left" +msgstr "Gauche" + +#: objects/ui_MainWindow.h:803 +msgid "Ctrl+6" +msgstr "" + +#: objects/ui_MainWindow.h:804 +msgid "Right" +msgstr "Droite" + +#: objects/ui_MainWindow.h:805 +msgid "Ctrl+7" +msgstr "" + +#: objects/ui_MainWindow.h:806 +msgid "Front" +msgstr "Face" + +#: objects/ui_MainWindow.h:807 +msgid "Ctrl+8" +msgstr "" + +#: objects/ui_MainWindow.h:808 +msgid "Back" +msgstr "Arrière" + +#: objects/ui_MainWindow.h:809 +msgid "Ctrl+9" +msgstr "" + +#: objects/ui_MainWindow.h:810 +msgid "Diagonal" +msgstr "" + +#: objects/ui_MainWindow.h:811 +msgid "Ctrl+0" +msgstr "" + +#: objects/ui_MainWindow.h:812 +msgid "Center" +msgstr "" + +#: objects/ui_MainWindow.h:813 +msgid "Perspective" +msgstr "" + +#: objects/ui_MainWindow.h:814 +msgid "Orthogonal" +msgstr "" + +#: objects/ui_MainWindow.h:815 +msgid "Hide console" +msgstr "" + +#: objects/ui_MainWindow.h:816 +msgid "About" +msgstr "À propos" + +#: objects/ui_MainWindow.h:817 +msgid "Documentation" +msgstr "" + +#: objects/ui_MainWindow.h:818 +msgid "Clear Recent" +msgstr "" + +#: objects/ui_MainWindow.h:819 +msgid "Export as DXF..." +msgstr "" + +#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "Fermer" + +#: objects/ui_MainWindow.h:821 +msgid "Ctrl+W" +msgstr "" + +#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 +msgid "Preferences" +msgstr "Préférences" + +#: objects/ui_MainWindow.h:823 +msgid "Find..." +msgstr "" + +#: objects/ui_MainWindow.h:824 +msgid "Ctrl+F" +msgstr "" + +#: objects/ui_MainWindow.h:825 +msgid "Find and Replace..." +msgstr "" + +#: objects/ui_MainWindow.h:826 +msgid "Ctrl+Alt+F" +msgstr "" + +#: objects/ui_MainWindow.h:827 +msgid "Find Next" +msgstr "" + +#: objects/ui_MainWindow.h:828 +msgid "Ctrl+G" +msgstr "" + +#: objects/ui_MainWindow.h:829 +msgid "Find Previous" +msgstr "" + +#: objects/ui_MainWindow.h:830 +msgid "Ctrl+Shift+G" +msgstr "" + +#: objects/ui_MainWindow.h:831 +msgid "Use Selection for Find" +msgstr "" + +#: objects/ui_MainWindow.h:832 +msgid "Ctrl+E" +msgstr "" + +#: objects/ui_MainWindow.h:833 +msgid "Flush Caches" +msgstr "" + +#: objects/ui_MainWindow.h:834 +msgid "OpenSCAD Homepage" +msgstr "" + +#: objects/ui_MainWindow.h:835 +msgid "Automatic Reload and Preview" +msgstr "" + +#: objects/ui_MainWindow.h:836 +msgid "Export as Image..." +msgstr "" + +#: objects/ui_MainWindow.h:837 +msgid "Export as CSG..." +msgstr "" + +#: objects/ui_MainWindow.h:838 +msgid "Library info" +msgstr "" + +#: objects/ui_MainWindow.h:839 +msgid "Check for Update.." +msgstr "" + +#: objects/ui_MainWindow.h:840 +msgid "Show Library Folder..." +msgstr "" + +#: objects/ui_MainWindow.h:841 +msgid "Reset View" +msgstr "" + +#: objects/ui_MainWindow.h:842 +msgid "Font List" +msgstr "" + +#: objects/ui_MainWindow.h:843 +msgid "Export as SVG..." +msgstr "" + +#: objects/ui_MainWindow.h:844 +msgid "Export as AMF..." +msgstr "" + +#: objects/ui_MainWindow.h:846 +msgid "Ctrl+]" +msgstr "" + +#: objects/ui_MainWindow.h:848 +msgid "Ctrl+[" +msgstr "" + +#: objects/ui_MainWindow.h:849 +#, fuzzy +msgid "View All" +msgstr "&Vue" + +#: objects/ui_MainWindow.h:850 +msgid "Convert Tabs to Spaces" +msgstr "" + +#: objects/ui_MainWindow.h:851 +msgid "Hide toolbars" +msgstr "" + +#: objects/ui_MainWindow.h:852 +msgid "Time:" +msgstr "" + +#: objects/ui_MainWindow.h:853 +msgid "FPS:" +msgstr "" + +#: objects/ui_MainWindow.h:854 +msgid "Steps:" +msgstr "" + +#: objects/ui_MainWindow.h:855 +msgid "Dump Pictures" +msgstr "" + +#: objects/ui_MainWindow.h:856 +msgid "&File" +msgstr "&Fichier" + +#: objects/ui_MainWindow.h:857 +#, fuzzy +msgid "Recent Files" +msgstr "Ouvrir un fichier" + +#: objects/ui_MainWindow.h:859 +msgid "Export" +msgstr "" + +#: objects/ui_MainWindow.h:860 +msgid "&Edit" +msgstr "&Édition" + +#: objects/ui_MainWindow.h:861 +msgid "&Design" +msgstr "" + +#: objects/ui_MainWindow.h:862 +msgid "&View" +msgstr "&Vue" + +#: objects/ui_MainWindow.h:863 +msgid "&Help" +msgstr "&Aide" + +#: objects/ui_MainWindow.h:866 +msgid "Find" +msgstr "" + +#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 +msgid "Replace" +msgstr "" + +#: objects/ui_MainWindow.h:869 +msgid "Search string" +msgstr "" + +#: objects/ui_MainWindow.h:870 +msgid "<" +msgstr "" + +#: objects/ui_MainWindow.h:871 +msgid ">" +msgstr "" + +#: objects/ui_MainWindow.h:872 +msgid "Done" +msgstr "" + +#: objects/ui_MainWindow.h:873 +msgid "Replacement string" +msgstr "" + +#: objects/ui_MainWindow.h:875 +msgid "All" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:86 +#, fuzzy +msgid "OpenGL Warning" +msgstr "Information OpenGL" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + +#: objects/ui_Preferences.h:609 +#, fuzzy +msgid "3D View" +msgstr "&Vue" + +#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 +msgid "Advanced" +msgstr "" + +#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 +msgid "Editor" +msgstr "" + +#: objects/ui_Preferences.h:612 +msgid "Update" +msgstr "" + +#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 +msgid "Features" +msgstr "" + +#: objects/ui_Preferences.h:615 +msgid "Enable/Disable experimental features" +msgstr "" + +#: objects/ui_Preferences.h:617 +msgid "Color scheme:" +msgstr "" + +#: objects/ui_Preferences.h:618 +msgid "Editor Type" +msgstr "" + +#: objects/ui_Preferences.h:621 +msgid "Simple Editor" +msgstr "" + +#: objects/ui_Preferences.h:622 +msgid "QScintilla Editor" +msgstr "" + +#: objects/ui_Preferences.h:624 +msgid "(requires restart)" +msgstr "" + +#: objects/ui_Preferences.h:625 +msgid "Font" +msgstr "" + +#: objects/ui_Preferences.h:626 +msgid "Color syntax highlighting" +msgstr "" + +#: objects/ui_Preferences.h:627 +msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" +msgstr "" + +#: objects/ui_Preferences.h:629 +msgid "Automatically check for updates" +msgstr "" + +#: objects/ui_Preferences.h:630 +msgid "Include development snapshots" +msgstr "" + +#: objects/ui_Preferences.h:631 +msgid "Check Now" +msgstr "" + +#: objects/ui_Preferences.h:632 +msgid "Last checked: " +msgstr "" + +#: objects/ui_Preferences.h:634 +msgid "OpenCSG" +msgstr "" + +#: objects/ui_Preferences.h:635 +msgid "Show capability warning" +msgstr "" + +#: objects/ui_Preferences.h:636 +msgid "Enable for OpenGL 1.x" +msgstr "" + +#: objects/ui_Preferences.h:637 +msgid "Turn off rendering at " +msgstr "" + +#: objects/ui_Preferences.h:638 +msgid "elements" +msgstr "" + +#: objects/ui_Preferences.h:639 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:640 +msgid "CGAL Cache size" +msgstr "" + +#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 +msgid "bytes" +msgstr "" + +#: objects/ui_Preferences.h:642 +msgid "PolySet Cache size" +msgstr "" + +#: objects/ui_Preferences.h:644 +msgid "Allow to open multiple documents" +msgstr "" + +#: objects/ui_Preferences.h:645 +msgid "Enable docking of Editor and Console in different places" +msgstr "" + +#: objects/ui_Preferences.h:646 +msgid "Enable undocking of Editor and Console to separate windows" +msgstr "" + +#: objects/ui_Preferences.h:647 +msgid "Show Welcome Screen" +msgstr "" + +#: objects/ui_Preferences.h:648 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" + +#: objects/ui_Preferences.h:649 +msgid "toolBar" +msgstr "" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: src/AboutDialog.h:15 +msgid "About OpenSCAD " +msgstr "" + +#: src/mainwin.cc:773 src/mainwin.cc:1315 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1314 +msgid "Save File" +msgstr "" + +#: src/mainwin.cc:1316 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1326 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1654 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1655 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1966 src/mainwin.cc:2023 +msgid "Export %1 File" +msgstr "" + +#: src/mainwin.cc:1967 src/mainwin.cc:2027 +msgid "%1 Files (*%2)" +msgstr "" + +#: src/mainwin.cc:1968 +msgid "Untitled" +msgstr "" + +#: src/mainwin.cc:2025 +msgid "Untitled%1" +msgstr "" + +#: src/mainwin.cc:2076 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:2077 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:2078 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:2344 +msgid "Console" +msgstr "" + +#: src/mainwin.cc:2471 +msgid "The document has been modified." +msgstr "" + +#: src/mainwin.cc:2472 +msgid "Do you want to save your changes?" +msgstr "" + +#: src/QGLView.cc:114 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" + +#: src/QGLView.cc:131 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:134 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:137 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/QGLView.cc:141 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/QGLView.cc:171 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Basics" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Shapes" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Extrusion" +msgstr "" + +#~ msgid "OpenGL Info" +#~ msgstr "Information OpenGL" diff --git a/po/openscad.pot b/locale/openscad.pot similarity index 84% rename from po/openscad.pot rename to locale/openscad.pot index ad221a23..4462daad 100644 --- a/po/openscad.pot +++ b/locale/openscad.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: OpenSCAD 2014.10.21\n" +"Project-Id-Version: OpenSCAD 2014.11.13\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-10-21 00:00+0200\n" +"POT-Creation-Date: 2014-11-13 00:22+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -54,6 +54,57 @@ msgid "" ""Liberation Sans:style=Italic");" msgstr "" +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "" + +#: objects/ui_launchingscreen.h:277 +msgid "New" +msgstr "" + +#: objects/ui_launchingscreen.h:278 +msgid "Open" +msgstr "" + +#: objects/ui_launchingscreen.h:279 +msgid "Help" +msgstr "" + +#: objects/ui_launchingscreen.h:280 +msgid "Recents" +msgstr "" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "" + +#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 +#: objects/ui_MainWindow.h:858 +msgid "Examples" +msgstr "" + +#: objects/ui_launchingscreen.h:285 +msgid "Open Example" +msgstr "" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "" + #: objects/ui_LibraryInfoDialog.h:75 msgid "Lib & Build Info" msgstr "" @@ -62,552 +113,547 @@ msgstr "" msgid "OpenSCAD Detailed Library and Build Information" msgstr "" -#: objects/ui_MainWindow.h:732 +#: objects/ui_MainWindow.h:733 msgid "&New" msgstr "" -#: objects/ui_MainWindow.h:733 +#: objects/ui_MainWindow.h:734 msgid "Ctrl+N" msgstr "" -#: objects/ui_MainWindow.h:734 +#: objects/ui_MainWindow.h:735 msgid "&Open..." msgstr "" -#: objects/ui_MainWindow.h:735 +#: objects/ui_MainWindow.h:736 msgid "Ctrl+O" msgstr "" -#: objects/ui_MainWindow.h:736 +#: objects/ui_MainWindow.h:737 msgid "&Save" msgstr "" -#: objects/ui_MainWindow.h:737 +#: objects/ui_MainWindow.h:738 msgid "Ctrl+S" msgstr "" -#: objects/ui_MainWindow.h:738 +#: objects/ui_MainWindow.h:739 msgid "Save &As..." msgstr "" -#: objects/ui_MainWindow.h:739 +#: objects/ui_MainWindow.h:740 msgid "Ctrl+Shift+S" msgstr "" -#: objects/ui_MainWindow.h:740 +#: objects/ui_MainWindow.h:741 msgid "&Reload" msgstr "" -#: objects/ui_MainWindow.h:741 +#: objects/ui_MainWindow.h:742 msgid "Ctrl+R" msgstr "" -#: objects/ui_MainWindow.h:742 +#: objects/ui_MainWindow.h:743 msgid "&Quit" msgstr "" -#: objects/ui_MainWindow.h:743 +#: objects/ui_MainWindow.h:744 msgid "Ctrl+Q" msgstr "" -#: objects/ui_MainWindow.h:744 +#: objects/ui_MainWindow.h:745 msgid "&Undo" msgstr "" -#: objects/ui_MainWindow.h:745 +#: objects/ui_MainWindow.h:746 msgid "Ctrl+Z" msgstr "" -#: objects/ui_MainWindow.h:746 +#: objects/ui_MainWindow.h:747 msgid "&Redo" msgstr "" -#: objects/ui_MainWindow.h:747 +#: objects/ui_MainWindow.h:748 msgid "Ctrl+Shift+Z" msgstr "" -#: objects/ui_MainWindow.h:748 +#: objects/ui_MainWindow.h:749 msgid "Cu&t" msgstr "" -#: objects/ui_MainWindow.h:749 +#: objects/ui_MainWindow.h:750 msgid "Ctrl+X" msgstr "" -#: objects/ui_MainWindow.h:750 +#: objects/ui_MainWindow.h:751 msgid "&Copy" msgstr "" -#: objects/ui_MainWindow.h:751 +#: objects/ui_MainWindow.h:752 msgid "Ctrl+C" msgstr "" -#: objects/ui_MainWindow.h:752 +#: objects/ui_MainWindow.h:753 msgid "&Paste" msgstr "" -#: objects/ui_MainWindow.h:753 +#: objects/ui_MainWindow.h:754 msgid "Ctrl+V" msgstr "" -#: objects/ui_MainWindow.h:754 +#: objects/ui_MainWindow.h:755 msgid "&Indent" msgstr "" -#: objects/ui_MainWindow.h:755 +#: objects/ui_MainWindow.h:756 msgid "Ctrl+I" msgstr "" -#: objects/ui_MainWindow.h:756 +#: objects/ui_MainWindow.h:757 msgid "U&nindent" msgstr "" -#: objects/ui_MainWindow.h:757 +#: objects/ui_MainWindow.h:758 msgid "Ctrl+Shift+I" msgstr "" -#: objects/ui_MainWindow.h:758 +#: objects/ui_MainWindow.h:759 msgid "C&omment" msgstr "" -#: objects/ui_MainWindow.h:759 +#: objects/ui_MainWindow.h:760 msgid "Ctrl+D" msgstr "" -#: objects/ui_MainWindow.h:760 +#: objects/ui_MainWindow.h:761 msgid "Unco&mment" msgstr "" -#: objects/ui_MainWindow.h:761 +#: objects/ui_MainWindow.h:762 msgid "Ctrl+Shift+D" msgstr "" -#: objects/ui_MainWindow.h:762 +#: objects/ui_MainWindow.h:763 msgid "Paste viewport translation" msgstr "" -#: objects/ui_MainWindow.h:763 +#: objects/ui_MainWindow.h:764 msgid "Ctrl+T" msgstr "" -#: objects/ui_MainWindow.h:764 +#: objects/ui_MainWindow.h:765 msgid "Paste viewport rotation" msgstr "" -#: objects/ui_MainWindow.h:765 objects/ui_MainWindow.h:844 +#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 msgid "Zoom In" msgstr "" -#: objects/ui_MainWindow.h:766 +#: objects/ui_MainWindow.h:767 msgid "Ctrl++" msgstr "" -#: objects/ui_MainWindow.h:767 objects/ui_MainWindow.h:846 +#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 msgid "Zoom Out" msgstr "" -#: objects/ui_MainWindow.h:768 +#: objects/ui_MainWindow.h:769 msgid "Ctrl+-" msgstr "" -#: objects/ui_MainWindow.h:769 +#: objects/ui_MainWindow.h:770 msgid "Hide editor" msgstr "" -#: objects/ui_MainWindow.h:770 +#: objects/ui_MainWindow.h:771 msgid "&Reload and Preview" msgstr "" -#: objects/ui_MainWindow.h:771 +#: objects/ui_MainWindow.h:772 msgid "F4" msgstr "" -#: objects/ui_MainWindow.h:772 +#: objects/ui_MainWindow.h:773 msgid "&Preview" msgstr "" -#: objects/ui_MainWindow.h:773 +#: objects/ui_MainWindow.h:774 msgid "F5" msgstr "" -#: objects/ui_MainWindow.h:774 +#: objects/ui_MainWindow.h:775 msgid "&Render" msgstr "" -#: objects/ui_MainWindow.h:775 +#: objects/ui_MainWindow.h:776 msgid "F6" msgstr "" -#: objects/ui_MainWindow.h:776 +#: objects/ui_MainWindow.h:777 msgid "Check Validity" msgstr "" -#: objects/ui_MainWindow.h:777 +#: objects/ui_MainWindow.h:778 msgid "Display &AST..." msgstr "" -#: objects/ui_MainWindow.h:778 +#: objects/ui_MainWindow.h:779 msgid "Display CSG &Tree..." msgstr "" -#: objects/ui_MainWindow.h:779 +#: objects/ui_MainWindow.h:780 msgid "Display CSG &Products..." msgstr "" -#: objects/ui_MainWindow.h:780 +#: objects/ui_MainWindow.h:781 msgid "Export as &STL..." msgstr "" -#: objects/ui_MainWindow.h:781 +#: objects/ui_MainWindow.h:782 msgid "Export as &OFF..." msgstr "" -#: objects/ui_MainWindow.h:782 +#: objects/ui_MainWindow.h:783 msgid "Preview" msgstr "" -#: objects/ui_MainWindow.h:783 +#: objects/ui_MainWindow.h:784 msgid "F9" msgstr "" -#: objects/ui_MainWindow.h:784 +#: objects/ui_MainWindow.h:785 msgid "Surfaces" msgstr "" -#: objects/ui_MainWindow.h:785 +#: objects/ui_MainWindow.h:786 msgid "F10" msgstr "" -#: objects/ui_MainWindow.h:786 +#: objects/ui_MainWindow.h:787 msgid "Wireframe" msgstr "" -#: objects/ui_MainWindow.h:787 +#: objects/ui_MainWindow.h:788 msgid "F11" msgstr "" -#: objects/ui_MainWindow.h:788 +#: objects/ui_MainWindow.h:789 msgid "Thrown Together" msgstr "" -#: objects/ui_MainWindow.h:789 +#: objects/ui_MainWindow.h:790 msgid "F12" msgstr "" -#: objects/ui_MainWindow.h:790 +#: objects/ui_MainWindow.h:791 msgid "Show Edges" msgstr "" -#: objects/ui_MainWindow.h:791 +#: objects/ui_MainWindow.h:792 msgid "Ctrl+1" msgstr "" -#: objects/ui_MainWindow.h:792 +#: objects/ui_MainWindow.h:793 msgid "Show Axes" msgstr "" -#: objects/ui_MainWindow.h:793 +#: objects/ui_MainWindow.h:794 msgid "Ctrl+2" msgstr "" -#: objects/ui_MainWindow.h:794 +#: objects/ui_MainWindow.h:795 msgid "Show Crosshairs" msgstr "" -#: objects/ui_MainWindow.h:795 +#: objects/ui_MainWindow.h:796 msgid "Ctrl+3" msgstr "" -#: objects/ui_MainWindow.h:796 +#: objects/ui_MainWindow.h:797 msgid "Animate" msgstr "" -#: objects/ui_MainWindow.h:797 +#: objects/ui_MainWindow.h:798 msgid "Top" msgstr "" -#: objects/ui_MainWindow.h:798 +#: objects/ui_MainWindow.h:799 msgid "Ctrl+4" msgstr "" -#: objects/ui_MainWindow.h:799 +#: objects/ui_MainWindow.h:800 msgid "Bottom" msgstr "" -#: objects/ui_MainWindow.h:800 +#: objects/ui_MainWindow.h:801 msgid "Ctrl+5" msgstr "" -#: objects/ui_MainWindow.h:801 +#: objects/ui_MainWindow.h:802 msgid "Left" msgstr "" -#: objects/ui_MainWindow.h:802 +#: objects/ui_MainWindow.h:803 msgid "Ctrl+6" msgstr "" -#: objects/ui_MainWindow.h:803 +#: objects/ui_MainWindow.h:804 msgid "Right" msgstr "" -#: objects/ui_MainWindow.h:804 +#: objects/ui_MainWindow.h:805 msgid "Ctrl+7" msgstr "" -#: objects/ui_MainWindow.h:805 +#: objects/ui_MainWindow.h:806 msgid "Front" msgstr "" -#: objects/ui_MainWindow.h:806 +#: objects/ui_MainWindow.h:807 msgid "Ctrl+8" msgstr "" -#: objects/ui_MainWindow.h:807 +#: objects/ui_MainWindow.h:808 msgid "Back" msgstr "" -#: objects/ui_MainWindow.h:808 +#: objects/ui_MainWindow.h:809 msgid "Ctrl+9" msgstr "" -#: objects/ui_MainWindow.h:809 +#: objects/ui_MainWindow.h:810 msgid "Diagonal" msgstr "" -#: objects/ui_MainWindow.h:810 +#: objects/ui_MainWindow.h:811 msgid "Ctrl+0" msgstr "" -#: objects/ui_MainWindow.h:811 +#: objects/ui_MainWindow.h:812 msgid "Center" msgstr "" -#: objects/ui_MainWindow.h:812 +#: objects/ui_MainWindow.h:813 msgid "Perspective" msgstr "" -#: objects/ui_MainWindow.h:813 +#: objects/ui_MainWindow.h:814 msgid "Orthogonal" msgstr "" -#: objects/ui_MainWindow.h:814 +#: objects/ui_MainWindow.h:815 msgid "Hide console" msgstr "" -#: objects/ui_MainWindow.h:815 +#: objects/ui_MainWindow.h:816 msgid "About" msgstr "" -#: objects/ui_MainWindow.h:816 +#: objects/ui_MainWindow.h:817 msgid "Documentation" msgstr "" -#: objects/ui_MainWindow.h:817 +#: objects/ui_MainWindow.h:818 msgid "Clear Recent" msgstr "" -#: objects/ui_MainWindow.h:818 +#: objects/ui_MainWindow.h:819 msgid "Export as DXF..." msgstr "" -#: objects/ui_MainWindow.h:819 objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 msgid "Close" msgstr "" -#: objects/ui_MainWindow.h:820 +#: objects/ui_MainWindow.h:821 msgid "Ctrl+W" msgstr "" -#: objects/ui_MainWindow.h:821 objects/ui_Preferences.h:609 +#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 msgid "Preferences" msgstr "" -#: objects/ui_MainWindow.h:822 +#: objects/ui_MainWindow.h:823 msgid "Find..." msgstr "" -#: objects/ui_MainWindow.h:823 +#: objects/ui_MainWindow.h:824 msgid "Ctrl+F" msgstr "" -#: objects/ui_MainWindow.h:824 +#: objects/ui_MainWindow.h:825 msgid "Find and Replace..." msgstr "" -#: objects/ui_MainWindow.h:825 +#: objects/ui_MainWindow.h:826 msgid "Ctrl+Alt+F" msgstr "" -#: objects/ui_MainWindow.h:826 +#: objects/ui_MainWindow.h:827 msgid "Find Next" msgstr "" -#: objects/ui_MainWindow.h:827 +#: objects/ui_MainWindow.h:828 msgid "Ctrl+G" msgstr "" -#: objects/ui_MainWindow.h:828 +#: objects/ui_MainWindow.h:829 msgid "Find Previous" msgstr "" -#: objects/ui_MainWindow.h:829 +#: objects/ui_MainWindow.h:830 msgid "Ctrl+Shift+G" msgstr "" -#: objects/ui_MainWindow.h:830 +#: objects/ui_MainWindow.h:831 msgid "Use Selection for Find" msgstr "" -#: objects/ui_MainWindow.h:831 +#: objects/ui_MainWindow.h:832 msgid "Ctrl+E" msgstr "" -#: objects/ui_MainWindow.h:832 +#: objects/ui_MainWindow.h:833 msgid "Flush Caches" msgstr "" -#: objects/ui_MainWindow.h:833 +#: objects/ui_MainWindow.h:834 msgid "OpenSCAD Homepage" msgstr "" -#: objects/ui_MainWindow.h:834 +#: objects/ui_MainWindow.h:835 msgid "Automatic Reload and Preview" msgstr "" -#: objects/ui_MainWindow.h:835 +#: objects/ui_MainWindow.h:836 msgid "Export as Image..." msgstr "" -#: objects/ui_MainWindow.h:836 +#: objects/ui_MainWindow.h:837 msgid "Export as CSG..." msgstr "" -#: objects/ui_MainWindow.h:837 +#: objects/ui_MainWindow.h:838 msgid "Library info" msgstr "" -#: objects/ui_MainWindow.h:838 +#: objects/ui_MainWindow.h:839 msgid "Check for Update.." msgstr "" -#: objects/ui_MainWindow.h:839 +#: objects/ui_MainWindow.h:840 msgid "Show Library Folder..." msgstr "" -#: objects/ui_MainWindow.h:840 +#: objects/ui_MainWindow.h:841 msgid "Reset View" msgstr "" -#: objects/ui_MainWindow.h:841 +#: objects/ui_MainWindow.h:842 msgid "Font List" msgstr "" -#: objects/ui_MainWindow.h:842 +#: objects/ui_MainWindow.h:843 msgid "Export as SVG..." msgstr "" -#: objects/ui_MainWindow.h:843 +#: objects/ui_MainWindow.h:844 msgid "Export as AMF..." msgstr "" -#: objects/ui_MainWindow.h:845 +#: objects/ui_MainWindow.h:846 msgid "Ctrl+]" msgstr "" -#: objects/ui_MainWindow.h:847 +#: objects/ui_MainWindow.h:848 msgid "Ctrl+[" msgstr "" -#: objects/ui_MainWindow.h:848 +#: objects/ui_MainWindow.h:849 msgid "View All" msgstr "" -#: objects/ui_MainWindow.h:849 +#: objects/ui_MainWindow.h:850 msgid "Convert Tabs to Spaces" msgstr "" -#: objects/ui_MainWindow.h:850 +#: objects/ui_MainWindow.h:851 msgid "Hide toolbars" msgstr "" -#: objects/ui_MainWindow.h:851 +#: objects/ui_MainWindow.h:852 msgid "Time:" msgstr "" -#: objects/ui_MainWindow.h:852 +#: objects/ui_MainWindow.h:853 msgid "FPS:" msgstr "" -#: objects/ui_MainWindow.h:853 +#: objects/ui_MainWindow.h:854 msgid "Steps:" msgstr "" -#: objects/ui_MainWindow.h:854 +#: objects/ui_MainWindow.h:855 msgid "Dump Pictures" msgstr "" -#: objects/ui_MainWindow.h:855 +#: objects/ui_MainWindow.h:856 msgid "&File" msgstr "" -#: objects/ui_MainWindow.h:856 +#: objects/ui_MainWindow.h:857 msgid "Recent Files" msgstr "" -#: objects/ui_MainWindow.h:857 objects/ui_launchingscreen.h:282 -#: objects/ui_launchingscreen.h:284 -msgid "Examples" -msgstr "" - -#: objects/ui_MainWindow.h:858 +#: objects/ui_MainWindow.h:859 msgid "Export" msgstr "" -#: objects/ui_MainWindow.h:859 +#: objects/ui_MainWindow.h:860 msgid "&Edit" msgstr "" -#: objects/ui_MainWindow.h:860 +#: objects/ui_MainWindow.h:861 msgid "&Design" msgstr "" -#: objects/ui_MainWindow.h:861 +#: objects/ui_MainWindow.h:862 msgid "&View" msgstr "" -#: objects/ui_MainWindow.h:862 +#: objects/ui_MainWindow.h:863 msgid "&Help" msgstr "" -#: objects/ui_MainWindow.h:865 +#: objects/ui_MainWindow.h:866 msgid "Find" msgstr "" -#: objects/ui_MainWindow.h:866 objects/ui_MainWindow.h:873 +#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 msgid "Replace" msgstr "" -#: objects/ui_MainWindow.h:868 +#: objects/ui_MainWindow.h:869 msgid "Search string" msgstr "" -#: objects/ui_MainWindow.h:869 +#: objects/ui_MainWindow.h:870 msgid "<" msgstr "" -#: objects/ui_MainWindow.h:870 +#: objects/ui_MainWindow.h:871 msgid ">" msgstr "" -#: objects/ui_MainWindow.h:871 +#: objects/ui_MainWindow.h:872 msgid "Done" msgstr "" -#: objects/ui_MainWindow.h:872 +#: objects/ui_MainWindow.h:873 msgid "Replacement string" msgstr "" -#: objects/ui_MainWindow.h:874 +#: objects/ui_MainWindow.h:875 msgid "All" msgstr "" @@ -637,179 +683,135 @@ msgstr "" msgid "Show this message again" msgstr "" -#: objects/ui_Preferences.h:610 +#: objects/ui_Preferences.h:609 msgid "3D View" msgstr "" -#: objects/ui_Preferences.h:611 src/UIUtils.cc:85 +#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 msgid "Advanced" msgstr "" -#: objects/ui_Preferences.h:612 src/mainwin.cc:2292 +#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 msgid "Editor" msgstr "" -#: objects/ui_Preferences.h:613 +#: objects/ui_Preferences.h:612 msgid "Update" msgstr "" -#: objects/ui_Preferences.h:614 objects/ui_Preferences.h:661 +#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 msgid "Features" msgstr "" -#: objects/ui_Preferences.h:616 +#: objects/ui_Preferences.h:615 msgid "Enable/Disable experimental features" msgstr "" -#: objects/ui_Preferences.h:618 +#: objects/ui_Preferences.h:617 msgid "Color scheme:" msgstr "" -#: objects/ui_Preferences.h:623 -msgid "Cornfield" -msgstr "" - -#: objects/ui_Preferences.h:625 -msgid "Metallic" -msgstr "" - -#: objects/ui_Preferences.h:627 -msgid "Sunset" -msgstr "" - -#: objects/ui_Preferences.h:629 -msgid "Starnight" -msgstr "" - -#: objects/ui_Preferences.h:631 -msgid "BeforeDawn" -msgstr "" - -#: objects/ui_Preferences.h:633 -msgid "Nature" -msgstr "" - -#: objects/ui_Preferences.h:635 -msgid "DeepOcean" -msgstr "" - -#: objects/ui_Preferences.h:638 +#: objects/ui_Preferences.h:618 msgid "Editor Type" msgstr "" -#: objects/ui_Preferences.h:641 +#: objects/ui_Preferences.h:621 msgid "Simple Editor" msgstr "" -#: objects/ui_Preferences.h:642 +#: objects/ui_Preferences.h:622 msgid "QScintilla Editor" msgstr "" -#: objects/ui_Preferences.h:644 +#: objects/ui_Preferences.h:624 msgid "(requires restart)" msgstr "" -#: objects/ui_Preferences.h:645 +#: objects/ui_Preferences.h:625 msgid "Font" msgstr "" -#: objects/ui_Preferences.h:646 +#: objects/ui_Preferences.h:626 msgid "Color syntax highlighting" msgstr "" -#: objects/ui_Preferences.h:649 -msgid "For Light Background" -msgstr "" - -#: objects/ui_Preferences.h:650 -msgid "For Dark Background" -msgstr "" - -#: objects/ui_Preferences.h:651 -msgid "Monokai" -msgstr "" - -#: objects/ui_Preferences.h:652 -msgid "Solarized" -msgstr "" - -#: objects/ui_Preferences.h:653 -msgid "Off" -msgstr "" - -#: objects/ui_Preferences.h:655 +#: objects/ui_Preferences.h:627 msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" msgstr "" -#: objects/ui_Preferences.h:657 +#: objects/ui_Preferences.h:629 msgid "Automatically check for updates" msgstr "" -#: objects/ui_Preferences.h:658 +#: objects/ui_Preferences.h:630 msgid "Include development snapshots" msgstr "" -#: objects/ui_Preferences.h:659 +#: objects/ui_Preferences.h:631 msgid "Check Now" msgstr "" -#: objects/ui_Preferences.h:660 +#: objects/ui_Preferences.h:632 msgid "Last checked: " msgstr "" -#: objects/ui_Preferences.h:662 +#: objects/ui_Preferences.h:634 msgid "OpenCSG" msgstr "" -#: objects/ui_Preferences.h:663 +#: objects/ui_Preferences.h:635 msgid "Show capability warning" msgstr "" -#: objects/ui_Preferences.h:664 +#: objects/ui_Preferences.h:636 msgid "Enable for OpenGL 1.x" msgstr "" -#: objects/ui_Preferences.h:665 +#: objects/ui_Preferences.h:637 msgid "Turn off rendering at " msgstr "" -#: objects/ui_Preferences.h:666 +#: objects/ui_Preferences.h:638 msgid "elements" msgstr "" -#: objects/ui_Preferences.h:667 +#: objects/ui_Preferences.h:639 msgid "Force Goldfeather" msgstr "" -#: objects/ui_Preferences.h:668 +#: objects/ui_Preferences.h:640 msgid "CGAL Cache size" msgstr "" -#: objects/ui_Preferences.h:669 objects/ui_Preferences.h:671 +#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 msgid "bytes" msgstr "" -#: objects/ui_Preferences.h:670 +#: objects/ui_Preferences.h:642 msgid "PolySet Cache size" msgstr "" -#: objects/ui_Preferences.h:672 +#: objects/ui_Preferences.h:644 msgid "Allow to open multiple documents" msgstr "" -#: objects/ui_Preferences.h:673 -msgid "Enable undocking of Editor and Console" +#: objects/ui_Preferences.h:645 +msgid "Enable docking of Editor and Console in different places" msgstr "" -#: objects/ui_Preferences.h:674 +#: objects/ui_Preferences.h:646 +msgid "Enable undocking of Editor and Console to separate windows" +msgstr "" + +#: objects/ui_Preferences.h:647 msgid "Show Welcome Screen" msgstr "" -#: objects/ui_Preferences.h:675 +#: objects/ui_Preferences.h:648 msgid "Enable user interface localization (requires restart of OpenSCAD)" msgstr "" -#: objects/ui_Preferences.h:676 +#: objects/ui_Preferences.h:649 msgid "toolBar" msgstr "" @@ -821,56 +823,86 @@ msgstr "" msgid "%v / %m" msgstr "" -#: objects/ui_launchingscreen.h:276 -msgid "Welcome to OpenSCAD" -msgstr "" - -#: objects/ui_launchingscreen.h:277 -msgid "New" -msgstr "" - -#: objects/ui_launchingscreen.h:278 -msgid "Open" -msgstr "" - -#: objects/ui_launchingscreen.h:279 -msgid "Help" -msgstr "" - -#: objects/ui_launchingscreen.h:280 -msgid "Recents" -msgstr "" - -#: objects/ui_launchingscreen.h:281 -msgid "Open Recent" -msgstr "" - -#: objects/ui_launchingscreen.h:285 -msgid "Open Example" -msgstr "" - -#: objects/ui_launchingscreen.h:287 -msgid "" -"\n" -"

OpenSCAD

\n" -"

The Programmers Solid 3D CAD Modeller

\n" -"\n" -"\n" -"\n" -msgstr "" - -#: objects/ui_launchingscreen.h:294 -msgid "Don't show again" -msgstr "" - #: src/AboutDialog.h:15 msgid "About OpenSCAD " msgstr "" +#: src/mainwin.cc:773 src/mainwin.cc:1315 +msgid "Untitled.scad" +msgstr "" + +#: src/mainwin.cc:1314 +msgid "Save File" +msgstr "" + +#: src/mainwin.cc:1316 +msgid "OpenSCAD Designs (*.scad)" +msgstr "" + +#: src/mainwin.cc:1326 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1654 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1655 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1966 src/mainwin.cc:2023 +msgid "Export %1 File" +msgstr "" + +#: src/mainwin.cc:1967 src/mainwin.cc:2027 +msgid "%1 Files (*%2)" +msgstr "" + +#: src/mainwin.cc:1968 +msgid "Untitled" +msgstr "" + +#: src/mainwin.cc:2025 +msgid "Untitled%1" +msgstr "" + +#: src/mainwin.cc:2076 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:2077 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:2078 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:2344 +msgid "Console" +msgstr "" + +#: src/mainwin.cc:2471 +msgid "The document has been modified." +msgstr "" + +#: src/mainwin.cc:2472 +msgid "Do you want to save your changes?" +msgstr "" + #: src/QGLView.cc:114 msgid "" "\n" @@ -924,79 +956,3 @@ msgstr "" #: src/UIUtils.cc:85 msgid "Extrusion" msgstr "" - -#: src/mainwin.cc:728 src/mainwin.cc:1269 -msgid "Untitled.scad" -msgstr "" - -#: src/mainwin.cc:1268 -msgid "Save File" -msgstr "" - -#: src/mainwin.cc:1270 -msgid "OpenSCAD Designs (*.scad)" -msgstr "" - -#: src/mainwin.cc:1280 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" - -#: src/mainwin.cc:1608 -msgid "Application" -msgstr "" - -#: src/mainwin.cc:1609 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" - -#: src/mainwin.cc:1907 src/mainwin.cc:1964 -msgid "Export %1 File" -msgstr "" - -#: src/mainwin.cc:1908 src/mainwin.cc:1968 -msgid "%1 Files (*%2)" -msgstr "" - -#: src/mainwin.cc:1909 -msgid "Untitled" -msgstr "" - -#: src/mainwin.cc:1966 -msgid "Untitled%1" -msgstr "" - -#: src/mainwin.cc:2017 -msgid "Export CSG File" -msgstr "" - -#: src/mainwin.cc:2018 -msgid "Untitled.csg" -msgstr "" - -#: src/mainwin.cc:2019 -msgid "CSG Files (*.csg)" -msgstr "" - -#: src/mainwin.cc:2045 -msgid "Export Image" -msgstr "" - -#: src/mainwin.cc:2045 -msgid "PNG Files (*.png)" -msgstr "" - -#: src/mainwin.cc:2297 -msgid "Console" -msgstr "" - -#: src/mainwin.cc:2420 -msgid "The document has been modified." -msgstr "" - -#: src/mainwin.cc:2421 -msgid "Do you want to save your changes?" -msgstr "" diff --git a/locale/ru.po b/locale/ru.po new file mode 100644 index 00000000..4f64a3de --- /dev/null +++ b/locale/ru.po @@ -0,0 +1,1009 @@ +# Russian translations for OpenSCAD package. +# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER +# This file is distributed under the same license as the OpenSCAD package. +# , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2014.01.05\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-13 00:22+0100\n" +"PO-Revision-Date: 2013-02-24 17:50+0100\n" +"Last-Translator: \n" +"Language-Team: Russian\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "О программе OpenSCAD" + +#: objects/ui_FontListDialog.h:102 +#, fuzzy +msgid "OpenSCAD Font List" +msgstr "Шрифт" + +#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 +msgid "&OK" +msgstr "" + +#: objects/ui_FontListDialog.h:105 +msgid "Paste font selector to Editor Window" +msgstr "" + +#: objects/ui_FontListDialog.h:107 +msgid "Copy to Clipboard" +msgstr "" + +#: objects/ui_FontListDialog.h:108 +msgid "Filter:" +msgstr "" + +#: objects/ui_FontListDialog.h:109 +msgid "" +"

This list shows the fonts currently registered with " +"OpenSCAD.

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" +msgstr "" + +#: objects/ui_launchingscreen.h:276 +#, fuzzy +msgid "Welcome to OpenSCAD" +msgstr "О программе OpenSCAD" + +#: objects/ui_launchingscreen.h:277 +#, fuzzy +msgid "New" +msgstr "&Создать" + +#: objects/ui_launchingscreen.h:278 +#, fuzzy +msgid "Open" +msgstr "&Открыть..." + +#: objects/ui_launchingscreen.h:279 +#, fuzzy +msgid "Help" +msgstr "&Справка" + +#: objects/ui_launchingscreen.h:280 +#, fuzzy +msgid "Recents" +msgstr "Открыть файл" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "Открыть недавние" + +#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 +#: objects/ui_MainWindow.h:858 +msgid "Examples" +msgstr "Примеры" + +#: objects/ui_launchingscreen.h:285 +#, fuzzy +msgid "Open Example" +msgstr "Примеры" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "" + +#: objects/ui_LibraryInfoDialog.h:75 +msgid "Lib & Build Info" +msgstr "" + +#: objects/ui_LibraryInfoDialog.h:76 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "Подробная информация о библиотеках и сборке OpenSCAD" + +#: objects/ui_MainWindow.h:733 +msgid "&New" +msgstr "&Создать" + +#: objects/ui_MainWindow.h:734 +msgid "Ctrl+N" +msgstr "" + +#: objects/ui_MainWindow.h:735 +msgid "&Open..." +msgstr "&Открыть..." + +#: objects/ui_MainWindow.h:736 +msgid "Ctrl+O" +msgstr "" + +#: objects/ui_MainWindow.h:737 +msgid "&Save" +msgstr "&Сохранить" + +#: objects/ui_MainWindow.h:738 +msgid "Ctrl+S" +msgstr "" + +#: objects/ui_MainWindow.h:739 +msgid "Save &As..." +msgstr "Сохранить &как..." + +#: objects/ui_MainWindow.h:740 +msgid "Ctrl+Shift+S" +msgstr "" + +#: objects/ui_MainWindow.h:741 +msgid "&Reload" +msgstr "&Обновить" + +#: objects/ui_MainWindow.h:742 +msgid "Ctrl+R" +msgstr "" + +#: objects/ui_MainWindow.h:743 +msgid "&Quit" +msgstr "&Выход" + +#: objects/ui_MainWindow.h:744 +msgid "Ctrl+Q" +msgstr "" + +#: objects/ui_MainWindow.h:745 +msgid "&Undo" +msgstr "&Отменить" + +#: objects/ui_MainWindow.h:746 +msgid "Ctrl+Z" +msgstr "" + +#: objects/ui_MainWindow.h:747 +msgid "&Redo" +msgstr "&Повторить" + +#: objects/ui_MainWindow.h:748 +msgid "Ctrl+Shift+Z" +msgstr "" + +#: objects/ui_MainWindow.h:749 +msgid "Cu&t" +msgstr "Вы&резать" + +#: objects/ui_MainWindow.h:750 +msgid "Ctrl+X" +msgstr "" + +#: objects/ui_MainWindow.h:751 +msgid "&Copy" +msgstr "&Копировать" + +#: objects/ui_MainWindow.h:752 +msgid "Ctrl+C" +msgstr "" + +#: objects/ui_MainWindow.h:753 +msgid "&Paste" +msgstr "&Вставить" + +#: objects/ui_MainWindow.h:754 +msgid "Ctrl+V" +msgstr "" + +#: objects/ui_MainWindow.h:755 +msgid "&Indent" +msgstr "&Добавить отступ" + +#: objects/ui_MainWindow.h:756 +msgid "Ctrl+I" +msgstr "" + +#: objects/ui_MainWindow.h:757 +msgid "U&nindent" +msgstr "У&брать отступ" + +#: objects/ui_MainWindow.h:758 +msgid "Ctrl+Shift+I" +msgstr "" + +#: objects/ui_MainWindow.h:759 +msgid "C&omment" +msgstr "Зако&мментировать" + +#: objects/ui_MainWindow.h:760 +msgid "Ctrl+D" +msgstr "" + +#: objects/ui_MainWindow.h:761 +msgid "Unco&mment" +msgstr "Р&аскомментировать" + +#: objects/ui_MainWindow.h:762 +msgid "Ctrl+Shift+D" +msgstr "" + +#: objects/ui_MainWindow.h:763 +msgid "Paste viewport translation" +msgstr "Вставить смещение точки обзора" + +#: objects/ui_MainWindow.h:764 +msgid "Ctrl+T" +msgstr "" + +#: objects/ui_MainWindow.h:765 +msgid "Paste viewport rotation" +msgstr "Вставить поворот точки обзора" + +#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 +msgid "Zoom In" +msgstr "Увеличить масштаб" + +#: objects/ui_MainWindow.h:767 +msgid "Ctrl++" +msgstr "" + +#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 +msgid "Zoom Out" +msgstr "Уменьшить масштаб" + +#: objects/ui_MainWindow.h:769 +msgid "Ctrl+-" +msgstr "" + +#: objects/ui_MainWindow.h:770 +msgid "Hide editor" +msgstr "Скрыть редактор" + +#: objects/ui_MainWindow.h:771 +#, fuzzy +msgid "&Reload and Preview" +msgstr "&Обновить и компилировать" + +#: objects/ui_MainWindow.h:772 +msgid "F4" +msgstr "" + +#: objects/ui_MainWindow.h:773 +msgid "&Preview" +msgstr "" + +#: objects/ui_MainWindow.h:774 +msgid "F5" +msgstr "" + +#: objects/ui_MainWindow.h:775 +msgid "&Render" +msgstr "" + +#: objects/ui_MainWindow.h:776 +msgid "F6" +msgstr "" + +#: objects/ui_MainWindow.h:777 +msgid "Check Validity" +msgstr "" + +#: objects/ui_MainWindow.h:778 +msgid "Display &AST..." +msgstr "Показать &AST..." + +#: objects/ui_MainWindow.h:779 +msgid "Display CSG &Tree..." +msgstr "Показать &дерево CSG..." + +#: objects/ui_MainWindow.h:780 +msgid "Display CSG &Products..." +msgstr "Показать &результаты CSG..." + +#: objects/ui_MainWindow.h:781 +msgid "Export as &STL..." +msgstr "Экспортировать в &STL..." + +#: objects/ui_MainWindow.h:782 +msgid "Export as &OFF..." +msgstr "Экспортировать в &OFF..." + +#: objects/ui_MainWindow.h:783 +msgid "Preview" +msgstr "" + +#: objects/ui_MainWindow.h:784 +msgid "F9" +msgstr "" + +#: objects/ui_MainWindow.h:785 +#, fuzzy +msgid "Surfaces" +msgstr "Поверхности CGAL" + +#: objects/ui_MainWindow.h:786 +msgid "F10" +msgstr "" + +#: objects/ui_MainWindow.h:787 +msgid "Wireframe" +msgstr "" + +#: objects/ui_MainWindow.h:788 +msgid "F11" +msgstr "" + +#: objects/ui_MainWindow.h:789 +msgid "Thrown Together" +msgstr "Всё вместе" + +#: objects/ui_MainWindow.h:790 +msgid "F12" +msgstr "" + +#: objects/ui_MainWindow.h:791 +msgid "Show Edges" +msgstr "Показывать рёбра" + +#: objects/ui_MainWindow.h:792 +msgid "Ctrl+1" +msgstr "" + +#: objects/ui_MainWindow.h:793 +msgid "Show Axes" +msgstr "Показывать оси" + +#: objects/ui_MainWindow.h:794 +msgid "Ctrl+2" +msgstr "" + +#: objects/ui_MainWindow.h:795 +msgid "Show Crosshairs" +msgstr "Показывать перекрестия" + +#: objects/ui_MainWindow.h:796 +msgid "Ctrl+3" +msgstr "" + +#: objects/ui_MainWindow.h:797 +msgid "Animate" +msgstr "Анимация" + +#: objects/ui_MainWindow.h:798 +msgid "Top" +msgstr "Сверху" + +#: objects/ui_MainWindow.h:799 +msgid "Ctrl+4" +msgstr "" + +#: objects/ui_MainWindow.h:800 +msgid "Bottom" +msgstr "Снизу" + +#: objects/ui_MainWindow.h:801 +msgid "Ctrl+5" +msgstr "" + +#: objects/ui_MainWindow.h:802 +msgid "Left" +msgstr "Слева" + +#: objects/ui_MainWindow.h:803 +msgid "Ctrl+6" +msgstr "" + +#: objects/ui_MainWindow.h:804 +msgid "Right" +msgstr "Справа" + +#: objects/ui_MainWindow.h:805 +msgid "Ctrl+7" +msgstr "" + +#: objects/ui_MainWindow.h:806 +msgid "Front" +msgstr "Спереди" + +#: objects/ui_MainWindow.h:807 +msgid "Ctrl+8" +msgstr "" + +#: objects/ui_MainWindow.h:808 +msgid "Back" +msgstr "Сзади" + +#: objects/ui_MainWindow.h:809 +msgid "Ctrl+9" +msgstr "" + +#: objects/ui_MainWindow.h:810 +msgid "Diagonal" +msgstr "Аксонометрический" + +#: objects/ui_MainWindow.h:811 +msgid "Ctrl+0" +msgstr "" + +#: objects/ui_MainWindow.h:812 +msgid "Center" +msgstr "По центру" + +#: objects/ui_MainWindow.h:813 +msgid "Perspective" +msgstr "Перспектива" + +#: objects/ui_MainWindow.h:814 +msgid "Orthogonal" +msgstr "Прямоугольная проекция" + +#: objects/ui_MainWindow.h:815 +msgid "Hide console" +msgstr "Скрыть консоль" + +#: objects/ui_MainWindow.h:816 +msgid "About" +msgstr "О программе" + +#: objects/ui_MainWindow.h:817 +msgid "Documentation" +msgstr "Документация" + +#: objects/ui_MainWindow.h:818 +msgid "Clear Recent" +msgstr "Очистить список" + +#: objects/ui_MainWindow.h:819 +msgid "Export as DXF..." +msgstr "Экспортировать в DXF..." + +#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "Закрыть" + +#: objects/ui_MainWindow.h:821 +msgid "Ctrl+W" +msgstr "" + +#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 +msgid "Preferences" +msgstr "Настройки" + +#: objects/ui_MainWindow.h:823 +msgid "Find..." +msgstr "" + +#: objects/ui_MainWindow.h:824 +msgid "Ctrl+F" +msgstr "" + +#: objects/ui_MainWindow.h:825 +msgid "Find and Replace..." +msgstr "" + +#: objects/ui_MainWindow.h:826 +msgid "Ctrl+Alt+F" +msgstr "" + +#: objects/ui_MainWindow.h:827 +msgid "Find Next" +msgstr "" + +#: objects/ui_MainWindow.h:828 +msgid "Ctrl+G" +msgstr "" + +#: objects/ui_MainWindow.h:829 +msgid "Find Previous" +msgstr "" + +#: objects/ui_MainWindow.h:830 +msgid "Ctrl+Shift+G" +msgstr "" + +#: objects/ui_MainWindow.h:831 +msgid "Use Selection for Find" +msgstr "" + +#: objects/ui_MainWindow.h:832 +msgid "Ctrl+E" +msgstr "" + +#: objects/ui_MainWindow.h:833 +msgid "Flush Caches" +msgstr "Очистить кэш" + +#: objects/ui_MainWindow.h:834 +msgid "OpenSCAD Homepage" +msgstr "Домашняя страница OpenSCAD" + +#: objects/ui_MainWindow.h:835 +#, fuzzy +msgid "Automatic Reload and Preview" +msgstr "Автоматически обновлять и комилировать" + +#: objects/ui_MainWindow.h:836 +msgid "Export as Image..." +msgstr "Экспортировать в растр..." + +#: objects/ui_MainWindow.h:837 +msgid "Export as CSG..." +msgstr "Экспортировать в CSG..." + +#: objects/ui_MainWindow.h:838 +msgid "Library info" +msgstr "Информация о библиотеках" + +#: objects/ui_MainWindow.h:839 +msgid "Check for Update.." +msgstr "Проверить обновления..." + +#: objects/ui_MainWindow.h:840 +msgid "Show Library Folder..." +msgstr "Открыть каталог библиотек..." + +#: objects/ui_MainWindow.h:841 +msgid "Reset View" +msgstr "Сбросить настройки вида" + +#: objects/ui_MainWindow.h:842 +#, fuzzy +msgid "Font List" +msgstr "Шрифт" + +#: objects/ui_MainWindow.h:843 +#, fuzzy +msgid "Export as SVG..." +msgstr "Экспортировать в CSG..." + +#: objects/ui_MainWindow.h:844 +#, fuzzy +msgid "Export as AMF..." +msgstr "Экспортировать в DXF..." + +#: objects/ui_MainWindow.h:846 +msgid "Ctrl+]" +msgstr "" + +#: objects/ui_MainWindow.h:848 +msgid "Ctrl+[" +msgstr "" + +#: objects/ui_MainWindow.h:849 +#, fuzzy +msgid "View All" +msgstr "&Вид" + +#: objects/ui_MainWindow.h:850 +msgid "Convert Tabs to Spaces" +msgstr "" + +#: objects/ui_MainWindow.h:851 +#, fuzzy +msgid "Hide toolbars" +msgstr "Скрыть редактор" + +#: objects/ui_MainWindow.h:852 +msgid "Time:" +msgstr "Время:" + +#: objects/ui_MainWindow.h:853 +msgid "FPS:" +msgstr "Кадров в секунду:" + +#: objects/ui_MainWindow.h:854 +msgid "Steps:" +msgstr "Шагов:" + +#: objects/ui_MainWindow.h:855 +msgid "Dump Pictures" +msgstr "Сохранять кадры" + +#: objects/ui_MainWindow.h:856 +msgid "&File" +msgstr "&Файл" + +#: objects/ui_MainWindow.h:857 +#, fuzzy +msgid "Recent Files" +msgstr "Открыть файл" + +#: objects/ui_MainWindow.h:859 +msgid "Export" +msgstr "" + +#: objects/ui_MainWindow.h:860 +msgid "&Edit" +msgstr "&Правка" + +#: objects/ui_MainWindow.h:861 +msgid "&Design" +msgstr "&Модель" + +#: objects/ui_MainWindow.h:862 +msgid "&View" +msgstr "&Вид" + +#: objects/ui_MainWindow.h:863 +msgid "&Help" +msgstr "&Справка" + +#: objects/ui_MainWindow.h:866 +msgid "Find" +msgstr "" + +#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 +msgid "Replace" +msgstr "" + +#: objects/ui_MainWindow.h:869 +msgid "Search string" +msgstr "" + +#: objects/ui_MainWindow.h:870 +msgid "<" +msgstr "" + +#: objects/ui_MainWindow.h:871 +msgid ">" +msgstr "" + +#: objects/ui_MainWindow.h:872 +msgid "Done" +msgstr "" + +#: objects/ui_MainWindow.h:873 +#, fuzzy +msgid "Replacement string" +msgstr "элементах" + +#: objects/ui_MainWindow.h:875 +msgid "All" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" + +#: objects/ui_OpenCSGWarningDialog.h:92 +#, fuzzy +msgid "Enable OpenCSG" +msgstr "Включить для OpenGL 1.x" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "" + +#: objects/ui_Preferences.h:609 +msgid "3D View" +msgstr "3D Вид" + +#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 +msgid "Advanced" +msgstr "Дополнительные" + +#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 +msgid "Editor" +msgstr "Редактор" + +#: objects/ui_Preferences.h:612 +msgid "Update" +msgstr "Обновления" + +#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 +msgid "Features" +msgstr "Функции" + +#: objects/ui_Preferences.h:615 +msgid "Enable/Disable experimental features" +msgstr "" + +#: objects/ui_Preferences.h:617 +msgid "Color scheme:" +msgstr "Цветовая схема:" + +#: objects/ui_Preferences.h:618 +#, fuzzy +msgid "Editor Type" +msgstr "Редактор" + +#: objects/ui_Preferences.h:621 +#, fuzzy +msgid "Simple Editor" +msgstr "Скрыть редактор" + +#: objects/ui_Preferences.h:622 +msgid "QScintilla Editor" +msgstr "" + +#: objects/ui_Preferences.h:624 +msgid "(requires restart)" +msgstr "" + +#: objects/ui_Preferences.h:625 +msgid "Font" +msgstr "Шрифт" + +#: objects/ui_Preferences.h:626 +msgid "Color syntax highlighting" +msgstr "Подсветка синтаксиса" + +#: objects/ui_Preferences.h:627 +msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" +msgstr "" + +#: objects/ui_Preferences.h:629 +msgid "Automatically check for updates" +msgstr "Автоматически проверять обновления" + +#: objects/ui_Preferences.h:630 +msgid "Include development snapshots" +msgstr "Включая рабочие сборки" + +#: objects/ui_Preferences.h:631 +msgid "Check Now" +msgstr "Проверить сейчас" + +#: objects/ui_Preferences.h:632 +msgid "Last checked: " +msgstr "Последняя проверка: " + +#: objects/ui_Preferences.h:634 +msgid "OpenCSG" +msgstr "" + +#: objects/ui_Preferences.h:635 +msgid "Show capability warning" +msgstr "Показывать предупреждение о возможностях" + +#: objects/ui_Preferences.h:636 +msgid "Enable for OpenGL 1.x" +msgstr "Включить для OpenGL 1.x" + +#: objects/ui_Preferences.h:637 +msgid "Turn off rendering at " +msgstr "Отключать отрисовку на " + +#: objects/ui_Preferences.h:638 +msgid "elements" +msgstr "элементах" + +#: objects/ui_Preferences.h:639 +msgid "Force Goldfeather" +msgstr "Принудительно использовать алгоритм Goldfeather («Золотое перо»)" + +#: objects/ui_Preferences.h:640 +msgid "CGAL Cache size" +msgstr "Размер кэша CGAL" + +#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 +msgid "bytes" +msgstr "байт" + +#: objects/ui_Preferences.h:642 +msgid "PolySet Cache size" +msgstr "Размер кэша PolySet" + +#: objects/ui_Preferences.h:644 +msgid "Allow to open multiple documents" +msgstr "" + +#: objects/ui_Preferences.h:645 +msgid "Enable docking of Editor and Console in different places" +msgstr "" + +#: objects/ui_Preferences.h:646 +msgid "Enable undocking of Editor and Console to separate windows" +msgstr "" + +#: objects/ui_Preferences.h:647 +msgid "Show Welcome Screen" +msgstr "" + +#: objects/ui_Preferences.h:648 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" + +#: objects/ui_Preferences.h:649 +msgid "toolBar" +msgstr "" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "" + +#: src/AboutDialog.h:15 +msgid "About OpenSCAD " +msgstr "" + +#: src/mainwin.cc:773 src/mainwin.cc:1315 +msgid "Untitled.scad" +msgstr "Безымянный.scad" + +#: src/mainwin.cc:1314 +msgid "Save File" +msgstr "Сохранить файл" + +#: src/mainwin.cc:1316 +msgid "OpenSCAD Designs (*.scad)" +msgstr "Модели OpenSCAD (*.scad)" + +#: src/mainwin.cc:1326 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" + +#: src/mainwin.cc:1654 +msgid "Application" +msgstr "" + +#: src/mainwin.cc:1655 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" + +#: src/mainwin.cc:1966 src/mainwin.cc:2023 +#, fuzzy +msgid "Export %1 File" +msgstr "Экспортировать в DXF..." + +#: src/mainwin.cc:1967 src/mainwin.cc:2027 +msgid "%1 Files (*%2)" +msgstr "" + +#: src/mainwin.cc:1968 +#, fuzzy +msgid "Untitled" +msgstr "Безымянный.scad" + +#: src/mainwin.cc:2025 +#, fuzzy +msgid "Untitled%1" +msgstr "Безымянный.scad" + +#: src/mainwin.cc:2076 +msgid "Export CSG File" +msgstr "" + +#: src/mainwin.cc:2077 +msgid "Untitled.csg" +msgstr "" + +#: src/mainwin.cc:2078 +msgid "CSG Files (*.csg)" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "Export Image" +msgstr "" + +#: src/mainwin.cc:2104 +msgid "PNG Files (*.png)" +msgstr "" + +#: src/mainwin.cc:2344 +msgid "Console" +msgstr "" + +#: src/mainwin.cc:2471 +#, fuzzy +msgid "The document has been modified." +msgstr "" +"Документ был изменен.\n" +"Сохранить изменения?" + +#: src/mainwin.cc:2472 +#, fuzzy +msgid "Do you want to save your changes?" +msgstr "" +"Документ был изменен.\n" +"Сохранить изменения?" + +#: src/QGLView.cc:114 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" + +#: src/QGLView.cc:131 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:134 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" + +#: src/QGLView.cc:137 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" + +#: src/QGLView.cc:141 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" + +#: src/QGLView.cc:171 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Basics" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Shapes" +msgstr "" + +#: src/UIUtils.cc:85 +msgid "Extrusion" +msgstr "" + +#~ msgid "Off" +#~ msgstr "Выключить" + +#~ msgid "For Light Background" +#~ msgstr "Для светлого фона" + +#~ msgid "For Dark Background" +#~ msgstr "Для тёмного фона" + +#~ msgid "OpenSCAD Designs (*.scad *.csg)" +#~ msgstr "Модели OpenSCAD (*.scad *.csg)" + +#~ msgid "&Compile" +#~ msgstr "&Компилировать" + +#~ msgid "Compile and &Render (CGAL)" +#~ msgstr "Компилировать и &отрисовать (CGAL)" + +#~ msgid "CGAL Grid Only" +#~ msgstr "Только сетка CGAL" diff --git a/openscad.pro b/openscad.pro index 0909281c..9c8c959d 100644 --- a/openscad.pro +++ b/openscad.pro @@ -497,16 +497,16 @@ isEmpty(LOCALE_PREFIX): LOCALE_PREFIX = $$PREFIX/share/openscad/locale QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh # Create install targets for the languages defined in LINGUAS -LINGUAS = $$cat(po/LINGUAS) +LINGUAS = $$cat(locale/LINGUAS) for(language, LINGUAS) { - catalog = po/$$language/LC_MESSAGES/openscad.mo + catalog = locale/$$language/LC_MESSAGES/openscad.mo exists($$catalog) { translation_path = translation_$${language}.path translation_files = translation_$${language}.files translation_depends = translation_$${language}.depends $$translation_path = $$LOCALE_PREFIX/$$language/LC_MESSAGES/ $$translation_files = $$catalog - $$translation_depends = po/$${language}.po + $$translation_depends = locale/$${language}.po INSTALLS += translation_$$language } } diff --git a/po/fr.po b/po/fr.po deleted file mode 100644 index b1958f6a..00000000 --- a/po/fr.po +++ /dev/null @@ -1,1938 +0,0 @@ -# French translations for OpenSCAD package. -# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER -# This file is distributed under the same license as the OpenSCAD package. -# don , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: OpenSCAD 2013.02.07\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-31 21:18+0100\n" -"PO-Revision-Date: 2013-02-08 15:06-0600\n" -"Last-Translator: don bright \n" -"Language-Team: French\n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Poedit-SourceCharset: utf-8\n" - -#: objects/ui_MainWindow.h:470 -msgid "MainWindow" -msgstr "" - -#: objects/ui_MainWindow.h:471 -msgid "&New" -msgstr "&Nouveau" - -#: objects/ui_MainWindow.h:472 -msgid "Ctrl+N" -msgstr "" - -#: objects/ui_MainWindow.h:473 -msgid "&Open..." -msgstr "&Ouvrir..." - -#: objects/ui_MainWindow.h:474 -msgid "Ctrl+O" -msgstr "" - -#: objects/ui_MainWindow.h:475 -msgid "&Save" -msgstr "Enregi&strer" - -#: objects/ui_MainWindow.h:476 -msgid "Ctrl+S" -msgstr "" - -#: objects/ui_MainWindow.h:477 -msgid "Save &As..." -msgstr "Enregistrer &sous..." - -#: objects/ui_MainWindow.h:478 -msgid "Ctrl+Shift+S" -msgstr "" - -#: objects/ui_MainWindow.h:479 -msgid "&Reload" -msgstr "&Recharger" - -#: objects/ui_MainWindow.h:480 -msgid "Ctrl+R" -msgstr "" - -#: objects/ui_MainWindow.h:481 -msgid "&Quit" -msgstr "&Quitter" - -#: objects/ui_MainWindow.h:482 -msgid "Ctrl+Q" -msgstr "" - -#: objects/ui_MainWindow.h:483 -msgid "&Undo" -msgstr "Ann&uler" - -#: objects/ui_MainWindow.h:484 -msgid "Ctrl+Z" -msgstr "" - -#: objects/ui_MainWindow.h:485 -msgid "&Redo" -msgstr "&Refaire" - -#: objects/ui_MainWindow.h:486 -msgid "Ctrl+Shift+Z" -msgstr "" - -#: objects/ui_MainWindow.h:487 -msgid "Cu&t" -msgstr "Co&uper" - -#: objects/ui_MainWindow.h:488 -msgid "Ctrl+X" -msgstr "" - -#: objects/ui_MainWindow.h:489 -msgid "&Copy" -msgstr "&Copier" - -#: objects/ui_MainWindow.h:490 -msgid "Ctrl+C" -msgstr "" - -#: objects/ui_MainWindow.h:491 -msgid "&Paste" -msgstr "&Coller" - -#: objects/ui_MainWindow.h:492 -msgid "Ctrl+V" -msgstr "" - -#: objects/ui_MainWindow.h:493 -msgid "&Indent" -msgstr "&Indenter" - -#: objects/ui_MainWindow.h:494 -msgid "Ctrl+I" -msgstr "" - -#: objects/ui_MainWindow.h:495 -msgid "U&nindent" -msgstr "Dési&ndenter" - -#: objects/ui_MainWindow.h:496 -msgid "Ctrl+Shift+I" -msgstr "" - -#: objects/ui_MainWindow.h:497 -msgid "C&omment" -msgstr "" - -#: objects/ui_MainWindow.h:498 -msgid "Ctrl+D" -msgstr "" - -#: objects/ui_MainWindow.h:499 -msgid "Unco&mment" -msgstr "" - -#: objects/ui_MainWindow.h:500 -msgid "Ctrl+Shift+D" -msgstr "" - -#: objects/ui_MainWindow.h:501 -msgid "Paste viewport translation" -msgstr "" - -#: objects/ui_MainWindow.h:502 -msgid "Ctrl+T" -msgstr "" - -#: objects/ui_MainWindow.h:503 -msgid "Paste viewport rotation" -msgstr "" - -#: objects/ui_MainWindow.h:504 -msgid "Zoom In" -msgstr "Zoom Avant" - -#: objects/ui_MainWindow.h:505 -msgid "Ctrl++" -msgstr "" - -#: objects/ui_MainWindow.h:506 -msgid "Zoom Out" -msgstr "Zoom Arrière" - -#: objects/ui_MainWindow.h:507 -msgid "Ctrl+-" -msgstr "" - -#: objects/ui_MainWindow.h:508 -msgid "Hide editor" -msgstr "" - -#: objects/ui_MainWindow.h:509 -msgid "&Reload and Preview" -msgstr "" - -#: objects/ui_MainWindow.h:510 -msgid "F4" -msgstr "" - -#: objects/ui_MainWindow.h:511 -msgid "&Preview" -msgstr "" - -#: objects/ui_MainWindow.h:512 -msgid "F5" -msgstr "" - -#: objects/ui_MainWindow.h:513 -msgid "&Render" -msgstr "" - -#: objects/ui_MainWindow.h:514 -msgid "F6" -msgstr "" - -#: objects/ui_MainWindow.h:515 -msgid "Display &AST..." -msgstr "" - -#: objects/ui_MainWindow.h:516 -msgid "Display CSG &Tree..." -msgstr "" - -#: objects/ui_MainWindow.h:517 -msgid "Display CSG &Products..." -msgstr "" - -#: objects/ui_MainWindow.h:518 -msgid "Export as &STL..." -msgstr "" - -#: objects/ui_MainWindow.h:519 -msgid "Export as &OFF..." -msgstr "" - -#: objects/ui_MainWindow.h:520 -msgid "Preview" -msgstr "" - -#: objects/ui_MainWindow.h:521 -msgid "F9" -msgstr "" - -#: objects/ui_MainWindow.h:522 -msgid "Surfaces" -msgstr "" - -#: objects/ui_MainWindow.h:523 -msgid "F10" -msgstr "" - -#: objects/ui_MainWindow.h:524 -msgid "Wireframe" -msgstr "" - -#: objects/ui_MainWindow.h:525 -msgid "F11" -msgstr "" - -#: objects/ui_MainWindow.h:526 -msgid "Thrown Together" -msgstr "" - -#: objects/ui_MainWindow.h:527 -msgid "F12" -msgstr "" - -#: objects/ui_MainWindow.h:528 -msgid "Show Edges" -msgstr "" - -#: objects/ui_MainWindow.h:529 -msgid "Ctrl+1" -msgstr "" - -#: objects/ui_MainWindow.h:530 -msgid "Show Axes" -msgstr "Afficher les axes" - -#: objects/ui_MainWindow.h:531 -msgid "Ctrl+2" -msgstr "" - -#: objects/ui_MainWindow.h:532 -msgid "Show Crosshairs" -msgstr "" - -#: objects/ui_MainWindow.h:533 -msgid "Ctrl+3" -msgstr "" - -#: objects/ui_MainWindow.h:534 -msgid "Animate" -msgstr "" - -#: objects/ui_MainWindow.h:535 -msgid "Top" -msgstr "Dessus" - -#: objects/ui_MainWindow.h:536 -msgid "Ctrl+4" -msgstr "" - -#: objects/ui_MainWindow.h:537 -msgid "Bottom" -msgstr "Dessous" - -#: objects/ui_MainWindow.h:538 -msgid "Ctrl+5" -msgstr "" - -#: objects/ui_MainWindow.h:539 -msgid "Left" -msgstr "Gauche" - -#: objects/ui_MainWindow.h:540 -msgid "Ctrl+6" -msgstr "" - -#: objects/ui_MainWindow.h:541 -msgid "Right" -msgstr "Droite" - -#: objects/ui_MainWindow.h:542 -msgid "Ctrl+7" -msgstr "" - -#: objects/ui_MainWindow.h:543 -msgid "Front" -msgstr "Face" - -#: objects/ui_MainWindow.h:544 -msgid "Ctrl+8" -msgstr "" - -#: objects/ui_MainWindow.h:545 -msgid "Back" -msgstr "Arrière" - -#: objects/ui_MainWindow.h:546 -msgid "Ctrl+9" -msgstr "" - -#: objects/ui_MainWindow.h:547 -msgid "Diagonal" -msgstr "" - -#: objects/ui_MainWindow.h:548 -msgid "Ctrl+0" -msgstr "" - -#: objects/ui_MainWindow.h:549 -msgid "Center" -msgstr "" - -#: objects/ui_MainWindow.h:550 -msgid "Ctrl+P" -msgstr "" - -#: objects/ui_MainWindow.h:551 -msgid "Perspective" -msgstr "" - -#: objects/ui_MainWindow.h:552 -msgid "Orthogonal" -msgstr "" - -#: objects/ui_MainWindow.h:553 -msgid "Hide console" -msgstr "" - -#: objects/ui_MainWindow.h:554 -msgid "About" -msgstr "À propos" - -#: objects/ui_MainWindow.h:555 -msgid "Documentation" -msgstr "" - -#: objects/ui_MainWindow.h:556 -msgid "Clear Recent" -msgstr "" - -#: objects/ui_MainWindow.h:557 -msgid "Export as DXF..." -msgstr "" - -#: objects/ui_MainWindow.h:558 -msgid "Close" -msgstr "Fermer" - -#: objects/ui_MainWindow.h:559 -msgid "Ctrl+W" -msgstr "" - -#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:517 -msgid "Preferences" -msgstr "Préférences" - -#: objects/ui_MainWindow.h:561 -msgid "Flush Caches" -msgstr "" - -#: objects/ui_MainWindow.h:562 -msgid "OpenSCAD Homepage" -msgstr "" - -#: objects/ui_MainWindow.h:563 -msgid "Automatic Reload and Preview" -msgstr "" - -#: objects/ui_MainWindow.h:564 -msgid "Export as Image..." -msgstr "" - -#: objects/ui_MainWindow.h:565 -msgid "Export as CSG..." -msgstr "" - -#: objects/ui_MainWindow.h:566 -msgid "Library info" -msgstr "" - -#: objects/ui_MainWindow.h:567 -msgid "Check for Update.." -msgstr "" - -#: objects/ui_MainWindow.h:568 -msgid "Show Library Folder..." -msgstr "" - -#: objects/ui_MainWindow.h:569 -msgid "Reset View" -msgstr "" - -#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:520 -msgid "Editor" -msgstr "" - -#: objects/ui_MainWindow.h:574 -msgid "Editor for SCAD code" -msgstr "" - -#: objects/ui_MainWindow.h:577 -msgid "Console" -msgstr "" - -#: objects/ui_MainWindow.h:580 -msgid "Console messages" -msgstr "" - -#: objects/ui_MainWindow.h:582 -msgid "Time:" -msgstr "" - -#: objects/ui_MainWindow.h:583 -msgid "FPS:" -msgstr "" - -#: objects/ui_MainWindow.h:584 -msgid "Steps:" -msgstr "" - -#: objects/ui_MainWindow.h:585 -msgid "Dump Pictures" -msgstr "" - -#: objects/ui_MainWindow.h:586 -msgid "&File" -msgstr "&Fichier" - -#: objects/ui_MainWindow.h:587 -msgid "Open Recent" -msgstr "" - -#: objects/ui_MainWindow.h:588 -msgid "Examples" -msgstr "&Exemples" - -#: objects/ui_MainWindow.h:589 -msgid "&Edit" -msgstr "&Édition" - -#: objects/ui_MainWindow.h:590 -msgid "&Design" -msgstr "" - -#: objects/ui_MainWindow.h:591 -msgid "&View" -msgstr "&Vue" - -#: objects/ui_MainWindow.h:592 -msgid "&Help" -msgstr "&Aide" - -#: objects/ui_Preferences.h:518 -#, fuzzy -msgid "3D View" -msgstr "&Vue" - -#: objects/ui_Preferences.h:519 -msgid "Advanced" -msgstr "" - -#: objects/ui_Preferences.h:521 -msgid "Update" -msgstr "" - -#: objects/ui_Preferences.h:522 objects/ui_Preferences.h:550 -msgid "Features" -msgstr "" - -#: objects/ui_Preferences.h:524 -msgid "Enable/Disable experimental features" -msgstr "" - -#: objects/ui_Preferences.h:526 -msgid "Color scheme:" -msgstr "" - -#: objects/ui_Preferences.h:531 -msgid "Cornfield" -msgstr "" - -#: objects/ui_Preferences.h:533 -msgid "Metallic" -msgstr "" - -#: objects/ui_Preferences.h:535 -msgid "Sunset" -msgstr "" - -#: objects/ui_Preferences.h:538 -msgid "Font" -msgstr "" - -#: objects/ui_Preferences.h:539 -msgid "Color syntax highlighting" -msgstr "" - -#: objects/ui_Preferences.h:542 -msgid "Off" -msgstr "" - -#: objects/ui_Preferences.h:543 -msgid "For Light Background" -msgstr "" - -#: objects/ui_Preferences.h:544 -msgid "For Dark Background" -msgstr "" - -#: objects/ui_Preferences.h:546 -msgid "Automatically check for updates" -msgstr "" - -#: objects/ui_Preferences.h:547 -msgid "Include development snapshots" -msgstr "" - -#: objects/ui_Preferences.h:548 -msgid "Check Now" -msgstr "" - -#: objects/ui_Preferences.h:549 -msgid "Last checked: " -msgstr "" - -#: objects/ui_Preferences.h:551 -msgid "OpenCSG" -msgstr "" - -#: objects/ui_Preferences.h:552 -msgid "Show capability warning" -msgstr "" - -#: objects/ui_Preferences.h:553 -msgid "Enable for OpenGL 1.x" -msgstr "" - -#: objects/ui_Preferences.h:554 -msgid "Turn off rendering at " -msgstr "" - -#: objects/ui_Preferences.h:555 -msgid "elements" -msgstr "" - -#: objects/ui_Preferences.h:556 -msgid "Force Goldfeather" -msgstr "" - -#: objects/ui_Preferences.h:557 -msgid "CGAL Cache size" -msgstr "" - -#: objects/ui_Preferences.h:558 objects/ui_Preferences.h:560 -msgid "bytes" -msgstr "" - -#: objects/ui_Preferences.h:559 -msgid "PolySet Cache size" -msgstr "" - -#: objects/ui_Preferences.h:561 -msgid "Enable user interface localization (requires restart of OpenSCAD)" -msgstr "" - -#: objects/ui_Preferences.h:562 -msgid "toolBar" -msgstr "" - -#: src/AboutDialog.h:16 -msgid "About OpenSCAD " -msgstr "" - -#: src/cache.h:181 -msgid "Trimming cache: %1% (%2% bytes)" -msgstr "" - -#: src/CGAL_Nef3_workaround.h:256 -#, c-format -msgid "WARNING: CGAL NefPolyhedron Triangulation failed: %s" -msgstr "" - -#: src/CsgInfo.h:48 -msgid "Error: CSG generation failed! (no top level object found)" -msgstr "" - -#: src/CsgInfo.h:53 src/mainwin.cc:818 -msgid "Compiling design (CSG Products normalization)..." -msgstr "" - -#: src/CsgInfo.h:60 src/mainwin.cc:865 -#, c-format -msgid "Normalized CSG tree has %d elements" -msgstr "" - -#: src/CsgInfo.h:64 src/mainwin.cc:830 -msgid "WARNING: CSG normalization resulted in an empty tree" -msgstr "" - -#: src/CsgInfo.h:69 -#, c-format -msgid "Compiling highlights (%i CSG Trees)..." -msgstr "" - -#: src/CsgInfo.h:79 -#, c-format -msgid "Compiling background (%i CSG Trees)..." -msgstr "" - -#: src/CGALCache.cc:15 -#, c-format -msgid "CGAL Cache hit: %s (%d bytes)" -msgstr "" - -#: src/CGALCache.cc:24 -#, c-format -msgid "CGAL Cache insert: %s (%d bytes)" -msgstr "" - -#: src/CGALCache.cc:25 -#, c-format -msgid "CGAL Cache insert failed: %s (%d bytes)" -msgstr "" - -#: src/CGALCache.cc:47 -#, c-format -msgid "CGAL Polyhedrons in cache: %d" -msgstr "" - -#: src/CGALCache.cc:48 -#, c-format -msgid "CGAL cache size in bytes: %d" -msgstr "" - -#: src/CGAL_Nef_polyhedron.cc:74 src/cgalutils.cc:44 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." -msgstr "" - -#: src/CGAL_Nef_polyhedron.cc:75 src/cgalutils.cc:45 src/PlatformUtils.cc:19 -#, c-format -msgid "ERROR: %s" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:49 -msgid "Warning: Scaling a 3D object with 0 - removing object" -msgstr "" - -#: src/cgalutils.cc:30 -msgid "" -"Hull() currently requires a valid 2-manifold. Please modify your design. See " -"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" -msgstr "" - -#: src/cgalutils.cc:107 -#, c-format -msgid "ERROR: Unsupported CGAL operator: %d" -msgstr "" - -#: src/cgalutils.cc:113 -#, c-format -msgid "CGAL error in CGALUtils::applyBinaryOperator %s: %s" -msgstr "" - -#: src/cgalutils.cc:159 -#, c-format -msgid "CGALUtils::project during plane intersection: %s" -msgstr "" - -#: src/cgalutils.cc:161 -msgid "Trying alternative intersection using very large thin box: " -msgstr "" - -#: src/cgalutils.cc:176 -#, c-format -msgid "CGAL error in CGALUtils::project during bigbox intersection: %s" -msgstr "" - -#: src/cgalutils.cc:182 -msgid "WARNING: projection() failed." -msgstr "" - -#: src/cgalutils.cc:204 -#, c-format -msgid "CGAL error in CGALUtils::project while flattening: %s" -msgstr "" - -#: src/cgalutils.cc:496 -msgid "ERROR: deproject failure" -msgstr "" - -#: src/cgalutils.cc:582 -msgid "ERROR: failed to find projection" -msgstr "" - -#: src/cgalutils.cc:593 -msgid "input polygon has 3 points. shortcut tessellation." -msgstr "" - -#: src/cgalutils.cc:605 -msgid "finding good projection" -msgstr "" - -#: src/cgalutils.cc:608 -#, c-format -msgid "plane %s" -msgstr "" - -#: src/cgalutils.cc:609 -#, c-format -msgid "proj: %i %i" -msgstr "" - -#: src/cgalutils.cc:610 -msgid "Inserting points and edges into Constrained Delaunay Triangulation" -msgstr "" - -#: src/cgalutils.cc:632 -#, c-format -msgid "WARNING: Constraint insertion failure %s" -msgstr "" - -#: src/cgalutils.cc:639 -#, c-format -msgid "seeding %i holes" -msgstr "" - -#: src/cgalutils.cc:660 -#, c-format -msgid "seed %f,%f" -msgstr "" - -#: src/cgalutils.cc:662 -msgid "seeding done" -msgstr "" - -#: src/cgalutils.cc:664 -msgid "meshing" -msgstr "" - -#: src/cgalutils.cc:669 -msgid "meshing done" -msgstr "" - -#: src/cgalutils.cc:690 -msgid "WARNING: 2d->3d deprojection failure" -msgstr "" - -#: src/cgalutils.cc:698 -#, c-format -msgid "built %i triangles\n" -msgstr "" - -#: src/cgalutils.cc:741 -msgid "WARNING: triangle doesn't have 3 points. skipping" -msgstr "" - -#: src/cgalutils.cc:941 -#, c-format -msgid "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" -msgstr "" - -#: src/cgalutils.cc:1021 -msgid "PolySet has nonplanar faces. Attempting alternate construction" -msgstr "" - -#: src/cgalutils.cc:1025 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "" - -#: src/cgalutils.cc:1036 -#, c-format -msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "" - -#: src/cgalworker.cc:36 -msgid "Rendering cancelled." -msgstr "" - -#: src/color.cc:69 -#, c-format -msgid "" -"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " -"large." -msgstr "" - -#: src/color.cc:81 -#, c-format -msgid "WARNING: Color name \"%s\" unknown. Please see" -msgstr "" - -#: src/color.cc:82 -msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" -msgstr "" - -#: src/context.cc:97 -#, c-format -msgid "WARNING: Attempt to modify constant '%s'." -msgstr "" - -#: src/context.cc:121 -#, c-format -msgid "WARNING: Ignoring unknown variable '%s'." -msgstr "" - -#: src/context.cc:128 -#, c-format -msgid "WARNING: Ignoring unknown function '%s'." -msgstr "" - -#: src/context.cc:135 -#, c-format -msgid "WARNING: Ignoring unknown module '%s'." -msgstr "" - -#: src/context.cc:156 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p)" -msgstr "" - -#: src/context.cc:158 src/evalcontext.cc:40 -#, c-format -msgid "Context: %p (%p)" -msgstr "" - -#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 -#, c-format -msgid " document path: %s" -msgstr "" - -#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 -msgid " module args:" -msgstr "" - -#: src/context.cc:170 src/modcontext.cc:159 -msgid " vars:" -msgstr "" - -#: src/control.cc:83 -#, c-format -msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." -msgstr "" - -#: src/control.cc:133 src/control.cc:138 src/control.cc:247 -#, c-format -msgid "" -"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " -"vector, range." -msgstr "" - -#: src/control.cc:144 -#, c-format -msgid "WARNING: Negative children index (%d) not allowed" -msgstr "" - -#: src/control.cc:150 -#, c-format -msgid "WARNING: Children index (%d) out of bounds (%d children)" -msgstr "" - -#: src/control.cc:170 -#, c-format -msgid "WARNING: Negative child index (%d) not allowed" -msgstr "" - -#: src/control.cc:189 -#, c-format -msgid "WARNING: Child index (%d) out of bounds (%d children)" -msgstr "" - -#: src/control.cc:234 -#, c-format -msgid "WARNING: Bad range parameter for children: too many elements (%lu)." -msgstr "" - -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 -#, c-format -msgid "" -"WARNING: Normalized tree is growing past %d elements. Aborting " -"normalization.\n" -msgstr "" - -#: src/dxfdata.cc:84 -#, c-format -msgid "WARNING: Can't open DXF file '%s'." -msgstr "" - -#: src/dxfdata.cc:148 -#, c-format -msgid "WARNING: Illegal ID '%s' in `%s'" -msgstr "" - -#: src/dxfdata.cc:387 -#, c-format -msgid "WARNING: Illegal value %s in '%s'" -msgstr "" - -#: src/dxfdata.cc:393 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." -msgstr "" - -#: src/dxfdata.cc:396 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." -msgstr "" - -#: src/dxfdim.cc:131 -#, c-format -msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" -msgstr "" - -#: src/dxfdim.cc:136 -#, c-format -msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" -msgstr "" - -#: src/dxfdim.cc:211 -#, c-format -msgid "WARNING: Can't find cross in '%s', layer '%s'!" -msgstr "" - -#: src/evalcontext.cc:38 -#, c-format -msgid "EvalContext %p (%p) for %s inst (%p)" -msgstr "" - -#: src/evalcontext.cc:43 -msgid " eval args:" -msgstr "" - -#: src/evalcontext.cc:48 -msgid " children:" -msgstr "" - -#: src/export.cc:180 src/export.cc:225 -msgid "Object isn't a valid 2-manifold! Modify your design.\n" -msgstr "" - -#: src/export.cc:187 -msgid "ERROR: Nef->PolySet failed" -msgstr "" - -#: src/export.cc:199 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" -msgstr "" - -#: src/export.cc:205 src/export.cc:234 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" -msgstr "" - -#: src/export.cc:208 -msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" -msgstr "" - -#: src/expr.cc:166 -#, c-format -msgid "ERROR: Recursion detected calling function '%s'" -msgstr "" - -#: src/feature.cc:21 -msgid "Enable the concat() function." -msgstr "" - -#: src/feature.cc:60 -#, c-format -msgid "WARNING: Ignoring request to enable unknown feature '%s'." -msgstr "" - -#: src/fileutils.cc:25 -#, c-format -msgid "" -"WARNING: Imported file (%s) found in document root instead of relative to " -"the importing module. This behavior is deprecated" -msgstr "" - -#: src/func.cc:503 src/func.cc:536 -#, c-format -msgid " WARNING: search term not found: \"%s\"" -msgstr "" - -#: src/func.cc:533 -#, c-format -msgid " WARNING: search term not found: %s" -msgstr "" - -#: src/func.cc:545 -#, c-format -msgid " WARNING: search: none performed on input %s" -msgstr "" - -#: src/func.cc:591 -#, c-format -msgid "WARNING: Negative parent module index (%d) not allowed" -msgstr "" - -#: src/func.cc:595 -#, c-format -msgid "" -"WARNING: Parent module index (%d) greater than the number of modules on the " -"stack" -msgstr "" - -#: src/GeometryCache.cc:14 -#, c-format -msgid "Geometry Cache hit: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:24 -#, c-format -msgid "Geometry Cache insert: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:26 -#, c-format -msgid "Geometry Cache insert failed: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:44 -#, c-format -msgid "Geometries in cache: %d" -msgstr "" - -#: src/GeometryCache.cc:45 -#, c-format -msgid "Geometry cache size in bytes: %d" -msgstr "" - -#: src/GeometryEvaluator.cc:76 -msgid "WARNING: Mixing 2D and 3D objects is not supported." -msgstr "" - -#: src/GeometryEvaluator.cc:188 -msgid "WARNING: Resize in direction normal to flat object is not implemented" -msgstr "" - -#: src/GeometryEvaluator.cc:252 -msgid "WARNING: Ignoring 3D child object for 2D operation" -msgstr "" - -#: src/GeometryEvaluator.cc:276 -msgid "WARNING: GeometryEvaluator: Node didn't fit into cache" -msgstr "" - -#: src/GeometryEvaluator.cc:324 -msgid "WARNING: Ignoring 2D child object for 3D operation" -msgstr "" - -#: src/GeometryEvaluator.cc:365 -#, c-format -msgid "Error: Unknown boolean operation %d" -msgstr "" - -#: src/GeometryEvaluator.cc:517 -msgid "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." -msgstr "" - -#: src/GeometryEvaluator.cc:765 -#, c-format -msgid "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" -msgstr "" - -#: src/handle_dep.cc:36 -#, c-format -msgid "Can't open dependencies file `%s' for writing!\n" -msgstr "" - -#: src/import.cc:98 -msgid "DEPRECATED: filename= is deprecated. Please use file=" -msgstr "" - -#: src/import.cc:122 -msgid "DEPRECATED: layername= is deprecated. Please use layer=" -msgstr "" - -#: src/import.cc:201 src/import.cc:286 -#, c-format -msgid "WARNING: Can't open import file '%s'." -msgstr "" - -#: src/import.cc:251 -#, c-format -msgid "WARNING: Can't parse vertex line '%s'." -msgstr "" - -#: src/import.cc:295 -msgid "WARNING: OFF import requires CGAL." -msgstr "" - -#: src/import.cc:305 -#, c-format -msgid "ERROR: Unsupported file format while trying to import file '%s'" -msgstr "" - -#: src/linearextrude.cc:77 -msgid "" -"DEPRECATED: Support for reading files in linear_extrude will be removed in " -"future releases. Use a child import() instead." -msgstr "" - -#: src/mainwin.cc:118 -msgid "" -"Copyright (C) 2009-2013 The OpenSCAD Developers\n" -"\n" -"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." -msgstr "" - -#: src/mainwin.cc:523 -msgid "OpenSCAD - New Document[*]" -msgstr "" - -#: src/mainwin.cc:527 -msgid "OpenSCAD - " -msgstr "" - -#: src/mainwin.cc:527 -msgid "[*]" -msgstr "" - -#: src/mainwin.cc:601 -#, c-format -msgid "Failed to open file %s: %s" -msgstr "" - -#: src/mainwin.cc:608 -#, c-format -msgid "Loaded design '%s'." -msgstr "" - -#: src/mainwin.cc:655 -#, c-format -msgid "Module cache size: %d modules" -msgstr "" - -#: src/mainwin.cc:739 -msgid "Compiling design (CSG Tree generation)..." -msgstr "" - -#: src/mainwin.cc:765 -msgid "ERROR: Compilation failed! (no top level object found)" -msgstr "" - -#: src/mainwin.cc:767 -msgid "ERROR: Compilation failed!" -msgstr "" - -#: src/mainwin.cc:780 -msgid "Compiling design (CSG Products generation)..." -msgstr "" - -#: src/mainwin.cc:801 -msgid "ERROR: CSG generation failed! (no top level object found)" -msgstr "" - -#: src/mainwin.cc:810 -msgid "CSG generation cancelled." -msgstr "" - -#: src/mainwin.cc:836 -#, c-format -msgid "Compiling highlights (%d CSG Trees)..." -msgstr "" - -#: src/mainwin.cc:848 -#, c-format -msgid "Compiling background (%d CSG Trees)..." -msgstr "" - -#: src/mainwin.cc:861 -#, c-format -msgid "WARNING: Normalized tree has %d elements!" -msgstr "" - -#: src/mainwin.cc:862 -msgid "WARNING: OpenCSG rendering has been disabled." -msgstr "" - -#: src/mainwin.cc:875 -msgid "CSG generation finished." -msgstr "" - -#: src/mainwin.cc:877 src/mainwin.cc:1315 -#, c-format -msgid "Total rendering time: %d hours, %d minutes, %d seconds" -msgstr "" - -#: src/mainwin.cc:904 -msgid "Open File" -msgstr "Ouvrir un fichier" - -#: src/mainwin.cc:905 -msgid "OpenSCAD Designs (*.scad *.csg)" -msgstr "" - -#: src/mainwin.cc:999 -#, c-format -msgid "Failed to open file for writing: %s (%s)" -msgstr "" - -#: src/mainwin.cc:1000 -msgid "" -"Failed to open file for writing:\n" -" %1 (%2)" -msgstr "" - -#: src/mainwin.cc:1007 -#, c-format -msgid "Saved design '%s'." -msgstr "" - -#: src/mainwin.cc:1017 -msgid "Save File" -msgstr "" - -#: src/mainwin.cc:1018 -msgid "Untitled.scad" -msgstr "" - -#: src/mainwin.cc:1019 -msgid "OpenSCAD Designs (*.scad)" -msgstr "" - -#: src/mainwin.cc:1029 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" - -#: src/mainwin.cc:1044 -#, c-format -msgid "WARNING: Library path %s doesn't exist. Creating" -msgstr "" - -#: src/mainwin.cc:1046 -#, c-format -msgid "ERROR: Cannot create library path: %s" -msgstr "" - -#: src/mainwin.cc:1181 src/mainwin.cc:1846 -msgid "Application" -msgstr "" - -#: src/mainwin.cc:1182 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" - -#: src/mainwin.cc:1232 src/mainwin.cc:1276 -msgid "Parsing design (AST generation)..." -msgstr "" - -#: src/mainwin.cc:1260 -#, c-format -msgid "frame%05d.png" -msgstr "" - -#: src/mainwin.cc:1294 -msgid "Rendering Polygon Mesh using CGAL..." -msgstr "" - -#: src/mainwin.cc:1320 src/mainwin.cc:1334 -msgid " Top level object is a 3D object:" -msgstr "" - -#: src/mainwin.cc:1321 -#, c-format -msgid " Simple: %6s" -msgstr "" - -#: src/mainwin.cc:1321 src/mainwin.cc:1322 -msgid "yes" -msgstr "" - -#: src/mainwin.cc:1321 src/mainwin.cc:1322 -msgid "no" -msgstr "" - -#: src/mainwin.cc:1322 -#, c-format -msgid " Valid: %6s" -msgstr "" - -#: src/mainwin.cc:1323 -#, c-format -msgid " Vertices: %6d" -msgstr "" - -#: src/mainwin.cc:1324 -#, c-format -msgid " Halfedges: %6d" -msgstr "" - -#: src/mainwin.cc:1325 -#, c-format -msgid " Edges: %6d" -msgstr "" - -#: src/mainwin.cc:1326 -#, c-format -msgid " Halffacets: %6d" -msgstr "" - -#: src/mainwin.cc:1327 src/mainwin.cc:1335 -#, c-format -msgid " Facets: %6d" -msgstr "" - -#: src/mainwin.cc:1328 -#, c-format -msgid " Volumes: %6d" -msgstr "" - -#: src/mainwin.cc:1337 -msgid " Top level object is a 2D object:" -msgstr "" - -#: src/mainwin.cc:1338 -#, c-format -msgid " Contours: %6d" -msgstr "" - -#: src/mainwin.cc:1340 -msgid "Unknown geometry type" -msgstr "" - -#: src/mainwin.cc:1342 -msgid "Rendering finished." -msgstr "" - -#: src/mainwin.cc:1351 -msgid "WARNING: No top level geometry to render" -msgstr "" - -#: src/mainwin.cc:1368 -msgid "AST Dump" -msgstr "" - -#: src/mainwin.cc:1373 -msgid "No AST to dump. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1386 -msgid "CSG Tree Dump" -msgstr "" - -#: src/mainwin.cc:1391 -msgid "No CSG to dump. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1404 -msgid "CSG Products Dump" -msgstr "" - -#: src/mainwin.cc:1406 -msgid "" -"\n" -"CSG before normalization:\n" -"%1\n" -"\n" -"\n" -"CSG after normalization:\n" -"%2\n" -"\n" -"\n" -"CSG rendering chain:\n" -"%3\n" -"\n" -"\n" -"Highlights CSG rendering chain:\n" -"%4\n" -"\n" -"\n" -"Background CSG rendering chain:\n" -"%5\n" -msgstr "" - -#: src/mainwin.cc:1429 src/mainwin.cc:1490 -msgid "Nothing to export! Try building first (press F6)." -msgstr "" - -#: src/mainwin.cc:1435 -msgid "Current top level object is not a 3D object." -msgstr "" - -#: src/mainwin.cc:1442 -msgid "" -"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." -"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" -msgstr "" - -#: src/mainwin.cc:1449 -msgid "Export STL File" -msgstr "" - -#: src/mainwin.cc:1449 -msgid "Export OFF File" -msgstr "" - -#: src/mainwin.cc:1451 -msgid "STL Files (*.stl)" -msgstr "" - -#: src/mainwin.cc:1451 -msgid "OFF Files (*.off)" -msgstr "" - -#: src/mainwin.cc:1453 -#, c-format -msgid "No filename specified. %s export aborted." -msgstr "" - -#: src/mainwin.cc:1460 src/mainwin.cc:1513 src/mainwin.cc:1546 -#: src/openscad.cc:313 src/openscad.cc:325 src/openscad.cc:343 -#: src/openscad.cc:391 src/openscad.cc:406 src/openscad.cc:421 -#: src/openscad.cc:432 -#, c-format -msgid "Can't open file \"%s\" for export" -msgstr "" - -#: src/mainwin.cc:1467 -#, c-format -msgid "%s export finished." -msgstr "" - -#: src/mainwin.cc:1496 -msgid "Current top level object is not a 2D object." -msgstr "" - -#: src/mainwin.cc:1502 -msgid "Export DXF File" -msgstr "" - -#: src/mainwin.cc:1503 -msgid "Untitled.dxf" -msgstr "" - -#: src/mainwin.cc:1504 -msgid "DXF Files (*.dxf)" -msgstr "" - -#: src/mainwin.cc:1506 -msgid "No filename specified. DXF export aborted." -msgstr "" - -#: src/mainwin.cc:1518 -msgid "DXF export finished." -msgstr "" - -#: src/mainwin.cc:1530 -msgid "Nothing to export. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1535 -msgid "Export CSG File" -msgstr "" - -#: src/mainwin.cc:1536 -msgid "Untitled.csg" -msgstr "" - -#: src/mainwin.cc:1537 -msgid "CSG Files (*.csg)" -msgstr "" - -#: src/mainwin.cc:1539 -msgid "No filename specified. CSG export aborted." -msgstr "" - -#: src/mainwin.cc:1551 -msgid "CSG export finished." -msgstr "" - -#: src/mainwin.cc:1562 -msgid "Export Image" -msgstr "" - -#: src/mainwin.cc:1562 -msgid "PNG Files (*.png)" -msgstr "" - -#: src/mainwin.cc:1564 -msgid "No filename specified. Image export aborted." -msgstr "" - -#: src/mainwin.cc:1816 -msgid "http://openscad.org/" -msgstr "" - -#: src/mainwin.cc:1822 -msgid "http://www.openscad.org/documentation.html" -msgstr "" - -#: src/mainwin.cc:1831 -msgid "OpenGL Info" -msgstr "Information OpenGL" - -#: src/mainwin.cc:1831 -msgid "OpenSCAD Detailed Library and Build Information" -msgstr "" - -#: src/mainwin.cc:1847 -msgid "" -"The document has been modified.\n" -"Do you want to save your changes?" -msgstr "" - -#: src/modcontext.cc:100 -#, c-format -msgid "WARNING: Experimental builtin function '%s' is not enabled." -msgstr "" - -#: src/modcontext.cc:113 -#, c-format -msgid "WARNING: Experimental builtin module '%s' is not enabled." -msgstr "" - -#: src/modcontext.cc:118 -#, c-format -msgid "" -"DEPRECATED: The %s() module will be removed in future releases. Use %s() " -"instead." -msgstr "" - -#: src/modcontext.cc:145 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p) " -msgstr "" - -#: src/modcontext.cc:147 -#, c-format -msgid "ModuleContext: %p (%p)" -msgstr "" - -#: src/modcontext.cc:193 -#, c-format -msgid "New lib Context for %s func:" -msgstr "" - -#: src/modcontext.cc:217 -msgid "New file Context:" -msgstr "" - -#: src/ModuleCache.cc:70 -#, c-format -msgid "Recompiling cached library: %s (%s)" -msgstr "" - -#: src/ModuleCache.cc:73 -#, c-format -msgid "Compiling library '%s'." -msgstr "" - -#: src/ModuleCache.cc:81 -#, c-format -msgid "WARNING: Can't open library file '%s'\n" -msgstr "" - -#: src/ModuleCache.cc:99 -#, c-format -msgid " compiled module: %p" -msgstr "" - -#: src/module.cc:139 -msgid "New eval ctx:" -msgstr "" - -#: src/module.cc:180 -#, c-format -msgid "ERROR: Recursion detected calling module '%s'" -msgstr "" - -#: src/module.cc:298 -#, c-format -msgid "WARNING: Failed to compile library '%s'." -msgstr "" - -#: src/OffscreenView.cc:27 -msgid "OpenSCAD recommended OpenGL version is 2.0." -msgstr "" - -#: src/openscad.cc:107 -msgid "" -"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" -"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" -"%2%[ --version ] [ --info ] \\\n" -"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" -"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" -"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" -"%2%[ --render | --preview[=throwntogether] ] \\\n" -"%2%[ --enable= ] \\\n" -"%2%filename\n" -msgstr "" - -#: src/openscad.cc:124 -#, c-format -msgid "OpenSCAD version %s\n" -msgstr "" - -#: src/openscad.cc:136 -#, c-format -msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" -msgstr "" - -#: src/openscad.cc:180 -msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" -msgstr "" - -#: src/openscad.cc:181 -msgid "or 6 numbers for Vector Camera\n" -msgstr "" - -#: src/openscad.cc:197 -msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" -msgstr "" - -#: src/openscad.cc:208 -msgid "Need 2 numbers for imgsize\n" -msgstr "" - -#: src/openscad.cc:257 -#, c-format -msgid "Unknown suffix for output file %s\n" -msgstr "" - -#: src/openscad.cc:281 -#, c-format -msgid "Can't open input file '%s'!\n" -msgstr "" - -#: src/openscad.cc:290 -#, c-format -msgid "Can't parse file '%s'!\n" -msgstr "" - -#: src/openscad.cc:373 -#, c-format -msgid "Output file:%s\n" -msgstr "" - -#: src/openscad.cc:374 -msgid "Sorry, don't know how to write deps for that file type. Exiting\n" -msgstr "" - -#: src/openscad.cc:379 -msgid "error writing deps" -msgstr "" - -#: src/openscad.cc:386 src/openscad.cc:401 -msgid "Current top level object is not a 3D object.\n" -msgstr "" - -#: src/openscad.cc:416 -msgid "Current top level object is not a 2D object.\n" -msgstr "" - -#: src/openscad.cc:594 -msgid "Allowed options" -msgstr "" - -#: src/openscad.cc:596 -msgid "help message" -msgstr "" - -#: src/openscad.cc:597 -msgid "print the version" -msgstr "" - -#: src/openscad.cc:598 -msgid "print information about the building process" -msgstr "" - -#: src/openscad.cc:599 -msgid "if exporting a png image, do a full CGAL render" -msgstr "" - -#: src/openscad.cc:600 -msgid "" -"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" -msgstr "" - -#: src/openscad.cc:601 -msgid "parameters for camera when exporting png" -msgstr "" - -#: src/openscad.cc:602 -msgid "=width,height for exporting png" -msgstr "" - -#: src/openscad.cc:603 -msgid "(o)rtho or (p)erspective when exporting png" -msgstr "" - -#: src/openscad.cc:604 -msgid "out-file" -msgstr "" - -#: src/openscad.cc:605 -msgid "stl-file" -msgstr "" - -#: src/openscad.cc:606 -msgid "dxf-file" -msgstr "" - -#: src/openscad.cc:607 -msgid "deps-file" -msgstr "" - -#: src/openscad.cc:608 -msgid "makefile" -msgstr "" - -#: src/openscad.cc:609 -msgid "var=val" -msgstr "" - -#: src/openscad.cc:610 -msgid "enable experimental features" -msgstr "" - -#: src/openscad.cc:612 -msgid "Hidden options" -msgstr "" - -#: src/openscad.cc:614 -msgid "input file" -msgstr "" - -#: src/openscad.cc:648 -msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" -msgstr "" - -#: src/openscad.cc:653 -msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" -msgstr "" - -#: src/openscad.cc:710 -msgid "Requested GUI mode but can't open display!\n" -msgstr "" - -#: src/PlatformUtils.cc:16 -#, c-format -msgid "ERROR: Cannot create %s" -msgstr "" - -#: src/polyset.cc:63 -msgid "PolySet:" -msgstr "" - -#: src/polyset.cc:64 -msgid "" -"\n" -" dimensions:" -msgstr "" - -#: src/polyset.cc:65 -msgid "" -"\n" -" convexity:" -msgstr "" - -#: src/polyset.cc:66 -msgid "" -"\n" -" num polygons: " -msgstr "" - -#: src/polyset.cc:67 -msgid "" -"\n" -" num outlines: " -msgstr "" - -#: src/polyset.cc:68 -msgid "" -"\n" -" polygons data:" -msgstr "" - -#: src/polyset.cc:70 -msgid "" -"\n" -" polygon begin:" -msgstr "" - -#: src/polyset.cc:74 -msgid "" -"\n" -" vertex:" -msgstr "" - -#: src/polyset.cc:77 -msgid "" -"\n" -" outlines data:" -msgstr "" - -#: src/polyset.cc:79 -msgid "" -"\n" -"PolySet end" -msgstr "" - -#: src/primitives.cc:134 -#, c-format -msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." -msgstr "" - -#: src/primitives.cc:187 -#, c-format -msgid "WARNING: $fs too small - clamping to %f" -msgstr "" - -#: src/primitives.cc:191 -#, c-format -msgid "WARNING: $fa too small - clamping to %f" -msgstr "" - -#: src/primitives.cc:248 -msgid "" -"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " -"polyhedron(faces=[]) instead." -msgstr "" - -#: src/primitives.cc:515 -#, c-format -msgid "ERROR: Unable to convert point at index %d to a vec3 of numbers" -msgstr "" - -#: src/primitives.cc:575 -#, c-format -msgid "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" -msgstr "" - -#: src/QGLView.cc:105 -msgid "" -"\n" -"Using QGLWidget\n" -"\n" -msgstr "" - -#: src/QGLView.cc:122 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" - -#: src/QGLView.cc:125 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" -msgstr "" - -#: src/QGLView.cc:128 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" -msgstr "" - -#: src/QGLView.cc:132 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" - -#: src/QGLView.cc:163 -#, c-format -msgid "" -"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " -"distance = %.2f" -msgstr "" - -#: src/rotateextrude.cc:71 -msgid "" -"DEPRECATED: Support for reading files in rotate_extrude will be removed in " -"future releases. Use a child import() instead." -msgstr "" - -#: src/surface.cc:107 -#, c-format -msgid "WARNING: Can't open DAT file '%s'." -msgstr "" - -#: src/surface.cc:139 -#, c-format -msgid "WARNING: Illegal value in '%s': %s" -msgstr "" - -#: src/value.cc:644 -msgid "" -"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " -"than the end value is deprecated." -msgstr "" - -#, fuzzy -#~ msgid "OpenGL Warning" -#~ msgstr "Information OpenGL" diff --git a/po/ru.po b/po/ru.po deleted file mode 100644 index cf2fce7c..00000000 --- a/po/ru.po +++ /dev/null @@ -1,1950 +0,0 @@ -# Russian translations for OpenSCAD package. -# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER -# This file is distributed under the same license as the OpenSCAD package. -# , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: OpenSCAD 2014.01.05\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-31 21:18+0100\n" -"PO-Revision-Date: 2013-02-24 17:50+0100\n" -"Last-Translator: \n" -"Language-Team: Russian\n" -"Language: ru\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" - -#: objects/ui_MainWindow.h:470 -msgid "MainWindow" -msgstr "" - -#: objects/ui_MainWindow.h:471 -msgid "&New" -msgstr "&Создать" - -#: objects/ui_MainWindow.h:472 -msgid "Ctrl+N" -msgstr "" - -#: objects/ui_MainWindow.h:473 -msgid "&Open..." -msgstr "&Открыть..." - -#: objects/ui_MainWindow.h:474 -msgid "Ctrl+O" -msgstr "" - -#: objects/ui_MainWindow.h:475 -msgid "&Save" -msgstr "&Сохранить" - -#: objects/ui_MainWindow.h:476 -msgid "Ctrl+S" -msgstr "" - -#: objects/ui_MainWindow.h:477 -msgid "Save &As..." -msgstr "Сохранить &как..." - -#: objects/ui_MainWindow.h:478 -msgid "Ctrl+Shift+S" -msgstr "" - -#: objects/ui_MainWindow.h:479 -msgid "&Reload" -msgstr "&Обновить" - -#: objects/ui_MainWindow.h:480 -msgid "Ctrl+R" -msgstr "" - -#: objects/ui_MainWindow.h:481 -msgid "&Quit" -msgstr "&Выход" - -#: objects/ui_MainWindow.h:482 -msgid "Ctrl+Q" -msgstr "" - -#: objects/ui_MainWindow.h:483 -msgid "&Undo" -msgstr "&Отменить" - -#: objects/ui_MainWindow.h:484 -msgid "Ctrl+Z" -msgstr "" - -#: objects/ui_MainWindow.h:485 -msgid "&Redo" -msgstr "&Повторить" - -#: objects/ui_MainWindow.h:486 -msgid "Ctrl+Shift+Z" -msgstr "" - -#: objects/ui_MainWindow.h:487 -msgid "Cu&t" -msgstr "Вы&резать" - -#: objects/ui_MainWindow.h:488 -msgid "Ctrl+X" -msgstr "" - -#: objects/ui_MainWindow.h:489 -msgid "&Copy" -msgstr "&Копировать" - -#: objects/ui_MainWindow.h:490 -msgid "Ctrl+C" -msgstr "" - -#: objects/ui_MainWindow.h:491 -msgid "&Paste" -msgstr "&Вставить" - -#: objects/ui_MainWindow.h:492 -msgid "Ctrl+V" -msgstr "" - -#: objects/ui_MainWindow.h:493 -msgid "&Indent" -msgstr "&Добавить отступ" - -#: objects/ui_MainWindow.h:494 -msgid "Ctrl+I" -msgstr "" - -#: objects/ui_MainWindow.h:495 -msgid "U&nindent" -msgstr "У&брать отступ" - -#: objects/ui_MainWindow.h:496 -msgid "Ctrl+Shift+I" -msgstr "" - -#: objects/ui_MainWindow.h:497 -msgid "C&omment" -msgstr "Зако&мментировать" - -#: objects/ui_MainWindow.h:498 -msgid "Ctrl+D" -msgstr "" - -#: objects/ui_MainWindow.h:499 -msgid "Unco&mment" -msgstr "Р&аскомментировать" - -#: objects/ui_MainWindow.h:500 -msgid "Ctrl+Shift+D" -msgstr "" - -#: objects/ui_MainWindow.h:501 -msgid "Paste viewport translation" -msgstr "Вставить смещение точки обзора" - -#: objects/ui_MainWindow.h:502 -msgid "Ctrl+T" -msgstr "" - -#: objects/ui_MainWindow.h:503 -msgid "Paste viewport rotation" -msgstr "Вставить поворот точки обзора" - -#: objects/ui_MainWindow.h:504 -msgid "Zoom In" -msgstr "Увеличить масштаб" - -#: objects/ui_MainWindow.h:505 -msgid "Ctrl++" -msgstr "" - -#: objects/ui_MainWindow.h:506 -msgid "Zoom Out" -msgstr "Уменьшить масштаб" - -#: objects/ui_MainWindow.h:507 -msgid "Ctrl+-" -msgstr "" - -#: objects/ui_MainWindow.h:508 -msgid "Hide editor" -msgstr "Скрыть редактор" - -#: objects/ui_MainWindow.h:509 -#, fuzzy -msgid "&Reload and Preview" -msgstr "&Обновить и компилировать" - -#: objects/ui_MainWindow.h:510 -msgid "F4" -msgstr "" - -#: objects/ui_MainWindow.h:511 -msgid "&Preview" -msgstr "" - -#: objects/ui_MainWindow.h:512 -msgid "F5" -msgstr "" - -#: objects/ui_MainWindow.h:513 -msgid "&Render" -msgstr "" - -#: objects/ui_MainWindow.h:514 -msgid "F6" -msgstr "" - -#: objects/ui_MainWindow.h:515 -msgid "Display &AST..." -msgstr "Показать &AST..." - -#: objects/ui_MainWindow.h:516 -msgid "Display CSG &Tree..." -msgstr "Показать &дерево CSG..." - -#: objects/ui_MainWindow.h:517 -msgid "Display CSG &Products..." -msgstr "Показать &результаты CSG..." - -#: objects/ui_MainWindow.h:518 -msgid "Export as &STL..." -msgstr "Экспортировать в &STL..." - -#: objects/ui_MainWindow.h:519 -msgid "Export as &OFF..." -msgstr "Экспортировать в &OFF..." - -#: objects/ui_MainWindow.h:520 -msgid "Preview" -msgstr "" - -#: objects/ui_MainWindow.h:521 -msgid "F9" -msgstr "" - -#: objects/ui_MainWindow.h:522 -#, fuzzy -msgid "Surfaces" -msgstr "Поверхности CGAL" - -#: objects/ui_MainWindow.h:523 -msgid "F10" -msgstr "" - -#: objects/ui_MainWindow.h:524 -msgid "Wireframe" -msgstr "" - -#: objects/ui_MainWindow.h:525 -msgid "F11" -msgstr "" - -#: objects/ui_MainWindow.h:526 -msgid "Thrown Together" -msgstr "Всё вместе" - -#: objects/ui_MainWindow.h:527 -msgid "F12" -msgstr "" - -#: objects/ui_MainWindow.h:528 -msgid "Show Edges" -msgstr "Показывать рёбра" - -#: objects/ui_MainWindow.h:529 -msgid "Ctrl+1" -msgstr "" - -#: objects/ui_MainWindow.h:530 -msgid "Show Axes" -msgstr "Показывать оси" - -#: objects/ui_MainWindow.h:531 -msgid "Ctrl+2" -msgstr "" - -#: objects/ui_MainWindow.h:532 -msgid "Show Crosshairs" -msgstr "Показывать перекрестия" - -#: objects/ui_MainWindow.h:533 -msgid "Ctrl+3" -msgstr "" - -#: objects/ui_MainWindow.h:534 -msgid "Animate" -msgstr "Анимация" - -#: objects/ui_MainWindow.h:535 -msgid "Top" -msgstr "Сверху" - -#: objects/ui_MainWindow.h:536 -msgid "Ctrl+4" -msgstr "" - -#: objects/ui_MainWindow.h:537 -msgid "Bottom" -msgstr "Снизу" - -#: objects/ui_MainWindow.h:538 -msgid "Ctrl+5" -msgstr "" - -#: objects/ui_MainWindow.h:539 -msgid "Left" -msgstr "Слева" - -#: objects/ui_MainWindow.h:540 -msgid "Ctrl+6" -msgstr "" - -#: objects/ui_MainWindow.h:541 -msgid "Right" -msgstr "Справа" - -#: objects/ui_MainWindow.h:542 -msgid "Ctrl+7" -msgstr "" - -#: objects/ui_MainWindow.h:543 -msgid "Front" -msgstr "Спереди" - -#: objects/ui_MainWindow.h:544 -msgid "Ctrl+8" -msgstr "" - -#: objects/ui_MainWindow.h:545 -msgid "Back" -msgstr "Сзади" - -#: objects/ui_MainWindow.h:546 -msgid "Ctrl+9" -msgstr "" - -#: objects/ui_MainWindow.h:547 -msgid "Diagonal" -msgstr "Аксонометрический" - -#: objects/ui_MainWindow.h:548 -msgid "Ctrl+0" -msgstr "" - -#: objects/ui_MainWindow.h:549 -msgid "Center" -msgstr "По центру" - -#: objects/ui_MainWindow.h:550 -msgid "Ctrl+P" -msgstr "" - -#: objects/ui_MainWindow.h:551 -msgid "Perspective" -msgstr "Перспектива" - -#: objects/ui_MainWindow.h:552 -msgid "Orthogonal" -msgstr "Прямоугольная проекция" - -#: objects/ui_MainWindow.h:553 -msgid "Hide console" -msgstr "Скрыть консоль" - -#: objects/ui_MainWindow.h:554 -msgid "About" -msgstr "О программе" - -#: objects/ui_MainWindow.h:555 -msgid "Documentation" -msgstr "Документация" - -#: objects/ui_MainWindow.h:556 -msgid "Clear Recent" -msgstr "Очистить список" - -#: objects/ui_MainWindow.h:557 -msgid "Export as DXF..." -msgstr "Экспортировать в DXF..." - -#: objects/ui_MainWindow.h:558 -msgid "Close" -msgstr "Закрыть" - -#: objects/ui_MainWindow.h:559 -msgid "Ctrl+W" -msgstr "" - -#: objects/ui_MainWindow.h:560 objects/ui_Preferences.h:517 -msgid "Preferences" -msgstr "Настройки" - -#: objects/ui_MainWindow.h:561 -msgid "Flush Caches" -msgstr "Очистить кэш" - -#: objects/ui_MainWindow.h:562 -msgid "OpenSCAD Homepage" -msgstr "Домашняя страница OpenSCAD" - -#: objects/ui_MainWindow.h:563 -#, fuzzy -msgid "Automatic Reload and Preview" -msgstr "Автоматически обновлять и комилировать" - -#: objects/ui_MainWindow.h:564 -msgid "Export as Image..." -msgstr "Экспортировать в растр..." - -#: objects/ui_MainWindow.h:565 -msgid "Export as CSG..." -msgstr "Экспортировать в CSG..." - -#: objects/ui_MainWindow.h:566 -msgid "Library info" -msgstr "Информация о библиотеках" - -#: objects/ui_MainWindow.h:567 -msgid "Check for Update.." -msgstr "Проверить обновления..." - -#: objects/ui_MainWindow.h:568 -msgid "Show Library Folder..." -msgstr "Открыть каталог библиотек..." - -#: objects/ui_MainWindow.h:569 -msgid "Reset View" -msgstr "Сбросить настройки вида" - -#: objects/ui_MainWindow.h:571 objects/ui_Preferences.h:520 -msgid "Editor" -msgstr "Редактор" - -#: objects/ui_MainWindow.h:574 -msgid "Editor for SCAD code" -msgstr "" - -#: objects/ui_MainWindow.h:577 -msgid "Console" -msgstr "" - -#: objects/ui_MainWindow.h:580 -msgid "Console messages" -msgstr "" - -#: objects/ui_MainWindow.h:582 -msgid "Time:" -msgstr "Время:" - -#: objects/ui_MainWindow.h:583 -msgid "FPS:" -msgstr "Кадров в секунду:" - -#: objects/ui_MainWindow.h:584 -msgid "Steps:" -msgstr "Шагов:" - -#: objects/ui_MainWindow.h:585 -msgid "Dump Pictures" -msgstr "Сохранять кадры" - -#: objects/ui_MainWindow.h:586 -msgid "&File" -msgstr "&Файл" - -#: objects/ui_MainWindow.h:587 -msgid "Open Recent" -msgstr "Открыть недавние" - -#: objects/ui_MainWindow.h:588 -msgid "Examples" -msgstr "Примеры" - -#: objects/ui_MainWindow.h:589 -msgid "&Edit" -msgstr "&Правка" - -#: objects/ui_MainWindow.h:590 -msgid "&Design" -msgstr "&Модель" - -#: objects/ui_MainWindow.h:591 -msgid "&View" -msgstr "&Вид" - -#: objects/ui_MainWindow.h:592 -msgid "&Help" -msgstr "&Справка" - -#: objects/ui_Preferences.h:518 -msgid "3D View" -msgstr "3D Вид" - -#: objects/ui_Preferences.h:519 -msgid "Advanced" -msgstr "Дополнительные" - -#: objects/ui_Preferences.h:521 -msgid "Update" -msgstr "Обновления" - -#: objects/ui_Preferences.h:522 objects/ui_Preferences.h:550 -msgid "Features" -msgstr "Функции" - -#: objects/ui_Preferences.h:524 -msgid "Enable/Disable experimental features" -msgstr "" - -#: objects/ui_Preferences.h:526 -msgid "Color scheme:" -msgstr "Цветовая схема:" - -#: objects/ui_Preferences.h:531 -msgid "Cornfield" -msgstr "" - -#: objects/ui_Preferences.h:533 -msgid "Metallic" -msgstr "" - -#: objects/ui_Preferences.h:535 -msgid "Sunset" -msgstr "" - -#: objects/ui_Preferences.h:538 -msgid "Font" -msgstr "Шрифт" - -#: objects/ui_Preferences.h:539 -msgid "Color syntax highlighting" -msgstr "Подсветка синтаксиса" - -#: objects/ui_Preferences.h:542 -msgid "Off" -msgstr "Выключить" - -#: objects/ui_Preferences.h:543 -msgid "For Light Background" -msgstr "Для светлого фона" - -#: objects/ui_Preferences.h:544 -msgid "For Dark Background" -msgstr "Для тёмного фона" - -#: objects/ui_Preferences.h:546 -msgid "Automatically check for updates" -msgstr "Автоматически проверять обновления" - -#: objects/ui_Preferences.h:547 -msgid "Include development snapshots" -msgstr "Включая рабочие сборки" - -#: objects/ui_Preferences.h:548 -msgid "Check Now" -msgstr "Проверить сейчас" - -#: objects/ui_Preferences.h:549 -msgid "Last checked: " -msgstr "Последняя проверка: " - -#: objects/ui_Preferences.h:551 -msgid "OpenCSG" -msgstr "" - -#: objects/ui_Preferences.h:552 -msgid "Show capability warning" -msgstr "Показывать предупреждение о возможностях" - -#: objects/ui_Preferences.h:553 -msgid "Enable for OpenGL 1.x" -msgstr "Включить для OpenGL 1.x" - -#: objects/ui_Preferences.h:554 -msgid "Turn off rendering at " -msgstr "Отключать отрисовку на " - -#: objects/ui_Preferences.h:555 -msgid "elements" -msgstr "элементах" - -#: objects/ui_Preferences.h:556 -msgid "Force Goldfeather" -msgstr "Принудительно использовать алгоритм Goldfeather («Золотое перо»)" - -#: objects/ui_Preferences.h:557 -msgid "CGAL Cache size" -msgstr "Размер кэша CGAL" - -#: objects/ui_Preferences.h:558 objects/ui_Preferences.h:560 -msgid "bytes" -msgstr "байт" - -#: objects/ui_Preferences.h:559 -msgid "PolySet Cache size" -msgstr "Размер кэша PolySet" - -#: objects/ui_Preferences.h:561 -msgid "Enable user interface localization (requires restart of OpenSCAD)" -msgstr "" - -#: objects/ui_Preferences.h:562 -msgid "toolBar" -msgstr "" - -#: src/AboutDialog.h:16 -msgid "About OpenSCAD " -msgstr "" - -#: src/cache.h:181 -msgid "Trimming cache: %1% (%2% bytes)" -msgstr "" - -#: src/CGAL_Nef3_workaround.h:256 -#, c-format -msgid "WARNING: CGAL NefPolyhedron Triangulation failed: %s" -msgstr "" - -#: src/CsgInfo.h:48 -msgid "Error: CSG generation failed! (no top level object found)" -msgstr "" - -#: src/CsgInfo.h:53 src/mainwin.cc:818 -msgid "Compiling design (CSG Products normalization)..." -msgstr "" - -#: src/CsgInfo.h:60 src/mainwin.cc:865 -#, c-format -msgid "Normalized CSG tree has %d elements" -msgstr "" - -#: src/CsgInfo.h:64 src/mainwin.cc:830 -msgid "WARNING: CSG normalization resulted in an empty tree" -msgstr "" - -#: src/CsgInfo.h:69 -#, c-format -msgid "Compiling highlights (%i CSG Trees)..." -msgstr "" - -#: src/CsgInfo.h:79 -#, c-format -msgid "Compiling background (%i CSG Trees)..." -msgstr "" - -#: src/CGALCache.cc:15 -#, c-format -msgid "CGAL Cache hit: %s (%d bytes)" -msgstr "" - -#: src/CGALCache.cc:24 -#, c-format -msgid "CGAL Cache insert: %s (%d bytes)" -msgstr "" - -#: src/CGALCache.cc:25 -#, c-format -msgid "CGAL Cache insert failed: %s (%d bytes)" -msgstr "" - -#: src/CGALCache.cc:47 -#, c-format -msgid "CGAL Polyhedrons in cache: %d" -msgstr "" - -#: src/CGALCache.cc:48 -#, c-format -msgid "CGAL cache size in bytes: %d" -msgstr "" - -#: src/CGAL_Nef_polyhedron.cc:74 src/cgalutils.cc:44 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed." -msgstr "" - -#: src/CGAL_Nef_polyhedron.cc:75 src/cgalutils.cc:45 src/PlatformUtils.cc:19 -#, c-format -msgid "ERROR: %s" -msgstr "" - -#: src/CGAL_Nef_polyhedron_DxfData.cc:49 -msgid "Warning: Scaling a 3D object with 0 - removing object" -msgstr "" - -#: src/cgalutils.cc:30 -msgid "" -"Hull() currently requires a valid 2-manifold. Please modify your design. See " -"http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" -msgstr "" - -#: src/cgalutils.cc:107 -#, c-format -msgid "ERROR: Unsupported CGAL operator: %d" -msgstr "" - -#: src/cgalutils.cc:113 -#, c-format -msgid "CGAL error in CGALUtils::applyBinaryOperator %s: %s" -msgstr "" - -#: src/cgalutils.cc:159 -#, c-format -msgid "CGALUtils::project during plane intersection: %s" -msgstr "" - -#: src/cgalutils.cc:161 -msgid "Trying alternative intersection using very large thin box: " -msgstr "" - -#: src/cgalutils.cc:176 -#, c-format -msgid "CGAL error in CGALUtils::project during bigbox intersection: %s" -msgstr "" - -#: src/cgalutils.cc:182 -msgid "WARNING: projection() failed." -msgstr "" - -#: src/cgalutils.cc:204 -#, c-format -msgid "CGAL error in CGALUtils::project while flattening: %s" -msgstr "" - -#: src/cgalutils.cc:496 -msgid "ERROR: deproject failure" -msgstr "" - -#: src/cgalutils.cc:582 -msgid "ERROR: failed to find projection" -msgstr "" - -#: src/cgalutils.cc:593 -msgid "input polygon has 3 points. shortcut tessellation." -msgstr "" - -#: src/cgalutils.cc:605 -msgid "finding good projection" -msgstr "" - -#: src/cgalutils.cc:608 -#, c-format -msgid "plane %s" -msgstr "" - -#: src/cgalutils.cc:609 -#, c-format -msgid "proj: %i %i" -msgstr "" - -#: src/cgalutils.cc:610 -msgid "Inserting points and edges into Constrained Delaunay Triangulation" -msgstr "" - -#: src/cgalutils.cc:632 -#, c-format -msgid "WARNING: Constraint insertion failure %s" -msgstr "" - -#: src/cgalutils.cc:639 -#, c-format -msgid "seeding %i holes" -msgstr "" - -#: src/cgalutils.cc:660 -#, c-format -msgid "seed %f,%f" -msgstr "" - -#: src/cgalutils.cc:662 -msgid "seeding done" -msgstr "" - -#: src/cgalutils.cc:664 -msgid "meshing" -msgstr "" - -#: src/cgalutils.cc:669 -msgid "meshing done" -msgstr "" - -#: src/cgalutils.cc:690 -msgid "WARNING: 2d->3d deprojection failure" -msgstr "" - -#: src/cgalutils.cc:698 -#, c-format -msgid "built %i triangles\n" -msgstr "" - -#: src/cgalutils.cc:741 -msgid "WARNING: triangle doesn't have 3 points. skipping" -msgstr "" - -#: src/cgalutils.cc:941 -#, c-format -msgid "CGAL error in CGALUtils::createPolyhedronFromPolySet: %s" -msgstr "" - -#: src/cgalutils.cc:1021 -msgid "PolySet has nonplanar faces. Attempting alternate construction" -msgstr "" - -#: src/cgalutils.cc:1025 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "" - -#: src/cgalutils.cc:1036 -#, c-format -msgid "Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s" -msgstr "" - -#: src/cgalworker.cc:36 -msgid "Rendering cancelled." -msgstr "" - -#: src/color.cc:69 -#, c-format -msgid "" -"WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too " -"large." -msgstr "" - -#: src/color.cc:81 -#, c-format -msgid "WARNING: Color name \"%s\" unknown. Please see" -msgstr "" - -#: src/color.cc:82 -msgid "WARNING: http://en.wikipedia.org/wiki/Web_colors" -msgstr "" - -#: src/context.cc:97 -#, c-format -msgid "WARNING: Attempt to modify constant '%s'." -msgstr "" - -#: src/context.cc:121 -#, c-format -msgid "WARNING: Ignoring unknown variable '%s'." -msgstr "" - -#: src/context.cc:128 -#, c-format -msgid "WARNING: Ignoring unknown function '%s'." -msgstr "" - -#: src/context.cc:135 -#, c-format -msgid "WARNING: Ignoring unknown module '%s'." -msgstr "" - -#: src/context.cc:156 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p)" -msgstr "" - -#: src/context.cc:158 src/evalcontext.cc:40 -#, c-format -msgid "Context: %p (%p)" -msgstr "" - -#: src/context.cc:159 src/evalcontext.cc:41 src/modcontext.cc:148 -#, c-format -msgid " document path: %s" -msgstr "" - -#: src/context.cc:163 src/evalcontext.cc:57 src/modcontext.cc:152 -msgid " module args:" -msgstr "" - -#: src/context.cc:170 src/modcontext.cc:159 -msgid " vars:" -msgstr "" - -#: src/control.cc:83 -#, c-format -msgid "WARNING: Bad range parameter in for statement: too many elements (%lu)." -msgstr "" - -#: src/control.cc:133 src/control.cc:138 src/control.cc:247 -#, c-format -msgid "" -"WARNING: Bad parameter type (%s) for children, only accept: empty, number, " -"vector, range." -msgstr "" - -#: src/control.cc:144 -#, c-format -msgid "WARNING: Negative children index (%d) not allowed" -msgstr "" - -#: src/control.cc:150 -#, c-format -msgid "WARNING: Children index (%d) out of bounds (%d children)" -msgstr "" - -#: src/control.cc:170 -#, c-format -msgid "WARNING: Negative child index (%d) not allowed" -msgstr "" - -#: src/control.cc:189 -#, c-format -msgid "WARNING: Child index (%d) out of bounds (%d children)" -msgstr "" - -#: src/control.cc:234 -#, c-format -msgid "WARNING: Bad range parameter for children: too many elements (%lu)." -msgstr "" - -#: src/csgtermnormalizer.cc:21 src/csgtermnormalizer.cc:69 -#, c-format -msgid "" -"WARNING: Normalized tree is growing past %d elements. Aborting " -"normalization.\n" -msgstr "" - -#: src/dxfdata.cc:84 -#, c-format -msgid "WARNING: Can't open DXF file '%s'." -msgstr "" - -#: src/dxfdata.cc:148 -#, c-format -msgid "WARNING: Illegal ID '%s' in `%s'" -msgstr "" - -#: src/dxfdata.cc:387 -#, c-format -msgid "WARNING: Illegal value %s in '%s'" -msgstr "" - -#: src/dxfdata.cc:393 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in %s." -msgstr "" - -#: src/dxfdata.cc:396 -#, c-format -msgid "WARNING: Unsupported DXF Entity '%s' (%x) in layer '%s' of %s." -msgstr "" - -#: src/dxfdim.cc:131 -#, c-format -msgid "WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!" -msgstr "" - -#: src/dxfdim.cc:136 -#, c-format -msgid "WARNING: Can't find dimension '%s' in '%s', layer '%s'!" -msgstr "" - -#: src/dxfdim.cc:211 -#, c-format -msgid "WARNING: Can't find cross in '%s', layer '%s'!" -msgstr "" - -#: src/evalcontext.cc:38 -#, c-format -msgid "EvalContext %p (%p) for %s inst (%p)" -msgstr "" - -#: src/evalcontext.cc:43 -msgid " eval args:" -msgstr "" - -#: src/evalcontext.cc:48 -msgid " children:" -msgstr "" - -#: src/export.cc:180 src/export.cc:225 -msgid "Object isn't a valid 2-manifold! Modify your design.\n" -msgstr "" - -#: src/export.cc:187 -msgid "ERROR: Nef->PolySet failed" -msgstr "" - -#: src/export.cc:199 -msgid "ERROR: CGAL NefPolyhedron->Polyhedron conversion failed" -msgstr "" - -#: src/export.cc:205 src/export.cc:234 -#, c-format -msgid "CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s" -msgstr "" - -#: src/export.cc:208 -msgid "CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()" -msgstr "" - -#: src/expr.cc:166 -#, c-format -msgid "ERROR: Recursion detected calling function '%s'" -msgstr "" - -#: src/feature.cc:21 -msgid "Enable the concat() function." -msgstr "" - -#: src/feature.cc:60 -#, c-format -msgid "WARNING: Ignoring request to enable unknown feature '%s'." -msgstr "" - -#: src/fileutils.cc:25 -#, c-format -msgid "" -"WARNING: Imported file (%s) found in document root instead of relative to " -"the importing module. This behavior is deprecated" -msgstr "" - -#: src/func.cc:503 src/func.cc:536 -#, c-format -msgid " WARNING: search term not found: \"%s\"" -msgstr "" - -#: src/func.cc:533 -#, c-format -msgid " WARNING: search term not found: %s" -msgstr "" - -#: src/func.cc:545 -#, c-format -msgid " WARNING: search: none performed on input %s" -msgstr "" - -#: src/func.cc:591 -#, c-format -msgid "WARNING: Negative parent module index (%d) not allowed" -msgstr "" - -#: src/func.cc:595 -#, c-format -msgid "" -"WARNING: Parent module index (%d) greater than the number of modules on the " -"stack" -msgstr "" - -#: src/GeometryCache.cc:14 -#, c-format -msgid "Geometry Cache hit: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:24 -#, c-format -msgid "Geometry Cache insert: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:26 -#, c-format -msgid "Geometry Cache insert failed: %s (%d bytes)" -msgstr "" - -#: src/GeometryCache.cc:44 -#, c-format -msgid "Geometries in cache: %d" -msgstr "" - -#: src/GeometryCache.cc:45 -#, c-format -msgid "Geometry cache size in bytes: %d" -msgstr "" - -#: src/GeometryEvaluator.cc:76 -msgid "WARNING: Mixing 2D and 3D objects is not supported." -msgstr "" - -#: src/GeometryEvaluator.cc:188 -msgid "WARNING: Resize in direction normal to flat object is not implemented" -msgstr "" - -#: src/GeometryEvaluator.cc:252 -msgid "WARNING: Ignoring 3D child object for 2D operation" -msgstr "" - -#: src/GeometryEvaluator.cc:276 -msgid "WARNING: GeometryEvaluator: Node didn't fit into cache" -msgstr "" - -#: src/GeometryEvaluator.cc:324 -msgid "WARNING: Ignoring 2D child object for 3D operation" -msgstr "" - -#: src/GeometryEvaluator.cc:365 -#, c-format -msgid "Error: Unknown boolean operation %d" -msgstr "" - -#: src/GeometryEvaluator.cc:517 -msgid "" -"Warning: Transformation matrix contains Not-a-Number and/or Infinity - " -"removing object." -msgstr "" - -#: src/GeometryEvaluator.cc:765 -#, c-format -msgid "" -"ERROR: all points for rotate_extrude() must have the same X coordinate sign " -"(range is %.2f -> %.2f)" -msgstr "" - -#: src/handle_dep.cc:36 -#, c-format -msgid "Can't open dependencies file `%s' for writing!\n" -msgstr "" - -#: src/import.cc:98 -msgid "DEPRECATED: filename= is deprecated. Please use file=" -msgstr "" - -#: src/import.cc:122 -msgid "DEPRECATED: layername= is deprecated. Please use layer=" -msgstr "" - -#: src/import.cc:201 src/import.cc:286 -#, c-format -msgid "WARNING: Can't open import file '%s'." -msgstr "" - -#: src/import.cc:251 -#, c-format -msgid "WARNING: Can't parse vertex line '%s'." -msgstr "" - -#: src/import.cc:295 -msgid "WARNING: OFF import requires CGAL." -msgstr "" - -#: src/import.cc:305 -#, c-format -msgid "ERROR: Unsupported file format while trying to import file '%s'" -msgstr "" - -#: src/linearextrude.cc:77 -msgid "" -"DEPRECATED: Support for reading files in linear_extrude will be removed in " -"future releases. Use a child import() instead." -msgstr "" - -#: src/mainwin.cc:118 -msgid "" -"Copyright (C) 2009-2013 The OpenSCAD Developers\n" -"\n" -"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." -msgstr "" - -#: src/mainwin.cc:523 -msgid "OpenSCAD - New Document[*]" -msgstr "" - -#: src/mainwin.cc:527 -msgid "OpenSCAD - " -msgstr "" - -#: src/mainwin.cc:527 -msgid "[*]" -msgstr "" - -#: src/mainwin.cc:601 -#, c-format -msgid "Failed to open file %s: %s" -msgstr "" - -#: src/mainwin.cc:608 -#, c-format -msgid "Loaded design '%s'." -msgstr "" - -#: src/mainwin.cc:655 -#, c-format -msgid "Module cache size: %d modules" -msgstr "" - -#: src/mainwin.cc:739 -msgid "Compiling design (CSG Tree generation)..." -msgstr "" - -#: src/mainwin.cc:765 -msgid "ERROR: Compilation failed! (no top level object found)" -msgstr "" - -#: src/mainwin.cc:767 -msgid "ERROR: Compilation failed!" -msgstr "" - -#: src/mainwin.cc:780 -msgid "Compiling design (CSG Products generation)..." -msgstr "" - -#: src/mainwin.cc:801 -msgid "ERROR: CSG generation failed! (no top level object found)" -msgstr "" - -#: src/mainwin.cc:810 -msgid "CSG generation cancelled." -msgstr "" - -#: src/mainwin.cc:836 -#, c-format -msgid "Compiling highlights (%d CSG Trees)..." -msgstr "" - -#: src/mainwin.cc:848 -#, c-format -msgid "Compiling background (%d CSG Trees)..." -msgstr "" - -#: src/mainwin.cc:861 -#, c-format -msgid "WARNING: Normalized tree has %d elements!" -msgstr "" - -#: src/mainwin.cc:862 -msgid "WARNING: OpenCSG rendering has been disabled." -msgstr "" - -#: src/mainwin.cc:875 -msgid "CSG generation finished." -msgstr "" - -#: src/mainwin.cc:877 src/mainwin.cc:1315 -#, c-format -msgid "Total rendering time: %d hours, %d minutes, %d seconds" -msgstr "" - -#: src/mainwin.cc:904 -msgid "Open File" -msgstr "Открыть файл" - -#: src/mainwin.cc:905 -msgid "OpenSCAD Designs (*.scad *.csg)" -msgstr "Модели OpenSCAD (*.scad *.csg)" - -#: src/mainwin.cc:999 -#, c-format -msgid "Failed to open file for writing: %s (%s)" -msgstr "" - -#: src/mainwin.cc:1000 -msgid "" -"Failed to open file for writing:\n" -" %1 (%2)" -msgstr "" - -#: src/mainwin.cc:1007 -#, c-format -msgid "Saved design '%s'." -msgstr "" - -#: src/mainwin.cc:1017 -msgid "Save File" -msgstr "Сохранить файл" - -#: src/mainwin.cc:1018 -msgid "Untitled.scad" -msgstr "Безымянный.scad" - -#: src/mainwin.cc:1019 -msgid "OpenSCAD Designs (*.scad)" -msgstr "Модели OpenSCAD (*.scad)" - -#: src/mainwin.cc:1029 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" - -#: src/mainwin.cc:1044 -#, c-format -msgid "WARNING: Library path %s doesn't exist. Creating" -msgstr "" - -#: src/mainwin.cc:1046 -#, c-format -msgid "ERROR: Cannot create library path: %s" -msgstr "" - -#: src/mainwin.cc:1181 src/mainwin.cc:1846 -msgid "Application" -msgstr "" - -#: src/mainwin.cc:1182 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" - -#: src/mainwin.cc:1232 src/mainwin.cc:1276 -msgid "Parsing design (AST generation)..." -msgstr "" - -#: src/mainwin.cc:1260 -#, c-format -msgid "frame%05d.png" -msgstr "" - -#: src/mainwin.cc:1294 -msgid "Rendering Polygon Mesh using CGAL..." -msgstr "" - -#: src/mainwin.cc:1320 src/mainwin.cc:1334 -msgid " Top level object is a 3D object:" -msgstr "" - -#: src/mainwin.cc:1321 -#, c-format -msgid " Simple: %6s" -msgstr "" - -#: src/mainwin.cc:1321 src/mainwin.cc:1322 -msgid "yes" -msgstr "" - -#: src/mainwin.cc:1321 src/mainwin.cc:1322 -msgid "no" -msgstr "" - -#: src/mainwin.cc:1322 -#, c-format -msgid " Valid: %6s" -msgstr "" - -#: src/mainwin.cc:1323 -#, c-format -msgid " Vertices: %6d" -msgstr "" - -#: src/mainwin.cc:1324 -#, c-format -msgid " Halfedges: %6d" -msgstr "" - -#: src/mainwin.cc:1325 -#, c-format -msgid " Edges: %6d" -msgstr "" - -#: src/mainwin.cc:1326 -#, c-format -msgid " Halffacets: %6d" -msgstr "" - -#: src/mainwin.cc:1327 src/mainwin.cc:1335 -#, c-format -msgid " Facets: %6d" -msgstr "" - -#: src/mainwin.cc:1328 -#, c-format -msgid " Volumes: %6d" -msgstr "" - -#: src/mainwin.cc:1337 -msgid " Top level object is a 2D object:" -msgstr "" - -#: src/mainwin.cc:1338 -#, c-format -msgid " Contours: %6d" -msgstr "" - -#: src/mainwin.cc:1340 -msgid "Unknown geometry type" -msgstr "" - -#: src/mainwin.cc:1342 -msgid "Rendering finished." -msgstr "" - -#: src/mainwin.cc:1351 -msgid "WARNING: No top level geometry to render" -msgstr "" - -#: src/mainwin.cc:1368 -msgid "AST Dump" -msgstr "" - -#: src/mainwin.cc:1373 -msgid "No AST to dump. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1386 -msgid "CSG Tree Dump" -msgstr "" - -#: src/mainwin.cc:1391 -msgid "No CSG to dump. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1404 -msgid "CSG Products Dump" -msgstr "" - -#: src/mainwin.cc:1406 -msgid "" -"\n" -"CSG before normalization:\n" -"%1\n" -"\n" -"\n" -"CSG after normalization:\n" -"%2\n" -"\n" -"\n" -"CSG rendering chain:\n" -"%3\n" -"\n" -"\n" -"Highlights CSG rendering chain:\n" -"%4\n" -"\n" -"\n" -"Background CSG rendering chain:\n" -"%5\n" -msgstr "" - -#: src/mainwin.cc:1429 src/mainwin.cc:1490 -msgid "Nothing to export! Try building first (press F6)." -msgstr "" - -#: src/mainwin.cc:1435 -msgid "Current top level object is not a 3D object." -msgstr "" - -#: src/mainwin.cc:1442 -msgid "" -"Object isn't a valid 2-manifold! Modify your design. See http://en.wikibooks." -"org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export" -msgstr "" - -#: src/mainwin.cc:1449 -msgid "Export STL File" -msgstr "" - -#: src/mainwin.cc:1449 -msgid "Export OFF File" -msgstr "" - -#: src/mainwin.cc:1451 -msgid "STL Files (*.stl)" -msgstr "" - -#: src/mainwin.cc:1451 -msgid "OFF Files (*.off)" -msgstr "" - -#: src/mainwin.cc:1453 -#, c-format -msgid "No filename specified. %s export aborted." -msgstr "" - -#: src/mainwin.cc:1460 src/mainwin.cc:1513 src/mainwin.cc:1546 -#: src/openscad.cc:313 src/openscad.cc:325 src/openscad.cc:343 -#: src/openscad.cc:391 src/openscad.cc:406 src/openscad.cc:421 -#: src/openscad.cc:432 -#, c-format -msgid "Can't open file \"%s\" for export" -msgstr "" - -#: src/mainwin.cc:1467 -#, c-format -msgid "%s export finished." -msgstr "" - -#: src/mainwin.cc:1496 -msgid "Current top level object is not a 2D object." -msgstr "" - -#: src/mainwin.cc:1502 -msgid "Export DXF File" -msgstr "" - -#: src/mainwin.cc:1503 -msgid "Untitled.dxf" -msgstr "" - -#: src/mainwin.cc:1504 -msgid "DXF Files (*.dxf)" -msgstr "" - -#: src/mainwin.cc:1506 -msgid "No filename specified. DXF export aborted." -msgstr "" - -#: src/mainwin.cc:1518 -msgid "DXF export finished." -msgstr "" - -#: src/mainwin.cc:1530 -msgid "Nothing to export. Please try compiling first..." -msgstr "" - -#: src/mainwin.cc:1535 -msgid "Export CSG File" -msgstr "" - -#: src/mainwin.cc:1536 -msgid "Untitled.csg" -msgstr "" - -#: src/mainwin.cc:1537 -msgid "CSG Files (*.csg)" -msgstr "" - -#: src/mainwin.cc:1539 -msgid "No filename specified. CSG export aborted." -msgstr "" - -#: src/mainwin.cc:1551 -msgid "CSG export finished." -msgstr "" - -#: src/mainwin.cc:1562 -msgid "Export Image" -msgstr "" - -#: src/mainwin.cc:1562 -msgid "PNG Files (*.png)" -msgstr "" - -#: src/mainwin.cc:1564 -msgid "No filename specified. Image export aborted." -msgstr "" - -#: src/mainwin.cc:1816 -msgid "http://openscad.org/" -msgstr "" - -#: src/mainwin.cc:1822 -msgid "http://www.openscad.org/documentation.html" -msgstr "" - -#: src/mainwin.cc:1831 -msgid "OpenGL Info" -msgstr "" - -#: src/mainwin.cc:1831 -msgid "OpenSCAD Detailed Library and Build Information" -msgstr "Подробная информация о библиотеках и сборке OpenSCAD" - -#: src/mainwin.cc:1847 -msgid "" -"The document has been modified.\n" -"Do you want to save your changes?" -msgstr "" -"Документ был изменен.\n" -"Сохранить изменения?" - -#: src/modcontext.cc:100 -#, c-format -msgid "WARNING: Experimental builtin function '%s' is not enabled." -msgstr "" - -#: src/modcontext.cc:113 -#, c-format -msgid "WARNING: Experimental builtin module '%s' is not enabled." -msgstr "" - -#: src/modcontext.cc:118 -#, c-format -msgid "" -"DEPRECATED: The %s() module will be removed in future releases. Use %s() " -"instead." -msgstr "" - -#: src/modcontext.cc:145 -#, c-format -msgid "ModuleContext %p (%p) for %s inst (%p) " -msgstr "" - -#: src/modcontext.cc:147 -#, c-format -msgid "ModuleContext: %p (%p)" -msgstr "" - -#: src/modcontext.cc:193 -#, c-format -msgid "New lib Context for %s func:" -msgstr "" - -#: src/modcontext.cc:217 -msgid "New file Context:" -msgstr "" - -#: src/ModuleCache.cc:70 -#, c-format -msgid "Recompiling cached library: %s (%s)" -msgstr "" - -#: src/ModuleCache.cc:73 -#, c-format -msgid "Compiling library '%s'." -msgstr "" - -#: src/ModuleCache.cc:81 -#, c-format -msgid "WARNING: Can't open library file '%s'\n" -msgstr "" - -#: src/ModuleCache.cc:99 -#, c-format -msgid " compiled module: %p" -msgstr "" - -#: src/module.cc:139 -msgid "New eval ctx:" -msgstr "" - -#: src/module.cc:180 -#, c-format -msgid "ERROR: Recursion detected calling module '%s'" -msgstr "" - -#: src/module.cc:298 -#, c-format -msgid "WARNING: Failed to compile library '%s'." -msgstr "" - -#: src/OffscreenView.cc:27 -msgid "OpenSCAD recommended OpenGL version is 2.0." -msgstr "" - -#: src/openscad.cc:107 -msgid "" -"Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" -"%2%[ -m make_command ] [ -D var=val [..] ] \\\n" -"%2%[ --version ] [ --info ] \\\n" -"%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" -"%2% --camera=eyex,y,z,centerx,y,z ] \\\n" -"%2%[ --imgsize=width,height ] [ --projection=(o)rtho|(p)ersp] \\\n" -"%2%[ --render | --preview[=throwntogether] ] \\\n" -"%2%[ --enable= ] \\\n" -"%2%filename\n" -msgstr "" - -#: src/openscad.cc:124 -#, c-format -msgid "OpenSCAD version %s\n" -msgstr "" - -#: src/openscad.cc:136 -#, c-format -msgid "Can't create OpenGL OffscreenView. Code: %i. Exiting.\n" -msgstr "" - -#: src/openscad.cc:180 -msgid "Camera setup requires either 7 numbers for Gimbal Camera\n" -msgstr "" - -#: src/openscad.cc:181 -msgid "or 6 numbers for Vector Camera\n" -msgstr "" - -#: src/openscad.cc:197 -msgid "projection needs to be 'o' or 'p' for ortho or perspective\n" -msgstr "" - -#: src/openscad.cc:208 -msgid "Need 2 numbers for imgsize\n" -msgstr "" - -#: src/openscad.cc:257 -#, c-format -msgid "Unknown suffix for output file %s\n" -msgstr "" - -#: src/openscad.cc:281 -#, c-format -msgid "Can't open input file '%s'!\n" -msgstr "" - -#: src/openscad.cc:290 -#, c-format -msgid "Can't parse file '%s'!\n" -msgstr "" - -#: src/openscad.cc:373 -#, c-format -msgid "Output file:%s\n" -msgstr "" - -#: src/openscad.cc:374 -msgid "Sorry, don't know how to write deps for that file type. Exiting\n" -msgstr "" - -#: src/openscad.cc:379 -msgid "error writing deps" -msgstr "" - -#: src/openscad.cc:386 src/openscad.cc:401 -msgid "Current top level object is not a 3D object.\n" -msgstr "" - -#: src/openscad.cc:416 -msgid "Current top level object is not a 2D object.\n" -msgstr "" - -#: src/openscad.cc:594 -msgid "Allowed options" -msgstr "" - -#: src/openscad.cc:596 -msgid "help message" -msgstr "" - -#: src/openscad.cc:597 -msgid "print the version" -msgstr "" - -#: src/openscad.cc:598 -msgid "print information about the building process" -msgstr "" - -#: src/openscad.cc:599 -msgid "if exporting a png image, do a full CGAL render" -msgstr "" - -#: src/openscad.cc:600 -msgid "" -"if exporting a png image, do an OpenCSG(default) or ThrownTogether preview" -msgstr "" - -#: src/openscad.cc:601 -msgid "parameters for camera when exporting png" -msgstr "" - -#: src/openscad.cc:602 -msgid "=width,height for exporting png" -msgstr "" - -#: src/openscad.cc:603 -msgid "(o)rtho or (p)erspective when exporting png" -msgstr "" - -#: src/openscad.cc:604 -msgid "out-file" -msgstr "" - -#: src/openscad.cc:605 -msgid "stl-file" -msgstr "" - -#: src/openscad.cc:606 -msgid "dxf-file" -msgstr "" - -#: src/openscad.cc:607 -msgid "deps-file" -msgstr "" - -#: src/openscad.cc:608 -msgid "makefile" -msgstr "" - -#: src/openscad.cc:609 -msgid "var=val" -msgstr "" - -#: src/openscad.cc:610 -msgid "enable experimental features" -msgstr "" - -#: src/openscad.cc:612 -msgid "Hidden options" -msgstr "" - -#: src/openscad.cc:614 -msgid "input file" -msgstr "" - -#: src/openscad.cc:648 -msgid "DEPRECATED: The -s option is deprecated. Use -o instead.\n" -msgstr "" - -#: src/openscad.cc:653 -msgid "DEPRECATED: The -x option is deprecated. Use -o instead.\n" -msgstr "" - -#: src/openscad.cc:710 -msgid "Requested GUI mode but can't open display!\n" -msgstr "" - -#: src/PlatformUtils.cc:16 -#, c-format -msgid "ERROR: Cannot create %s" -msgstr "" - -#: src/polyset.cc:63 -msgid "PolySet:" -msgstr "" - -#: src/polyset.cc:64 -msgid "" -"\n" -" dimensions:" -msgstr "" - -#: src/polyset.cc:65 -msgid "" -"\n" -" convexity:" -msgstr "" - -#: src/polyset.cc:66 -msgid "" -"\n" -" num polygons: " -msgstr "" - -#: src/polyset.cc:67 -msgid "" -"\n" -" num outlines: " -msgstr "" - -#: src/polyset.cc:68 -msgid "" -"\n" -" polygons data:" -msgstr "" - -#: src/polyset.cc:70 -msgid "" -"\n" -" polygon begin:" -msgstr "" - -#: src/polyset.cc:74 -msgid "" -"\n" -" vertex:" -msgstr "" - -#: src/polyset.cc:77 -msgid "" -"\n" -" outlines data:" -msgstr "" - -#: src/polyset.cc:79 -msgid "" -"\n" -"PolySet end" -msgstr "" - -#: src/primitives.cc:134 -#, c-format -msgid "WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too." -msgstr "" - -#: src/primitives.cc:187 -#, c-format -msgid "WARNING: $fs too small - clamping to %f" -msgstr "" - -#: src/primitives.cc:191 -#, c-format -msgid "WARNING: $fa too small - clamping to %f" -msgstr "" - -#: src/primitives.cc:248 -msgid "" -"DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use " -"polyhedron(faces=[]) instead." -msgstr "" - -#: src/primitives.cc:515 -#, c-format -msgid "ERROR: Unable to convert point at index %d to a vec3 of numbers" -msgstr "" - -#: src/primitives.cc:575 -#, c-format -msgid "ERROR: Unable to convert point %s at index %d to a vec2 of numbers" -msgstr "" - -#: src/QGLView.cc:105 -msgid "" -"\n" -"Using QGLWidget\n" -"\n" -msgstr "" - -#: src/QGLView.cc:122 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" - -#: src/QGLView.cc:125 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" -msgstr "" - -#: src/QGLView.cc:128 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" -msgstr "" - -#: src/QGLView.cc:132 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" - -#: src/QGLView.cc:163 -#, c-format -msgid "" -"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " -"distance = %.2f" -msgstr "" - -#: src/rotateextrude.cc:71 -msgid "" -"DEPRECATED: Support for reading files in rotate_extrude will be removed in " -"future releases. Use a child import() instead." -msgstr "" - -#: src/surface.cc:107 -#, c-format -msgid "WARNING: Can't open DAT file '%s'." -msgstr "" - -#: src/surface.cc:139 -#, c-format -msgid "WARNING: Illegal value in '%s': %s" -msgstr "" - -#: src/value.cc:644 -msgid "" -"DEPRECATED: Using ranges of the form [begin:end] with begin value greater " -"than the end value is deprecated." -msgstr "" - -#~ msgid "About OpenSCAD" -#~ msgstr "О программе OpenSCAD" - -#~ msgid "&Compile" -#~ msgstr "&Компилировать" - -#~ msgid "Compile and &Render (CGAL)" -#~ msgstr "Компилировать и &отрисовать (CGAL)" - -#~ msgid "CGAL Grid Only" -#~ msgstr "Только сетка CGAL" diff --git a/scripts/translation-make.sh b/scripts/translation-make.sh index f9877661..95dcfb4e 100755 --- a/scripts/translation-make.sh +++ b/scripts/translation-make.sh @@ -13,9 +13,9 @@ TOPDIR="`dirname \"$SCRIPTDIR\"`" cd "$TOPDIR" echo "Generating POTFILES..." -./scripts/generate-potfiles.sh > po/POTFILES +./scripts/generate-potfiles.sh > locale/POTFILES echo "Updating translation files..." ./scripts/translation-update.sh -echo "Done." \ No newline at end of file +echo "Done." diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index bba298bc..1cb5ec38 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -11,9 +11,9 @@ updatepot() echo "cannot find file '$f' from POTFILES" exit 1 fi - done < po/POTFILES + done < locale/POTFILES - grep ui_MainWindow.h po/POTFILES >/dev/null 2>/dev/null + grep ui_MainWindow.h locale/POTFILES >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then echo "cannot find .../ui_xxxxx.h files. perhaps if you run make...?" exit 1 @@ -26,22 +26,22 @@ updatepot() OPTS=$OPTS' --default-domain=openscad' OPTS=$OPTS' --keyword=_' OPTS=$OPTS' --keyword=N_' - OPTS=$OPTS' --files-from=./po/POTFILES' - cmd="${GETTEXT_PATH}xgettext "$OPTS' -o ./po/openscad.pot' + OPTS=$OPTS' --files-from=./locale/POTFILES' + cmd="${GETTEXT_PATH}xgettext "$OPTS' -o ./locale/openscad.pot' echo $cmd $cmd if [ ! $? = 0 ]; then echo error running xgettext exit 1 fi - sed -e s/"CHARSET"/"UTF-8"/g ./po/openscad.pot > ./po/openscad.pot.new && mv ./po/openscad.pot.new ./po/openscad.pot + sed -e s/"CHARSET"/"UTF-8"/g ./locale/openscad.pot > ./locale/openscad.pot.new && mv ./locale/openscad.pot.new ./locale/openscad.pot } updatepo() { - for LANGCODE in `cat ./po/LINGUAS | grep -v "#"`; do + for LANGCODE in `cat ./locale/LINGUAS | grep -v "#"`; do OPTS='--update --backup=t' - cmd="$GETTEXT_PATH"'msgmerge '$OPTS' ./po/'$LANGCODE'.po ./po/openscad.pot' + cmd="$GETTEXT_PATH"'msgmerge '$OPTS' ./locale/'$LANGCODE'.po ./locale/openscad.pot' echo $cmd $cmd if [ ! $? = 0 ]; then @@ -53,10 +53,10 @@ updatepo() updatemo() { - for LANGCODE in `cat po/LINGUAS | grep -v "#"`; do - mkdir -p ./po/$LANGCODE/LC_MESSAGES + for LANGCODE in `cat locale/LINGUAS | grep -v "#"`; do + mkdir -p ./locale/$LANGCODE/LC_MESSAGES OPTS='-c -v' - cmd="$GETTEXT_PATH"'msgfmt '$OPTS' -o ./po/'$LANGCODE'/LC_MESSAGES/openscad.mo ./po/'$LANGCODE'.po' + cmd="$GETTEXT_PATH"'msgfmt '$OPTS' -o ./locale/'$LANGCODE'/LC_MESSAGES/openscad.mo ./locale/'$LANGCODE'.po' echo $cmd $cmd if [ ! $? = 0 ]; then diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index 4a0dd58e..868c54c8 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -1,10 +1,6 @@ #include #include "PlatformUtils.h" -#include -#ifdef USE_SCINTILLA_EDITOR -#include -#endif extern std::vector librarypath; extern std::vector fontpath; diff --git a/src/colormap.cc b/src/colormap.cc index c3a1b18a..07d860a0 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -194,7 +194,7 @@ ColorMap::colorscheme_set_t ColorMap::enumerateColorSchemes() RenderColorScheme *defaultColorScheme = new RenderColorScheme(); result_set.insert(colorscheme_set_t::value_type(defaultColorScheme->index(), boost::shared_ptr(defaultColorScheme))); - enumerateColorSchemesInPath(result_set, PlatformUtils::resourcesPath()); + enumerateColorSchemesInPath(result_set, PlatformUtils::resourceBasePath()); enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); return result_set; diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index d29d28f3..e2d4d781 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "boosty.h" #include "scintillaeditor.h" #include #include "Preferences.h" @@ -254,7 +255,7 @@ ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes() { colorscheme_set_t result_set; - enumerateColorSchemesInPath(result_set, PlatformUtils::resourcesPath()); + enumerateColorSchemesInPath(result_set, PlatformUtils::resourceBasePath()); enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); return result_set; From 99c617562c53b7ff4a9e5f864feba1a1619921f1 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 13 Nov 2014 00:39:17 +0100 Subject: [PATCH 032/263] Remove obsolete LOCALE_PREFIX and update documentation. --- .gitignore | 4 +- doc/translation.txt | 25 +++-- locale/POTFILES | 228 -------------------------------------------- openscad.pro | 11 +-- src/openscad.cc | 5 +- 5 files changed, 16 insertions(+), 257 deletions(-) delete mode 100644 locale/POTFILES diff --git a/.gitignore b/.gitignore index 862b173e..52a67b4a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,8 +13,8 @@ parser_yacc.h /tmp /OpenSCAD.app */#*# -/po/*/*/*.mo -/po/POTFILES +/locale/*/*/*.mo +/locale/POTFILES /nbproject /openscad /tests/openscad_nogui diff --git a/doc/translation.txt b/doc/translation.txt index cced8f60..67bc4137 100644 --- a/doc/translation.txt +++ b/doc/translation.txt @@ -15,13 +15,13 @@ There is a script included, translation-update.sh, that automates this process. File layout: ============ - ./po/*.po - .po files, one per language - ./po/openscad.pot - .pot template, generated by xgettext - ./po/POTFILES.in - list of source code files with translatable strings - ./po/LINGUAS - list of language codes for which .po files exist + ./locale/*.po - .po files, one per language + ./locale/openscad.pot - .pot template, generated by xgettext + ./locale/POTFILES - list of source files with translatable strings (generated) + ./locale/LINGUAS - list of language codes for which .po files exist ./src/qtgettext.h - wrapper code between QT and GNU gettext ./scripts/translation-update.sh - simple unix helper script - ./po/xx/LC_MESSAGES/openscad.mo - 'binaries' of .po files, built by script + ./locale/xx/LC_MESSAGES/openscad.mo - 'binaries' of .po files, built by script To translate the strings: ========================= @@ -49,27 +49,26 @@ files. $ make clean && qmake && make -Now make sure your .cc and ui_xxxx.h files are listed in po/POTFILES.in. -Then run the script to scan them, and regenerate .pot & .po files. +Then run the script to scan the source files, and regenerate .pot & .po files. - $ ./scripts/translate.sh updateall + $ ./scripts/translation-make.sh This will create new .po files with any new untranslated strings you added to the source code. These .po files can be distributed to translators for translation. After the translated .po file is obtained, overwrite the old .po and run the same script to update the .mo files. - $ ./scripts/translate.sh updateall + $ ./scripts/translation-make.sh To add a new language: ====================== -First add the language code to file ./po/LINGUAS. Then run msginit, replacing -$LANGCODE with the language code you want. +First add the language code to file ./locale/LINGUAS. Then run msginit, +replacing $LANGCODE with the language code you want. - $ msginit -l $LANGCODE -o ./po/$LANGCODE.po -i ./po/openscad.pot + $ msginit -l $LANGCODE -o ./locale/$LANGCODE.po -i ./locale/openscad.pot -You will now have a new ./po/xx.po file to edit and translate +You will now have a new ./locale/xx.po file to edit and translate Testing: ======== diff --git a/locale/POTFILES b/locale/POTFILES deleted file mode 100644 index b412c7f0..00000000 --- a/locale/POTFILES +++ /dev/null @@ -1,228 +0,0 @@ -./objects/ui_AboutDialog.h -./objects/ui_FontListDialog.h -./objects/ui_launchingscreen.h -./objects/ui_LibraryInfoDialog.h -./objects/ui_MainWindow.h -./objects/ui_OpenCSGWarningDialog.h -./objects/ui_Preferences.h -./objects/ui_ProgressWidget.h -src/AboutDialog.h -src/AppleEvents.h -src/AutoUpdater.h -src/boost-utils.h -src/boosty.h -src/builtin.h -src/cache.h -src/calc.h -src/Camera.h -src/cgaladvnode.h -src/CGALCache.h -src/cgalfwd.h -src/cgal.h -src/CGAL_Nef3_workaround.h -src/CGAL_Nef_polyhedron.h -src/CGAL_OGL_Polyhedron.h -src/CGALRenderer.h -src/cgalutils.h -src/CGAL_workaround_Mark_bounded_volumes.h -src/cgalworker.h -src/clipper-utils.h -src/CocoaUtils.h -src/colormap.h -src/colornode.h -src/context.h -src/CsgInfo.h -src/csgnode.h -src/CSGTermEvaluator.h -src/csgterm.h -src/csgtermnormalizer.h -src/Dock.h -src/DrawingCallback.h -src/dxfdata.h -src/dxfdim.h -src/editor.h -src/enums.h -src/evalcontext.h -src/EventFilter.h -src/export.h -src/expression.h -src/fbo.h -src/feature.h -src/fileutils.h -src/FontCache.h -src/FontListDialog.h -src/FreetypeRenderer.h -src/function.h -src/GeometryCache.h -src/GeometryEvaluator.h -src/Geometry.h -src/GLView.h -src/grid.h -src/handle_dep.h -src/highlighter.h -src/imageutils.h -src/importnode.h -src/launchingscreen.h -src/legacyeditor.h -src/LibraryInfoDialog.h -src/LibraryInfo.h -src/linalg.h -src/linearextrudenode.h -src/localscope.h -src/lodepng.h -src/MainWindow.h -src/mathc99.h -src/memory.h -src/modcontext.h -src/ModuleCache.h -src/module.h -src/nodecache.h -src/nodedumper.h -src/node.h -src/OffscreenContext.h -src/OffscreenView.h -src/offsetnode.h -src/OGL_helper.h -src/OpenCSGRenderer.h -src/OpenCSGWarningDialog.h -src/openscad.h -src/parsersettings.h -src/parser_yacc.h -src/PlatformUtils.h -src/Polygon2d-CGAL.h -src/Polygon2d.h -src/polyset.h -src/polyset-utils.h -src/Preferences.h -src/printutils.h -src/progress.h -src/ProgressWidget.h -src/projectionnode.h -src/QGLView.h -src/qtgettext.h -src/Reindexer.h -src/renderer.h -src/rendernode.h -src/rendersettings.h -src/rotateextrudenode.h -src/scadlexer.h -src/scintillaeditor.h -src/SparkleAutoUpdater.h -src/state.h -src/stl-utils.h -src/svg.h -src/system-gl.h -src/textnode.h -src/ThrownTogetherRenderer.h -src/transformnode.h -src/traverser.h -src/Tree.h -src/typedefs.h -src/UIUtils.h -src/value.h -src/version_check.h -src/visitor.h -src/AppleEvents.cc -src/AutoUpdater.cc -src/boost-utils.cc -src/builtin.cc -src/calc.cc -src/Camera.cc -src/cgaladv.cc -src/CGALCache.cc -src/CGAL_Nef_polyhedron.cc -src/CGAL_Nef_polyhedron_DxfData.cc -src/CGALRenderer.cc -src/cgalutils.cc -src/cgalutils-tess.cc -src/cgalworker.cc -src/clipper-utils.cc -src/color.cc -src/colormap.cc -src/context.cc -src/control.cc -src/csgops.cc -src/csgterm.cc -src/CSGTermEvaluator.cc -src/csgtermnormalizer.cc -src/Dock.cc -src/DrawingCallback.cc -src/dxfdata.cc -src/dxfdim.cc -src/editor.cc -src/evalcontext.cc -src/export.cc -src/export_png.cc -src/expr.cc -src/fbo.cc -src/feature.cc -src/fileutils.cc -src/FontCache.cc -src/FontListDialog.cc -src/FreetypeRenderer.cc -src/func.cc -src/GeometryCache.cc -src/Geometry.cc -src/GeometryEvaluator.cc -src/GLView.cc -src/handle_dep.cc -src/highlighter.cc -src/imageutils.cc -src/imageutils-lodepng.cc -src/imageutils-macosx.cc -src/import.cc -src/launchingscreen.cc -src/legacyeditor.cc -src/LibraryInfo.cc -src/LibraryInfoDialog.cc -src/linalg.cc -src/linearextrude.cc -src/localscope.cc -src/mainwin.cc -src/mathc99.cc -src/modcontext.cc -src/ModuleCache.cc -src/module.cc -src/node.cc -src/nodedumper.cc -src/NULLGL.cc -src/OffscreenContextGLX.cc -src/OffscreenContextNULL.cc -src/OffscreenContextWGL.cc -src/OffscreenView.cc -src/offset.cc -src/OpenCSGRenderer.cc -src/OpenCSGWarningDialog.cc -src/openscad.cc -src/parsersettings.cc -src/PlatformUtils.cc -src/PlatformUtils-posix.cc -src/PlatformUtils-win.cc -src/Polygon2d.cc -src/Polygon2d-CGAL.cc -src/polyset.cc -src/polyset-utils.cc -src/polyset-utils-old.cc -src/Preferences.cc -src/primitives.cc -src/printutils.cc -src/progress.cc -src/ProgressWidget.cc -src/projection.cc -src/QGLView.cc -src/render.cc -src/renderer.cc -src/rendersettings.cc -src/rotateextrude.cc -src/stl-utils.cc -src/surface.cc -src/svg.cc -src/system-gl.cc -src/text.cc -src/ThrownTogetherRenderer.cc -src/transform.cc -src/traverser.cc -src/Tree.cc -src/UIUtils.cc -src/value.cc -src/version_check.cc diff --git a/openscad.pro b/openscad.pro index 9c8c959d..10aa51ee 100644 --- a/openscad.pro +++ b/openscad.pro @@ -12,14 +12,6 @@ # # PREFIX defines the base installation folder # -# LOCALE_PREFIX can overwrite the location of the gettext message catalogs -# -# For linux packages that want to install the localization files into -# a folder shared by all packages, specify the LOCALE_PREFIX which will -# force usage of the given folder. -# The default layout is created by: LOCALE_PREFIX=/share/locale -# where is the base installation folder. -# # Please see the 'Building' sections of the OpenSCAD user manual # for updated tips & workarounds. # @@ -490,14 +482,13 @@ isEmpty(PREFIX):PREFIX = /usr/local target.path = $$PREFIX/bin/ INSTALLS += target -!isEmpty(LOCALE_PREFIX): DEFINES += LOCALE_PREFIX=\'\"$$LOCALE_PREFIX\"\' -isEmpty(LOCALE_PREFIX): LOCALE_PREFIX = $$PREFIX/share/openscad/locale # Run translation update scripts as last step after linking the target QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh # Create install targets for the languages defined in LINGUAS LINGUAS = $$cat(locale/LINGUAS) +LOCALE_PREFIX = $$PREFIX/share/openscad/locale for(language, LINGUAS) { catalog = locale/$$language/LC_MESSAGES/openscad.mo exists($$catalog) { diff --git a/src/openscad.cc b/src/openscad.cc index fb1becd5..ef44659a 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -161,12 +161,9 @@ static void info() * files. */ void localization_init() { -#ifdef LOCALE_PREFIX - std::string locale_path(LOCALE_PREFIX); -#else fs::path po_dir(PlatformUtils::resourcePath("locale")); std::string locale_path(po_dir.string()); -#endif + if (fs::is_directory(locale_path)) { setlocale(LC_ALL, ""); bindtextdomain("openscad", locale_path.c_str()); From 441160d8e8ca4262837119ff786efe9382009a75 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 14 Nov 2014 21:31:42 +0100 Subject: [PATCH 033/263] Fix release package creation. --- scripts/release-common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 1843696e..381504c0 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -392,7 +392,7 @@ fi if [ -n $TRANSLATIONDIR ]; then echo $TRANSLATIONDIR mkdir -p $TRANSLATIONDIR - cd po && tar cvf $OPENSCADDIR/translations.tar */*/*.mo && cd $OPENSCADDIR + cd locale && tar cvf $OPENSCADDIR/translations.tar */*/*.mo && cd $OPENSCADDIR cd $TRANSLATIONDIR && tar xvf $OPENSCADDIR/translations.tar && cd $OPENSCADDIR rm -f translations.tar fi From 406e6e1baca1e8928a2fecf8a66e09a481b3272f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 23 Nov 2014 00:59:17 -0500 Subject: [PATCH 034/263] #409 Pass Value objects as shared_ptr instances instead of by Value to battle excess stack usage --- src/builtin.cc | 12 +- src/cgaladv.cc | 31 +-- src/cgaladvnode.h | 2 +- src/color.cc | 16 +- src/context.cc | 32 ++- src/context.h | 9 +- src/control.cc | 46 ++--- src/dxfdim.cc | 62 +++--- src/dxfdim.h | 4 +- src/evalcontext.cc | 6 +- src/evalcontext.h | 4 +- src/expr.cc | 94 ++++----- src/expression.h | 18 +- src/func.cc | 476 +++++++++++++++++++++---------------------- src/function.h | 18 +- src/import.cc | 33 ++- src/linearextrude.cc | 58 +++--- src/mainwin.cc | 20 +- src/memory.h | 2 + src/modcontext.cc | 24 ++- src/modcontext.h | 11 +- src/module.cc | 12 +- src/offset.cc | 22 +- src/parser.y | 12 +- src/primitives.cc | 90 ++++---- src/projection.cc | 10 +- src/render.cc | 6 +- src/rotateextrude.cc | 28 +-- src/surface.cc | 22 +- src/text.cc | 6 +- src/transform.cc | 47 ++--- src/value.cc | 123 ++++++++++- src/value.h | 40 +++- 33 files changed, 786 insertions(+), 610 deletions(-) diff --git a/src/builtin.cc b/src/builtin.cc index c20f9f03..b04d2b53 100644 --- a/src/builtin.cc +++ b/src/builtin.cc @@ -94,19 +94,19 @@ std::string Builtins::isDeprecated(const std::string &name) Builtins::Builtins() { - this->globalscope.assignments.push_back(Assignment("$fn", boost::shared_ptr(new Expression(Value(0.0))))); - this->globalscope.assignments.push_back(Assignment("$fs", boost::shared_ptr(new Expression(Value(2.0))))); - this->globalscope.assignments.push_back(Assignment("$fa", boost::shared_ptr(new Expression(Value(12.0))))); - this->globalscope.assignments.push_back(Assignment("$t", boost::shared_ptr(new Expression(Value(0.0))))); + this->globalscope.assignments.push_back(Assignment("$fn", boost::shared_ptr(new Expression(ValuePtr(0.0))))); + this->globalscope.assignments.push_back(Assignment("$fs", boost::shared_ptr(new Expression(ValuePtr(2.0))))); + this->globalscope.assignments.push_back(Assignment("$fa", boost::shared_ptr(new Expression(ValuePtr(12.0))))); + this->globalscope.assignments.push_back(Assignment("$t", boost::shared_ptr(new Expression(ValuePtr(0.0))))); Value::VectorType zero3; zero3.push_back(Value(0.0)); zero3.push_back(Value(0.0)); zero3.push_back(Value(0.0)); - Value zero3val(zero3); + ValuePtr zero3val(zero3); this->globalscope.assignments.push_back(Assignment("$vpt", boost::shared_ptr(new Expression(zero3val)))); this->globalscope.assignments.push_back(Assignment("$vpr", boost::shared_ptr(new Expression(zero3val)))); - this->globalscope.assignments.push_back(Assignment("$vpd", boost::shared_ptr(new Expression(500)))); + this->globalscope.assignments.push_back(Assignment("$vpd", boost::shared_ptr(new Expression(ValuePtr(500))))); } Builtins::~Builtins() diff --git a/src/cgaladv.cc b/src/cgaladv.cc index c6c66ff6..55610621 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -63,8 +63,11 @@ AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstant Context c(ctx); c.setVariables(args, evalctx); - Value convexity, path, subdiv_type, level; - + ValuePtr convexity = ValuePtr::undefined; + ValuePtr path = ValuePtr::undefined; + ValuePtr subdiv_type = ValuePtr::undefined; + ValuePtr level = ValuePtr::undefined; + if (type == MINKOWSKI) { convexity = c.lookup_variable("convexity", true); } @@ -81,31 +84,31 @@ AbstractNode *CgaladvModule::instantiate(const Context *ctx, const ModuleInstant } if (type == RESIZE) { - Value ns = c.lookup_variable("newsize"); + ValuePtr ns = c.lookup_variable("newsize"); node->newsize << 0,0,0; - if ( ns.type() == Value::VECTOR ) { - Value::VectorType vs = ns.toVector(); + if ( ns->type() == Value::VECTOR ) { + const Value::VectorType &vs = ns->toVector(); if ( vs.size() >= 1 ) node->newsize[0] = vs[0].toDouble(); if ( vs.size() >= 2 ) node->newsize[1] = vs[1].toDouble(); if ( vs.size() >= 3 ) node->newsize[2] = vs[2].toDouble(); } - Value autosize = c.lookup_variable("auto"); + ValuePtr autosize = c.lookup_variable("auto"); node->autosize << false, false, false; - if ( autosize.type() == Value::VECTOR ) { - Value::VectorType va = autosize.toVector(); + if ( autosize->type() == Value::VECTOR ) { + const Value::VectorType &va = autosize->toVector(); if ( va.size() >= 1 ) node->autosize[0] = va[0].toBool(); if ( va.size() >= 2 ) node->autosize[1] = va[1].toBool(); if ( va.size() >= 3 ) node->autosize[2] = va[2].toBool(); } - else if ( autosize.type() == Value::BOOL ) { - node->autosize << autosize.toBool(),autosize.toBool(),autosize.toBool(); + else if ( autosize->type() == Value::BOOL ) { + node->autosize << autosize->toBool(),autosize->toBool(),autosize->toBool(); } } - node->convexity = (int)convexity.toDouble(); + node->convexity = (int)convexity->toDouble(); node->path = path; - node->subdiv_type = subdiv_type.toString(); - node->level = (int)level.toDouble(); + node->subdiv_type = subdiv_type->toString(); + node->level = (int)level->toDouble(); if (node->level <= 1) node->level = 1; @@ -150,7 +153,7 @@ std::string CgaladvNode::toString() const stream << "(convexity = " << this->convexity << ")"; break; case GLIDE: - stream << "(path = " << this->path << ", convexity = " << this->convexity << ")"; + stream << "(path = " << *this->path << ", convexity = " << this->convexity << ")"; break; case SUBDIV: stream << "(level = " << this->level << ", convexity = " << this->convexity << ")"; diff --git a/src/cgaladvnode.h b/src/cgaladvnode.h index 6794ae90..a2f81fe7 100644 --- a/src/cgaladvnode.h +++ b/src/cgaladvnode.h @@ -26,7 +26,7 @@ public: virtual std::string toString() const; virtual std::string name() const; - Value path; + ValuePtr path; std::string subdiv_type; int convexity, level; Vector3d newsize; diff --git a/src/color.cc b/src/color.cc index 7792f0bf..ced7a0b9 100644 --- a/src/color.cc +++ b/src/color.cc @@ -219,15 +219,15 @@ AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantia Context c(ctx); c.setVariables(args, evalctx); - Value v = c.lookup_variable("c"); - if (v.type() == Value::VECTOR) { + ValuePtr v = c.lookup_variable("c"); + if (v->type() == Value::VECTOR) { for (size_t i = 0; i < 4; i++) { - node->color[i] = i < v.toVector().size() ? v.toVector()[i].toDouble() : 1.0; + node->color[i] = i < v->toVector().size() ? v->toVector()[i].toDouble() : 1.0; if (node->color[i] > 1) PRINTB_NOCACHE("WARNING: color() expects numbers between 0.0 and 1.0. Value of %.1f is too large.", node->color[i]); } - } else if (v.type() == Value::STRING) { - std::string colorname = v.toString(); + } else if (v->type() == Value::STRING) { + std::string colorname = v->toString(); boost::algorithm::to_lower(colorname); Color4f color; if (webcolors.find(colorname) != webcolors.end()) { @@ -237,9 +237,9 @@ AbstractNode *ColorModule::instantiate(const Context *ctx, const ModuleInstantia PRINT_NOCACHE("WARNING: http://en.wikipedia.org/wiki/Web_colors"); } } - Value alpha = c.lookup_variable("alpha"); - if (alpha.type() == Value::NUMBER) { - node->color[3] = alpha.toDouble(); + ValuePtr alpha = c.lookup_variable("alpha"); + if (alpha->type() == Value::NUMBER) { + node->color[3] = alpha->toDouble(); } std::vector instantiatednodes = inst->instantiateChildren(evalctx); diff --git a/src/context.cc b/src/context.cc index 2fdeceeb..fdbe9990 100644 --- a/src/context.cc +++ b/src/context.cc @@ -78,14 +78,14 @@ void Context::setVariables(const AssignmentList &args, const EvalContext *evalctx) { BOOST_FOREACH(const Assignment &arg, args) { - set_variable(arg.first, arg.second ? arg.second->evaluate(this->parent) : Value()); + set_variable(arg.first, arg.second ? arg.second->evaluate(this->parent) : ValuePtr::undefined); } if (evalctx) { size_t posarg = 0; for (size_t i=0; inumArgs(); i++) { const std::string &name = evalctx->getArgName(i); - const Value &val = evalctx->getArgValue(i); + ValuePtr val = evalctx->getArgValue(i); if (name.empty()) { if (posarg < args.size()) this->set_variable(args[posarg++].first, val); } else { @@ -95,13 +95,18 @@ void Context::setVariables(const AssignmentList &args, } } -void Context::set_variable(const std::string &name, const Value &value) +void Context::set_variable(const std::string &name, const ValuePtr &value) { if (is_config_variable(name)) this->config_variables[name] = value; else this->variables[name] = value; } -void Context::set_constant(const std::string &name, const Value &value) +void Context::set_variable(const std::string &name, const Value &value) +{ + set_variable(name, ValuePtr(value)); +} + +void Context::set_constant(const std::string &name, const ValuePtr &value) { if (this->constants.find(name) != this->constants.end()) { PRINTB("WARNING: Attempt to modify constant '%s'.", name); @@ -111,11 +116,16 @@ void Context::set_constant(const std::string &name, const Value &value) } } -Value Context::lookup_variable(const std::string &name, bool silent) const +void Context::set_constant(const std::string &name, const Value &value) +{ + set_constant(name, ValuePtr(value)); +} + +ValuePtr Context::lookup_variable(const std::string &name, bool silent) const { if (!this->ctx_stack) { PRINT("ERROR: Context had null stack in lookup_variable()!!"); - return Value(); + return ValuePtr::undefined; } if (is_config_variable(name)) { for (int i = this->ctx_stack->size()-1; i >= 0; i--) { @@ -123,7 +133,7 @@ Value Context::lookup_variable(const std::string &name, bool silent) const if (confvars.find(name) != confvars.end()) return confvars.find(name)->second; } - return Value(); + return ValuePtr::undefined; } if (!this->parent && this->constants.find(name) != this->constants.end()) return this->constants.find(name)->second; @@ -133,7 +143,7 @@ Value Context::lookup_variable(const std::string &name, bool silent) const return this->parent->lookup_variable(name, silent); if (!silent) PRINTB("WARNING: Ignoring unknown variable '%s'.", name); - return Value(); + return ValuePtr::undefined; } bool Context::has_local_variable(const std::string &name) const @@ -145,11 +155,11 @@ bool Context::has_local_variable(const std::string &name) const return variables.find(name) != variables.end(); } -Value Context::evaluate_function(const std::string &name, const EvalContext *evalctx) const +ValuePtr Context::evaluate_function(const std::string &name, const EvalContext *evalctx) const { if (this->parent) return this->parent->evaluate_function(name, evalctx); PRINTB("WARNING: Ignoring unknown function '%s'.", name); - return Value(); + return ValuePtr::undefined; } AbstractNode *Context::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const @@ -190,7 +200,7 @@ std::string Context::dump(const AbstractModule *mod, const ModuleInstantiation * } } } - typedef std::pair ValueMapType; + typedef std::pair ValueMapType; s << " vars:"; BOOST_FOREACH(const ValueMapType &v, constants) { s << boost::format(" %s = %s") % v.first % v.second; diff --git a/src/context.h b/src/context.h index 3465c946..d80c0bef 100644 --- a/src/context.h +++ b/src/context.h @@ -5,6 +5,7 @@ #include #include "value.h" #include "typedefs.h" +#include "memory.h" class Context { @@ -14,16 +15,18 @@ public: virtual ~Context(); const Context *getParent() const { return this->parent; } - virtual Value evaluate_function(const std::string &name, const class EvalContext *evalctx) const; + virtual ValuePtr evaluate_function(const std::string &name, const class EvalContext *evalctx) const; virtual class AbstractNode *instantiate_module(const class ModuleInstantiation &inst, const EvalContext *evalctx) const; void setVariables(const AssignmentList &args, const class EvalContext *evalctx = NULL); + void set_variable(const std::string &name, const ValuePtr &value); void set_variable(const std::string &name, const Value &value); + void set_constant(const std::string &name, const ValuePtr &value); void set_constant(const std::string &name, const Value &value); - Value lookup_variable(const std::string &name, bool silent = false) const; + ValuePtr lookup_variable(const std::string &name, bool silent = false) const; bool has_local_variable(const std::string &name) const; void setDocumentPath(const std::string &path) { this->document_path = path; } @@ -36,7 +39,7 @@ protected: const Context *parent; Stack *ctx_stack; - typedef boost::unordered_map ValueMap; + typedef boost::unordered_map ValueMap; ValueMap constants; ValueMap variables; ValueMap config_variables; diff --git a/src/control.cc b/src/control.cc index 79ce6910..ee8c7e54 100644 --- a/src/control.cc +++ b/src/control.cc @@ -62,7 +62,7 @@ public: // methods static const EvalContext* getLastModuleCtx(const EvalContext *evalctx); - static AbstractNode* getChild(const Value& value, const EvalContext* modulectx); + static AbstractNode* getChild(const Value &value, const EvalContext* modulectx); private: // data Type type; @@ -74,27 +74,27 @@ void ControlModule::for_eval(AbstractNode &node, const ModuleInstantiation &inst { if (evalctx->numArgs() > l) { const std::string &it_name = evalctx->getArgName(l); - const Value &it_values = evalctx->getArgValue(l, ctx); + ValuePtr it_values = evalctx->getArgValue(l, ctx); Context c(ctx); - if (it_values.type() == Value::RANGE) { - Value::RangeType range = it_values.toRange(); + if (it_values->type() == Value::RANGE) { + Value::RangeType range = it_values->toRange(); boost::uint32_t steps = range.nbsteps(); if (steps >= 10000) { PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps); } else { for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { - c.set_variable(it_name, Value(*it)); + c.set_variable(it_name, ValuePtr(*it)); for_eval(node, inst, l+1, &c, evalctx); } } } - else if (it_values.type() == Value::VECTOR) { - for (size_t i = 0; i < it_values.toVector().size(); i++) { - c.set_variable(it_name, it_values.toVector()[i]); + else if (it_values->type() == Value::VECTOR) { + for (size_t i = 0; i < it_values->toVector().size(); i++) { + c.set_variable(it_name, it_values->toVector()[i]); for_eval(node, inst, l+1, &c, evalctx); } } - else if (it_values.type() != Value::UNDEFINED) { + else if (it_values->type() != Value::UNDEFINED) { c.set_variable(it_name, it_values); for_eval(node, inst, l+1, &c, evalctx); } @@ -165,7 +165,7 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns int n = 0; if (evalctx->numArgs() > 0) { double v; - if (evalctx->getArgValue(0).getDouble(v)) { + if (evalctx->getArgValue(0)->getDouble(v)) { n = trunc(v); if (n < 0) { PRINTB("WARNING: Negative child index (%d) not allowed", n); @@ -213,13 +213,13 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns } else if (evalctx->numArgs()>0) { // one (or more ignored) parameter - const Value& value = evalctx->getArgValue(0); - if (value.type() == Value::NUMBER) { - return getChild(value,modulectx); + ValuePtr value = evalctx->getArgValue(0); + if (value->type() == Value::NUMBER) { + return getChild(*value, modulectx); } - else if (value.type() == Value::VECTOR) { + else if (value->type() == Value::VECTOR) { AbstractNode* node = new AbstractNode(inst); - const Value::VectorType& vect = value.toVector(); + const Value::VectorType& vect = value->toVector(); foreach (const Value::VectorType::value_type& vectvalue, vect) { AbstractNode* childnode = getChild(vectvalue,modulectx); if (childnode==NULL) continue; // error @@ -227,9 +227,9 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns } return node; } - else if (value.type() == Value::RANGE) { + else if (value->type() == Value::RANGE) { AbstractNode* node = new AbstractNode(inst); - Value::RangeType range = value.toRange(); + Value::RangeType range = value->toRange(); boost::uint32_t steps = range.nbsteps(); if (steps >= 10000) { PRINTB("WARNING: Bad range parameter for children: too many elements (%lu).", steps); @@ -245,7 +245,7 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns else { // Invalid parameter // (e.g. first child of difference is invalid) - PRINTB("WARNING: Bad parameter type (%s) for children, only accept: empty, number, vector, range.", value.toString()); + PRINTB("WARNING: Bad parameter type (%s) for children, only accept: empty, number, vector, range.", value->toString()); return NULL; } } @@ -264,11 +264,11 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns for (size_t i = 0; i < inst->arguments.size(); i++) { if (i > 0) msg << ", "; if (!evalctx->getArgName(i).empty()) msg << evalctx->getArgName(i) << " = "; - Value val = evalctx->getArgValue(i); - if (val.type() == Value::STRING) { - msg << '"' << val.toString() << '"'; + ValuePtr val = evalctx->getArgValue(i); + if (val->type() == Value::STRING) { + msg << '"' << val->toString() << '"'; } else { - msg << val.toString(); + msg << val->toString(); } } PRINTB("%s", msg.str()); @@ -293,7 +293,7 @@ AbstractNode *ControlModule::instantiate(const Context* /*ctx*/, const ModuleIns if (type == IF) { const IfElseModuleInstantiation *ifelse = dynamic_cast(inst); - if (evalctx->numArgs() > 0 && evalctx->getArgValue(0).toBool()) { + if (evalctx->numArgs() > 0 && evalctx->getArgValue(0)->toBool()) { std::vector instantiatednodes = ifelse->instantiateChildren(evalctx); node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end()); } diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 8f55a2fa..8bcd1bc5 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -39,11 +39,11 @@ #include #include -boost::unordered_map dxf_dim_cache; -boost::unordered_map dxf_cross_cache; +boost::unordered_map dxf_dim_cache; +boost::unordered_map dxf_cross_cache; namespace fs = boost::filesystem; -Value builtin_dxf_dim(const Context *ctx, const EvalContext *evalctx) +ValuePtr builtin_dxf_dim(const Context *ctx, const EvalContext *evalctx) { std::string filename; std::string layername; @@ -56,17 +56,16 @@ Value builtin_dxf_dim(const Context *ctx, const EvalContext *evalctx) // since the path is only available for ModuleInstantiations, not function expressions. // See issue #217 for (size_t i = 0; i < evalctx->numArgs(); i++) { - if (evalctx->getArgName(i) == "file") - filename = lookup_file(evalctx->getArgValue(i).toString(), + ValuePtr n = evalctx->getArgName(i); + ValuePtr v = evalctx->getArgValue(i); + if (evalctx->getArgName(i) == "file") { + filename = lookup_file(v->toString(), evalctx->documentPath(), ctx->documentPath()); - if (evalctx->getArgName(i) == "layer") - layername = evalctx->getArgValue(i).toString(); - if (evalctx->getArgName(i) == "origin") - evalctx->getArgValue(i).getVec2(xorigin, yorigin); - if (evalctx->getArgName(i) == "scale") - evalctx->getArgValue(i).getDouble(scale); - if (evalctx->getArgName(i) == "name") - name = evalctx->getArgValue(i).toString(); + } + if (n == "layer") layername = v->toString(); + if (n == "origin") v->getVec2(xorigin, yorigin); + if (n == "scale") v->getDouble(scale); + if (n == "name") name = v->toString(); } std::stringstream keystream; @@ -100,46 +99,46 @@ Value builtin_dxf_dim(const Context *ctx, const EvalContext *evalctx) double y = d->coords[4][1] - d->coords[3][1]; double angle = d->angle; double distance_projected_on_line = fabs(x * cos(angle*M_PI/180) + y * sin(angle*M_PI/180)); - return dxf_dim_cache[key] = Value(distance_projected_on_line); + return dxf_dim_cache[key] = ValuePtr(distance_projected_on_line); } else if (type == 1) { // Aligned double x = d->coords[4][0] - d->coords[3][0]; double y = d->coords[4][1] - d->coords[3][1]; - return dxf_dim_cache[key] = Value(sqrt(x*x + y*y)); + return dxf_dim_cache[key] = ValuePtr(sqrt(x*x + y*y)); } else if (type == 2) { // Angular double a1 = atan2(d->coords[0][0] - d->coords[5][0], d->coords[0][1] - d->coords[5][1]); double a2 = atan2(d->coords[4][0] - d->coords[3][0], d->coords[4][1] - d->coords[3][1]); - return dxf_dim_cache[key] = Value(fabs(a1 - a2) * 180 / M_PI); + return dxf_dim_cache[key] = ValuePtr(fabs(a1 - a2) * 180 / M_PI); } else if (type == 3 || type == 4) { // Diameter or Radius double x = d->coords[5][0] - d->coords[0][0]; double y = d->coords[5][1] - d->coords[0][1]; - return dxf_dim_cache[key] = Value(sqrt(x*x + y*y)); + return dxf_dim_cache[key] = ValuePtr(sqrt(x*x + y*y)); } else if (type == 5) { // Angular 3 Point } else if (type == 6) { // Ordinate - return dxf_dim_cache[key] = Value((d->type & 64) ? d->coords[3][0] : d->coords[3][1]); + return dxf_dim_cache[key] = ValuePtr((d->type & 64) ? d->coords[3][0] : d->coords[3][1]); } PRINTB("WARNING: Dimension '%s' in '%s', layer '%s' has unsupported type!", name % filename % layername); - return Value(); + return ValuePtr::undefined; } PRINTB("WARNING: Can't find dimension '%s' in '%s', layer '%s'!", name % filename % layername); - return Value(); + return ValuePtr::undefined; } -Value builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx) +ValuePtr builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx) { std::string filename; std::string layername; @@ -151,14 +150,12 @@ Value builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx) // since the path is only available for ModuleInstantiations, not function expressions. // See isse #217 for (size_t i = 0; i < evalctx->numArgs(); i++) { - if (evalctx->getArgName(i) == "file") - filename = ctx->getAbsolutePath(evalctx->getArgValue(i).toString()); - if (evalctx->getArgName(i) == "layer") - layername = evalctx->getArgValue(i).toString(); - if (evalctx->getArgName(i) == "origin") - evalctx->getArgValue(i).getVec2(xorigin, yorigin); - if (evalctx->getArgName(i) == "scale") - evalctx->getArgValue(i).getDouble(scale); + ValuePtr n = evalctx->getArgName(i); + ValuePtr v = evalctx->getArgValue(i); + if (n == "file") filename = ctx->getAbsolutePath(v->toString()); + if (n == "layer") layername = v->toString(); + if (n == "origin") v->getVec2(xorigin, yorigin); + if (n == "scale") v->getDouble(scale); } std::stringstream keystream; @@ -174,8 +171,9 @@ Value builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx) << "|" << filesize; std::string key = keystream.str(); - if (dxf_cross_cache.find(key) != dxf_cross_cache.end()) + 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); @@ -204,13 +202,13 @@ Value builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx) Value::VectorType ret; ret.push_back(Value(x)); ret.push_back(Value(y)); - return dxf_cross_cache[key] = Value(ret); + return dxf_cross_cache[key] = ValuePtr(ret); } } PRINTB("WARNING: Can't find cross in '%s', layer '%s'!", filename % layername); - return Value(); + return ValuePtr::undefined; } void initialize_builtin_dxf_dim() diff --git a/src/dxfdim.h b/src/dxfdim.h index d84d07ce..bdadcee3 100644 --- a/src/dxfdim.h +++ b/src/dxfdim.h @@ -3,5 +3,5 @@ #include #include "value.h" -extern boost::unordered_map dxf_dim_cache; -extern boost::unordered_map dxf_cross_cache; +extern boost::unordered_map dxf_dim_cache; +extern boost::unordered_map dxf_cross_cache; diff --git a/src/evalcontext.cc b/src/evalcontext.cc index 1b3624e7..085a5f8f 100644 --- a/src/evalcontext.cc +++ b/src/evalcontext.cc @@ -14,11 +14,11 @@ const std::string &EvalContext::getArgName(size_t i) const return this->eval_arguments[i].first; } -Value EvalContext::getArgValue(size_t i, const Context *ctx) const +ValuePtr EvalContext::getArgValue(size_t i, const Context *ctx) const { assert(i < this->eval_arguments.size()); const Assignment &arg = this->eval_arguments[i]; - return arg.second ? arg.second->evaluate(ctx ? ctx : this) : Value(); + return arg.second ? arg.second->evaluate(ctx ? ctx : this) : ValuePtr::undefined; } size_t EvalContext::numChildren() const @@ -56,7 +56,7 @@ std::string EvalContext::dump(const AbstractModule *mod, const ModuleInstantiati if (m) { s << boost::format(" module args:"); BOOST_FOREACH(const Assignment &arg, m->definition_arguments) { - s << boost::format(" %s = %s") % arg.first % variables[arg.first]; + s << boost::format(" %s = %s") % arg.first % *(variables[arg.first]); } } } diff --git a/src/evalcontext.h b/src/evalcontext.h index 928e96f6..108de1cf 100644 --- a/src/evalcontext.h +++ b/src/evalcontext.h @@ -18,7 +18,7 @@ public: size_t numArgs() const { return this->eval_arguments.size(); } const std::string &getArgName(size_t i) const; - Value getArgValue(size_t i, const Context *ctx = NULL) const; + ValuePtr getArgValue(size_t i, const Context *ctx = NULL) const; size_t numChildren() const; ModuleInstantiation *getChild(size_t i) const; @@ -29,6 +29,6 @@ public: private: const AssignmentList &eval_arguments; - std::vector > eval_values; + std::vector > eval_values; const LocalScope *const scope; }; diff --git a/src/expr.cc b/src/expr.cc index ea83ba24..b2fa061d 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -52,7 +52,7 @@ Expression::Expression(const std::string &type, Expression *expr) this->children.push_back(expr); } -Expression::Expression(const Value &val) : const_value(val), type("C"), recursioncount(0) +Expression::Expression(const ValuePtr &val) : const_value(val), type("C"), recursioncount(0) { } @@ -61,62 +61,62 @@ Expression::~Expression() std::for_each(this->children.begin(), this->children.end(), del_fun()); } -Value Expression::sub_evaluate_range(const Context *context) const +ValuePtr Expression::sub_evaluate_range(const Context *context) const { - Value v1 = this->children[0]->evaluate(context); - if (v1.type() == Value::NUMBER) { - Value v2 = this->children[1]->evaluate(context); - if (v2.type() == Value::NUMBER) { + ValuePtr v1 = this->children[0]->evaluate(context); + if (v1->type() == Value::NUMBER) { + ValuePtr v2 = this->children[1]->evaluate(context); + if (v2->type() == Value::NUMBER) { if (this->children.size() == 2) { - Value::RangeType range(v1.toDouble(), v2.toDouble()); - return Value(range); + Value::RangeType range(v1->toDouble(), v2->toDouble()); + return ValuePtr(range); } else { - Value v3 = this->children[2]->evaluate(context); - if (v3.type() == Value::NUMBER) { - Value::RangeType range(v1.toDouble(), v2.toDouble(), v3.toDouble()); - return Value(range); + ValuePtr v3 = this->children[2]->evaluate(context); + if (v3->type() == Value::NUMBER) { + Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble()); + return ValuePtr(range); } } } } - return Value(); + return ValuePtr::undefined; } -Value Expression::sub_evaluate_member(const Context *context) const +ValuePtr Expression::sub_evaluate_member(const Context *context) const { - Value v = this->children[0]->evaluate(context); + ValuePtr v = this->children[0]->evaluate(context); - if (v.type() == Value::VECTOR) { + if (v->type() == Value::VECTOR) { if (this->var_name == "x") return v[0]; if (this->var_name == "y") return v[1]; if (this->var_name == "z") return v[2]; - } else if (v.type() == Value::RANGE) { - if (this->var_name == "begin") return Value(v[0]); - if (this->var_name == "step") return Value(v[1]); - if (this->var_name == "end") return Value(v[2]); + } else if (v->type() == Value::RANGE) { + if (this->var_name == "begin") return v[0]; + if (this->var_name == "step") return v[1]; + if (this->var_name == "end") return v[2]; } - return Value(); + return ValuePtr::undefined; } -Value Expression::sub_evaluate_vector(const Context *context) const +ValuePtr Expression::sub_evaluate_vector(const Context *context) const { Value::VectorType vec; BOOST_FOREACH(const Expression *e, this->children) { - vec.push_back(e->evaluate(context)); + vec.push_back(*(e->evaluate(context))); } - return Value(vec); + return ValuePtr(vec); } -Value Expression::sub_evaluate_function(const Context *context) const +ValuePtr Expression::sub_evaluate_function(const Context *context) const { if (this->recursioncount >= 1000) { PRINTB("ERROR: Recursion detected calling function '%s'", this->call_funcname); // TO DO: throw function_recursion_detected(); - return Value(); + return ValuePtr::undefined; } this->recursioncount += 1; EvalContext c(context, this->call_arguments); - const Value &result = context->evaluate_function(this->call_funcname, &c); + ValuePtr result = context->evaluate_function(this->call_funcname, &c); this->recursioncount -= 1; return result; } @@ -161,7 +161,7 @@ namespace { for (int i = 0; i < let_context.numArgs(); i++) { if (!allow_reassignment && context->has_local_variable(let_context.getArgName(i))) { - PRINTB("WARNING: Ignoring duplicate variable assignment %s = %s", let_context.getArgName(i) % let_context.getArgValue(i, context).toString()); + PRINTB("WARNING: Ignoring duplicate variable assignment %s = %s", let_context.getArgName(i) % let_context.getArgValue(i, context)->toString()); } else { // NOTE: iteratively evaluated list of arguments context->set_variable(let_context.getArgName(i), let_context.getArgValue(i, context)); @@ -170,7 +170,7 @@ namespace { } } -Value Expression::sub_evaluate_let_expression(const Context *context) const +ValuePtr Expression::sub_evaluate_let_expression(const Context *context) const { Context c(context); evaluate_sequential_assignment(this->call_arguments, &c); @@ -178,7 +178,7 @@ Value Expression::sub_evaluate_let_expression(const Context *context) const return this->children[0]->evaluate(&c); } -Value Expression::sub_evaluate_list_comprehension(const Context *context) const +ValuePtr Expression::sub_evaluate_list_comprehension(const Context *context) const { Value::VectorType vec; @@ -187,10 +187,10 @@ Value Expression::sub_evaluate_list_comprehension(const Context *context) const if (this->children[1]->type == "c") { return this->children[1]->evaluate(context); } else { - vec.push_back(this->children[1]->evaluate(context)); + vec.push_back((*this->children[1]->evaluate(context))); } } - return vec; + return ValuePtr(vec); } else if (this->call_funcname == "for") { EvalContext for_context(context, this->call_arguments); @@ -198,36 +198,36 @@ Value Expression::sub_evaluate_list_comprehension(const Context *context) const // comprehension for statements are by the parser reduced to only contain one single element const std::string &it_name = for_context.getArgName(0); - const Value &it_values = for_context.getArgValue(0, &assign_context); + ValuePtr it_values = for_context.getArgValue(0, &assign_context); Context c(context); - if (it_values.type() == Value::RANGE) { - Value::RangeType range = it_values.toRange(); + if (it_values->type() == Value::RANGE) { + Value::RangeType range = it_values->toRange(); boost::uint32_t steps = range.nbsteps(); if (steps >= 1000000) { PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps); } else { for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { - c.set_variable(it_name, Value(*it)); - vec.push_back(this->children[0]->evaluate(&c)); + c.set_variable(it_name, ValuePtr(*it)); + vec.push_back((*this->children[0]->evaluate(&c))); } } } - else if (it_values.type() == Value::VECTOR) { - for (size_t i = 0; i < it_values.toVector().size(); i++) { - c.set_variable(it_name, it_values.toVector()[i]); - vec.push_back(this->children[0]->evaluate(&c)); + else if (it_values->type() == Value::VECTOR) { + for (size_t i = 0; i < it_values->toVector().size(); i++) { + c.set_variable(it_name, it_values->toVector()[i]); + vec.push_back((*this->children[0]->evaluate(&c))); } } - else if (it_values.type() != Value::UNDEFINED) { + else if (it_values->type() != Value::UNDEFINED) { c.set_variable(it_name, it_values); - vec.push_back(this->children[0]->evaluate(&c)); + vec.push_back((*this->children[0]->evaluate(&c))); } if (this->children[0]->type == "c") { - return flatten(vec); + return ValuePtr(flatten(vec)); } else { - return vec; + return ValuePtr(vec); } } else if (this->call_funcname == "let") { Context c(context); @@ -240,7 +240,7 @@ Value Expression::sub_evaluate_list_comprehension(const Context *context) const } -Value Expression::evaluate(const Context *context) const +ValuePtr Expression::evaluate(const Context *context) const { switch (type2int(this->type.c_str())) { case '!': @@ -336,7 +336,7 @@ std::string Expression::toString() const stream << "!" << *this->children[0]; } else if (this->type == "C") { - stream << this->const_value; + stream << *this->const_value; } else if (this->type == "R") { stream << "[" << *this->children[0] << " : " << *this->children[1]; diff --git a/src/expression.h b/src/expression.h index b17496e5..07237ab7 100644 --- a/src/expression.h +++ b/src/expression.h @@ -10,7 +10,7 @@ class Expression public: std::vector children; - const Value const_value; + ValuePtr const_value; std::string var_name; std::string call_funcname; @@ -35,12 +35,12 @@ public: std::string type; Expression(); - Expression(const Value &val); + Expression(const ValuePtr &val); Expression(const std::string &type, Expression *left, Expression *right); Expression(const std::string &type, Expression *expr); ~Expression(); - Value evaluate(const class Context *context) const; + ValuePtr evaluate(const class Context *context) const; std::string toString() const; @@ -48,12 +48,12 @@ private: mutable int recursioncount; // The following sub_* methods are needed to minimize stack usage only. - Value sub_evaluate_function(const class Context *context) const; - Value sub_evaluate_member(const class Context *context) const; - Value sub_evaluate_range(const class Context *context) const; - Value sub_evaluate_vector(const class Context *context) const; - Value sub_evaluate_let_expression(const class Context *context) const; - Value sub_evaluate_list_comprehension(const class Context *context) const; + ValuePtr sub_evaluate_function(const class Context *context) const; + ValuePtr sub_evaluate_member(const class Context *context) const; + ValuePtr sub_evaluate_range(const class Context *context) const; + ValuePtr sub_evaluate_vector(const class Context *context) const; + ValuePtr sub_evaluate_let_expression(const class Context *context) const; + ValuePtr sub_evaluate_list_comprehension(const class Context *context) const; }; std::ostream &operator<<(std::ostream &stream, const Expression &expr); diff --git a/src/func.cc b/src/func.cc index f26f44c5..f1c9ada4 100644 --- a/src/func.cc +++ b/src/func.cc @@ -69,10 +69,11 @@ AbstractFunction::~AbstractFunction() { } -Value AbstractFunction::evaluate(const Context*, const EvalContext *evalctx) const +// FIXME: Is this needed? +ValuePtr AbstractFunction::evaluate(const Context*, const EvalContext *evalctx) const { (void)evalctx; // unusued parameter - return Value(); + return ValuePtr::undefined; } std::string AbstractFunction::dump(const std::string &indent, const std::string &name) const @@ -87,9 +88,9 @@ Function::~Function() delete expr; } -Value Function::evaluate(const Context *ctx, const EvalContext *evalctx) const +ValuePtr Function::evaluate(const Context *ctx, const EvalContext *evalctx) const { - if (!expr) return Value(); + if (!expr) return ValuePtr::undefined; Context c(ctx); c.setVariables(definition_arguments, evalctx); return expr->evaluate(&c); @@ -113,7 +114,7 @@ BuiltinFunction::~BuiltinFunction() { } -Value BuiltinFunction::evaluate(const Context *ctx, const EvalContext *evalctx) const +ValuePtr BuiltinFunction::evaluate(const Context *ctx, const EvalContext *evalctx) const { return eval_func(ctx, evalctx); } @@ -135,51 +136,51 @@ static inline double rad2deg(double x) return x * 180.0 / M_PI; } -Value builtin_abs(const Context *, const EvalContext *evalctx) +ValuePtr builtin_abs(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(fabs(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(fabs(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_sign(const Context *, const EvalContext *evalctx) +ValuePtr builtin_sign(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) { - register double x = v.toDouble(); - return Value((x<0) ? -1.0 : ((x>0) ? 1.0 : 0.0)); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) { + register double x = v->toDouble(); + return ValuePtr((x<0) ? -1.0 : ((x>0) ? 1.0 : 0.0)); } } - return Value(); + return ValuePtr::undefined; } -Value builtin_rands(const Context *, const EvalContext *evalctx) +ValuePtr builtin_rands(const Context *, const EvalContext *evalctx) { size_t n = evalctx->numArgs(); if (n == 3 || n == 4) { - const Value &v0 = evalctx->getArgValue(0); - if (v0.type() != Value::NUMBER) goto quit; - double min = v0.toDouble(); + ValuePtr v0 = evalctx->getArgValue(0); + if (v0->type() != Value::NUMBER) goto quit; + double min = v0->toDouble(); - const Value &v1 = evalctx->getArgValue(1); - if (v1.type() != Value::NUMBER) goto quit; - double max = v1.toDouble(); + ValuePtr v1 = evalctx->getArgValue(1); + if (v1->type() != Value::NUMBER) goto quit; + double max = v1->toDouble(); if (max < min) { register double tmp = min; min = max; max = tmp; } - const Value &v2 = evalctx->getArgValue(2); - if (v2.type() != Value::NUMBER) goto quit; - size_t numresults = std::max( 0, static_cast( v2.toDouble() ) ); + ValuePtr v2 = evalctx->getArgValue(2); + if (v2->type() != Value::NUMBER) goto quit; + size_t numresults = std::max(0, static_cast(v2->toDouble())); bool deterministic = false; if (n > 3) { - const Value &v3 = evalctx->getArgValue(3); - if (v3.type() != Value::NUMBER) goto quit; - deterministic_rng.seed( (unsigned int) v3.toDouble() ); + ValuePtr v3 = evalctx->getArgValue(3); + if (v3->type() != Value::NUMBER) goto quit; + deterministic_rng.seed((unsigned int) v3->toDouble()); deterministic = true; } boost::uniform_real<> distributor( min, max ); @@ -190,83 +191,81 @@ Value builtin_rands(const Context *, const EvalContext *evalctx) } else { for (size_t i=0; i < numresults; i++) { if ( deterministic ) { - vec.push_back( Value( distributor( deterministic_rng ) ) ); + vec.push_back(Value(distributor(deterministic_rng))); } else { - vec.push_back( Value( distributor( lessdeterministic_rng ) ) ); + vec.push_back(Value(distributor(lessdeterministic_rng))); } } } - return Value(vec); + return ValuePtr(vec); } quit: - return Value(); + return ValuePtr::undefined; } -Value builtin_min(const Context *, const EvalContext *evalctx) +ValuePtr builtin_min(const Context *, const EvalContext *evalctx) { // preserve special handling of the first argument // as a template for vector processing size_t n = evalctx->numArgs(); if (n >= 1) { - const Value &v0 = evalctx->getArgValue(0); + ValuePtr v0 = evalctx->getArgValue(0); - if (n == 1 && v0.type() == Value::VECTOR && !v0.toVector().empty()) { - Value min = v0.toVector()[0]; - for (size_t i = 1; i < v0.toVector().size(); i++) { - if (v0.toVector()[i] < min) - min = v0.toVector()[i]; + if (n == 1 && v0->type() == Value::VECTOR && !v0->toVector().empty()) { + Value min = v0->toVector()[0]; + for (size_t i = 1; i < v0->toVector().size(); i++) { + if (v0->toVector()[i] < min) min = v0->toVector()[i]; } - return min; + return ValuePtr(min); } - if (v0.type() == Value::NUMBER) { - double val = v0.toDouble(); + if (v0->type() == Value::NUMBER) { + double val = v0->toDouble(); for (size_t i = 1; i < n; ++i) { - const Value &v = evalctx->getArgValue(i); + ValuePtr v = evalctx->getArgValue(i); // 4/20/14 semantic change per discussion: // break on any non-number - if (v.type() != Value::NUMBER) goto quit; - register double x = v.toDouble(); + if (v->type() != Value::NUMBER) goto quit; + register double x = v->toDouble(); if (x < val) val = x; } - return Value(val); + return ValuePtr(val); } } quit: - return Value(); + return ValuePtr::undefined; } -Value builtin_max(const Context *, const EvalContext *evalctx) +ValuePtr builtin_max(const Context *, const EvalContext *evalctx) { // preserve special handling of the first argument // as a template for vector processing size_t n = evalctx->numArgs(); if (n >= 1) { - const Value &v0 = evalctx->getArgValue(0); + ValuePtr v0 = evalctx->getArgValue(0); - if (n == 1 && v0.type() == Value::VECTOR && !v0.toVector().empty()) { - Value max = v0.toVector()[0]; - for (size_t i = 1; i < v0.toVector().size(); i++) { - if (v0.toVector()[i] > max) - max = v0.toVector()[i]; + if (n == 1 && v0->type() == Value::VECTOR && !v0->toVector().empty()) { + Value max = v0->toVector()[0]; + for (size_t i = 1; i < v0->toVector().size(); i++) { + if (v0->toVector()[i] > max) max = v0->toVector()[i]; } - return max; + return ValuePtr(max); } - if (v0.type() == Value::NUMBER) { - double val = v0.toDouble(); + if (v0->type() == Value::NUMBER) { + double val = v0->toDouble(); for (size_t i = 1; i < n; ++i) { - const Value &v = evalctx->getArgValue(i); + ValuePtr v = evalctx->getArgValue(i); // 4/20/14 semantic change per discussion: // break on any non-number - if (v.type() != Value::NUMBER) goto quit; - register double x = v.toDouble(); + if (v->type() != Value::NUMBER) goto quit; + register double x = v->toDouble(); if (x > val) val = x; } - return Value(val); + return ValuePtr(val); } } quit: - return Value(); + return ValuePtr::undefined; } // this limit assumes 26+26=52 bits mantissa @@ -307,14 +306,14 @@ double sin_degrees(register double x) return oppose ? -x : x; } -Value builtin_sin(const Context *, const EvalContext *evalctx) +ValuePtr builtin_sin(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(sin_degrees(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(sin_degrees(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } double cos_degrees(register double x) @@ -354,220 +353,221 @@ double cos_degrees(register double x) return oppose ? -x : x; } -Value builtin_cos(const Context *, const EvalContext *evalctx) +ValuePtr builtin_cos(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(cos_degrees(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(cos_degrees(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_asin(const Context *, const EvalContext *evalctx) +ValuePtr builtin_asin(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(rad2deg(asin(v.toDouble()))); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(rad2deg(asin(v->toDouble()))); } - return Value(); + return ValuePtr::undefined; } -Value builtin_acos(const Context *, const EvalContext *evalctx) +ValuePtr builtin_acos(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(rad2deg(acos(v.toDouble()))); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(rad2deg(acos(v->toDouble()))); } - return Value(); + return ValuePtr::undefined; } -Value builtin_tan(const Context *, const EvalContext *evalctx) +ValuePtr builtin_tan(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(tan(deg2rad(v.toDouble()))); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(tan(deg2rad(v->toDouble()))); } - return Value(); + return ValuePtr::undefined; } -Value builtin_atan(const Context *, const EvalContext *evalctx) +ValuePtr builtin_atan(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(rad2deg(atan(v.toDouble()))); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(rad2deg(atan(v->toDouble()))); } - return Value(); + return ValuePtr::undefined; } -Value builtin_atan2(const Context *, const EvalContext *evalctx) +ValuePtr builtin_atan2(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 2) { - Value v0 = evalctx->getArgValue(0), v1 = evalctx->getArgValue(1); - if (v0.type() == Value::NUMBER && v1.type() == Value::NUMBER) - return Value(rad2deg(atan2(v0.toDouble(), v1.toDouble()))); + ValuePtr v0 = evalctx->getArgValue(0), v1 = evalctx->getArgValue(1); + if (v0->type() == Value::NUMBER && v1->type() == Value::NUMBER) + return ValuePtr(rad2deg(atan2(v0->toDouble(), v1->toDouble()))); } - return Value(); + return ValuePtr::undefined; } -Value builtin_pow(const Context *, const EvalContext *evalctx) +ValuePtr builtin_pow(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 2) { - Value v0 = evalctx->getArgValue(0), v1 = evalctx->getArgValue(1); - if (v0.type() == Value::NUMBER && v1.type() == Value::NUMBER) - return Value(pow(v0.toDouble(), v1.toDouble())); + ValuePtr v0 = evalctx->getArgValue(0), v1 = evalctx->getArgValue(1); + if (v0->type() == Value::NUMBER && v1->type() == Value::NUMBER) + return ValuePtr(pow(v0->toDouble(), v1->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_round(const Context *, const EvalContext *evalctx) +ValuePtr builtin_round(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(round(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(round(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_ceil(const Context *, const EvalContext *evalctx) +ValuePtr builtin_ceil(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(ceil(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(ceil(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_floor(const Context *, const EvalContext *evalctx) +ValuePtr builtin_floor(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(floor(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(floor(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_sqrt(const Context *, const EvalContext *evalctx) +ValuePtr builtin_sqrt(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(sqrt(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(sqrt(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_exp(const Context *, const EvalContext *evalctx) +ValuePtr builtin_exp(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(exp(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(exp(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_length(const Context *, const EvalContext *evalctx) +ValuePtr builtin_length(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::VECTOR) return Value(int(v.toVector().size())); - if (v.type() == Value::STRING) { + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::VECTOR) return ValuePtr(int(v->toVector().size())); + if (v->type() == Value::STRING) { //Unicode glyph count for the length -- rather than the string (num. of bytes) length. - std::string text = v.toString(); - return Value(int( g_utf8_strlen( text.c_str(), text.size() ) )); + std::string text = v->toString(); + return ValuePtr(int( g_utf8_strlen( text.c_str(), text.size() ) )); } } - return Value(); + return ValuePtr::undefined; } -Value builtin_log(const Context *, const EvalContext *evalctx) +ValuePtr builtin_log(const Context *, const EvalContext *evalctx) { size_t n = evalctx->numArgs(); if (n == 1 || n == 2) { - const Value &v0 = evalctx->getArgValue(0); - if (v0.type() == Value::NUMBER) { - double x = 10.0, y = v0.toDouble(); + ValuePtr v0 = evalctx->getArgValue(0); + if (v0->type() == Value::NUMBER) { + double x = 10.0, y = v0->toDouble(); if (n > 1) { - const Value &v1 = evalctx->getArgValue(1); - if (v1.type() != Value::NUMBER) goto quit; - x = y; y = v1.toDouble(); + ValuePtr v1 = evalctx->getArgValue(1); + if (v1->type() != Value::NUMBER) goto quit; + x = y; y = v1->toDouble(); } - return Value(log(y) / log(x)); + return ValuePtr(log(y) / log(x)); } } quit: - return Value(); + return ValuePtr::undefined; } -Value builtin_ln(const Context *, const EvalContext *evalctx) +ValuePtr builtin_ln(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() == Value::NUMBER) - return Value(log(v.toDouble())); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() == Value::NUMBER) + return ValuePtr(log(v->toDouble())); } - return Value(); + return ValuePtr::undefined; } -Value builtin_str(const Context *, const EvalContext *evalctx) +ValuePtr builtin_str(const Context *, const EvalContext *evalctx) { std::stringstream stream; for (size_t i = 0; i < evalctx->numArgs(); i++) { - stream << evalctx->getArgValue(i).toString(); + stream << evalctx->getArgValue(i)->toString(); } - return Value(stream.str()); + return ValuePtr(stream.str()); } -Value builtin_chr(const Context *, const EvalContext *evalctx) +ValuePtr builtin_chr(const Context *, const EvalContext *evalctx) { std::stringstream stream; for (size_t i = 0; i < evalctx->numArgs(); i++) { - const Value v = evalctx->getArgValue(i); - stream << v.chrString(); + ValuePtr v = evalctx->getArgValue(i); + stream << v->chrString(); } - return Value(stream.str()); + return ValuePtr(stream.str()); } -Value builtin_concat(const Context *, const EvalContext *evalctx) +ValuePtr builtin_concat(const Context *, const EvalContext *evalctx) { Value::VectorType result; for (size_t i = 0; i < evalctx->numArgs(); i++) { - const Value v = evalctx->getArgValue(i); - if (v.type() == Value::VECTOR) { - Value::VectorType vec = v.toVector(); + ValuePtr v = evalctx->getArgValue(i); + if (v->type() == Value::VECTOR) { + Value::VectorType vec = v->toVector(); for (Value::VectorType::const_iterator it = vec.begin(); it != vec.end(); it++) { result.push_back(*it); } } else { - result.push_back(v); + result.push_back(*v); } } - return Value(result); + return ValuePtr(result); } -Value builtin_lookup(const Context *, const EvalContext *evalctx) +ValuePtr builtin_lookup(const Context *, const EvalContext *evalctx) { double p, low_p, low_v, high_p, high_v; if (evalctx->numArgs() < 2 || // Needs two args - !evalctx->getArgValue(0).getDouble(p)) // First must be a number - return Value(); + !evalctx->getArgValue(0)->getDouble(p)) // First must be a number + return ValuePtr::undefined; - const Value::VectorType vec = evalctx->getArgValue(1).toVector(); + ValuePtr v1 = evalctx->getArgValue(1); + const Value::VectorType &vec = v1->toVector(); if (vec[0].toVector().size() < 2) // Second must be a vector of vectors - return Value(); + return ValuePtr::undefined; if (!vec[0].getVec2(low_p, low_v) || !vec[0].getVec2(high_p, high_v)) - return Value(); + return ValuePtr::undefined; for (size_t i = 1; i < vec.size(); i++) { double this_p, this_v; if (vec[i].getVec2(this_p, this_v)) { @@ -582,11 +582,11 @@ Value builtin_lookup(const Context *, const EvalContext *evalctx) } } if (p <= low_p) - return Value(high_v); + return ValuePtr(high_v); if (p >= high_p) - return Value(low_v); + return ValuePtr(low_v); double f = (p-low_p) / (high_p-low_p); - return Value(high_v * f + low_v * (1-f)); + return ValuePtr(high_v * f + low_v * (1-f)); } /* @@ -715,48 +715,48 @@ static Value::VectorType search(const std::string &find, const Value::VectorType return returnvec; } -Value builtin_search(const Context *, const EvalContext *evalctx) +ValuePtr builtin_search(const Context *, const EvalContext *evalctx) { - if (evalctx->numArgs() < 2) return Value(); + if (evalctx->numArgs() < 2) return ValuePtr::undefined; - const Value &findThis = evalctx->getArgValue(0); - const Value &searchTable = evalctx->getArgValue(1); - unsigned int num_returns_per_match = (evalctx->numArgs() > 2) ? evalctx->getArgValue(2).toDouble() : 1; - unsigned int index_col_num = (evalctx->numArgs() > 3) ? evalctx->getArgValue(3).toDouble() : 0; + ValuePtr findThis = evalctx->getArgValue(0); + ValuePtr searchTable = evalctx->getArgValue(1); + unsigned int num_returns_per_match = (evalctx->numArgs() > 2) ? evalctx->getArgValue(2)->toDouble() : 1; + unsigned int index_col_num = (evalctx->numArgs() > 3) ? evalctx->getArgValue(3)->toDouble() : 0; Value::VectorType returnvec; - if (findThis.type() == Value::NUMBER) { + if (findThis->type() == Value::NUMBER) { unsigned int matchCount = 0; - for (size_t j = 0; j < searchTable.toVector().size(); j++) { - const Value& search_element = searchTable.toVector()[j]; + for (size_t j = 0; j < searchTable->toVector().size(); j++) { + const Value &search_element = searchTable->toVector()[j]; - if ((index_col_num == 0 && findThis == search_element) || + if ((index_col_num == 0 && *findThis == search_element) || (index_col_num < search_element.toVector().size() && - findThis == search_element.toVector()[index_col_num])) { + *findThis == search_element.toVector()[index_col_num])) { returnvec.push_back(Value(double(j))); matchCount++; if (num_returns_per_match != 0 && matchCount >= num_returns_per_match) break; } } - } else if (findThis.type() == Value::STRING) { - if (searchTable.type() == Value::STRING) { - returnvec = search(findThis.toString(), searchTable.toString(), num_returns_per_match, index_col_num); + } else if (findThis->type() == Value::STRING) { + if (searchTable->type() == Value::STRING) { + returnvec = search(findThis->toString(), searchTable->toString(), num_returns_per_match, index_col_num); } else { - returnvec = search(findThis.toString(), searchTable.toVector(), num_returns_per_match, index_col_num); + returnvec = search(findThis->toString(), searchTable->toVector(), num_returns_per_match, index_col_num); } - } else if (findThis.type() == Value::VECTOR) { - for (size_t i = 0; i < findThis.toVector().size(); i++) { + } else if (findThis->type() == Value::VECTOR) { + for (size_t i = 0; i < findThis->toVector().size(); i++) { unsigned int matchCount = 0; Value::VectorType resultvec; - Value const& find_value = findThis.toVector()[i]; + Value const& find_value = findThis->toVector()[i]; - for (size_t j = 0; j < searchTable.toVector().size(); j++) { + for (size_t j = 0; j < searchTable->toVector().size(); j++) { - Value const& search_element = searchTable.toVector()[j]; + Value const& search_element = searchTable->toVector()[j]; if ((index_col_num == 0 && find_value == search_element) || (index_col_num < search_element.toVector().size() && @@ -773,53 +773,53 @@ Value builtin_search(const Context *, const EvalContext *evalctx) } } if (num_returns_per_match == 1 && matchCount == 0) { - if (findThis.toVector()[i].type() == Value::NUMBER) { - PRINTB(" WARNING: search term not found: %s",findThis.toVector()[i].toDouble()); + if (findThis->toVector()[i].type() == Value::NUMBER) { + PRINTB(" WARNING: search term not found: %s",findThis->toVector()[i].toDouble()); } - else if (findThis.toVector()[i].type() == Value::STRING) { - PRINTB(" WARNING: search term not found: \"%s\"",findThis.toVector()[i].toString()); + else if (findThis->toVector()[i].type() == Value::STRING) { + PRINTB(" WARNING: search term not found: \"%s\"",findThis->toVector()[i].toString()); } - returnvec.push_back(Value(resultvec)); + returnvec.push_back(resultvec); } if (num_returns_per_match == 0 || num_returns_per_match > 1) { - returnvec.push_back(Value(resultvec)); + returnvec.push_back(resultvec); } } } else { PRINTB(" WARNING: search: none performed on input %s", findThis); - return Value(); + return ValuePtr::undefined; } - return Value(returnvec); + return ValuePtr(returnvec); } #define QUOTE(x__) # x__ #define QUOTED(x__) QUOTE(x__) -Value builtin_version(const Context *, const EvalContext *evalctx) +ValuePtr builtin_version(const Context *, const EvalContext *evalctx) { (void)evalctx; // unusued parameter Value::VectorType val; - val.push_back(Value(double(OPENSCAD_YEAR))); - val.push_back(Value(double(OPENSCAD_MONTH))); + val.push_back(double(OPENSCAD_YEAR)); + val.push_back(double(OPENSCAD_MONTH)); #ifdef OPENSCAD_DAY - val.push_back(Value(double(OPENSCAD_DAY))); + val.push_back(double(OPENSCAD_DAY)); #endif - return Value(val); + return ValuePtr(val); } -Value builtin_version_num(const Context *ctx, const EvalContext *evalctx) +ValuePtr builtin_version_num(const Context *ctx, const EvalContext *evalctx) { - Value val = (evalctx->numArgs() == 0) ? builtin_version(ctx, evalctx) : evalctx->getArgValue(0); + ValuePtr val = (evalctx->numArgs() == 0) ? builtin_version(ctx, evalctx) : evalctx->getArgValue(0); double y, m, d = 0; - if (!val.getVec3(y, m, d)) { - if (!val.getVec2(y, m)) { - return Value(); + if (!val->getVec3(y, m, d)) { + if (!val->getVec2(y, m)) { + return ValuePtr::undefined; } } - return Value(y * 10000 + m * 100 + d); + return ValuePtr(y * 10000 + m * 100 + d); } -Value builtin_parent_module(const Context *, const EvalContext *evalctx) +ValuePtr builtin_parent_module(const Context *, const EvalContext *evalctx) { int n; double d; @@ -827,30 +827,30 @@ Value builtin_parent_module(const Context *, const EvalContext *evalctx) if (evalctx->numArgs() == 0) d=1; // parent module else if (evalctx->numArgs() == 1) { - const Value &v = evalctx->getArgValue(0); - if (v.type() != Value::NUMBER) return Value(); - v.getDouble(d); + ValuePtr v = evalctx->getArgValue(0); + if (v->type() != Value::NUMBER) return ValuePtr::undefined; + v->getDouble(d); } else - return Value(); + return ValuePtr::undefined; n=trunc(d); if (n < 0) { PRINTB("WARNING: Negative parent module index (%d) not allowed", n); - return Value(); + return ValuePtr::undefined; } if (n >= s) { PRINTB("WARNING: Parent module index (%d) greater than the number of modules on the stack", n); - return Value(); + return ValuePtr::undefined; } - return Value(Module::stack_element(s - 1 - n)); + return ValuePtr(Module::stack_element(s - 1 - n)); } -Value builtin_norm(const Context *, const EvalContext *evalctx) +ValuePtr builtin_norm(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() == 1) { - const Value &val = evalctx->getArgValue(0); - if (val.type() == Value::VECTOR) { + ValuePtr val = evalctx->getArgValue(0); + if (val->type() == Value::VECTOR) { double sum = 0; - Value::VectorType v = val.toVector(); + Value::VectorType v = val->toVector(); size_t n = v.size(); for (size_t i = 0; i < n; i++) if (v[i].type() == Value::NUMBER) { @@ -859,48 +859,48 @@ Value builtin_norm(const Context *, const EvalContext *evalctx) sum += x*x; } else { PRINT(" WARNING: Incorrect arguments to norm()"); - return Value(); + return ValuePtr::undefined; } - return Value(sqrt(sum)); + return ValuePtr(sqrt(sum)); } } - return Value(); + return ValuePtr::undefined; } -Value builtin_cross(const Context *, const EvalContext *evalctx) +ValuePtr builtin_cross(const Context *, const EvalContext *evalctx) { if (evalctx->numArgs() != 2) { PRINT("WARNING: Invalid number of parameters for cross()"); - return Value(); + return ValuePtr::undefined; } - Value arg0 = evalctx->getArgValue(0); - Value arg1 = evalctx->getArgValue(1); - if ((arg0.type() != Value::VECTOR) || (arg1.type() != Value::VECTOR)) { + ValuePtr arg0 = evalctx->getArgValue(0); + ValuePtr arg1 = evalctx->getArgValue(1); + if ((arg0->type() != Value::VECTOR) || (arg1->type() != Value::VECTOR)) { PRINT("WARNING: Invalid type of parameters for cross()"); - return Value(); + return ValuePtr::undefined; } - Value::VectorType v0 = arg0.toVector(); - Value::VectorType v1 = arg1.toVector(); + Value::VectorType v0 = arg0->toVector(); + Value::VectorType v1 = arg1->toVector(); if ((v0.size() != 3) || (v1.size() != 3)) { PRINT("WARNING: Invalid vector size of parameter for cross()"); - return Value(); + return ValuePtr::undefined; } for (unsigned int a = 0;a < 3;a++) { if ((v0[a].type() != Value::NUMBER) || (v1[a].type() != Value::NUMBER)) { PRINT("WARNING: Invalid value in parameter vector for cross()"); - return Value(); + return ValuePtr::undefined; } double d0 = v0[a].toDouble(); double d1 = v1[a].toDouble(); if (boost::math::isnan(d0) || boost::math::isnan(d1)) { PRINT("WARNING: Invalid value (NaN) in parameter vector for cross()"); - return Value(); + return ValuePtr::undefined; } if (boost::math::isinf(d0) || boost::math::isinf(d1)) { PRINT("WARNING: Invalid value (INF) in parameter vector for cross()"); - return Value(); + return ValuePtr::undefined; } } @@ -912,7 +912,7 @@ Value builtin_cross(const Context *, const EvalContext *evalctx) result.push_back(Value(x)); result.push_back(Value(y)); result.push_back(Value(z)); - return Value(result); + return ValuePtr(result); } void register_builtin_functions() diff --git a/src/function.h b/src/function.h index d8e3ad77..fe39f61f 100644 --- a/src/function.h +++ b/src/function.h @@ -11,28 +11,28 @@ class AbstractFunction { private: - const Feature *feature; + const Feature *feature; public: - AbstractFunction() : feature(NULL) {} - AbstractFunction(const Feature& feature) : feature(&feature) {} + AbstractFunction() : feature(NULL) {} + AbstractFunction(const Feature& feature) : feature(&feature) {} virtual ~AbstractFunction(); - virtual bool is_experimental() const { return feature != NULL; } - virtual bool is_enabled() const { return (feature == NULL) || feature->is_enabled(); } - virtual Value evaluate(const class Context *ctx, const class EvalContext *evalctx) const; + virtual bool is_experimental() const { return feature != NULL; } + virtual bool is_enabled() const { return (feature == NULL) || feature->is_enabled(); } + virtual ValuePtr evaluate(const class Context *ctx, const class EvalContext *evalctx) 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 EvalContext *evalctx); + typedef ValuePtr (*eval_func_t)(const Context *ctx, const EvalContext *evalctx); eval_func_t eval_func; BuiltinFunction(eval_func_t f) : eval_func(f) { } BuiltinFunction(eval_func_t f, const Feature& feature) : AbstractFunction(feature), eval_func(f) { } virtual ~BuiltinFunction(); - virtual Value evaluate(const Context *ctx, const EvalContext *evalctx) const; + virtual ValuePtr evaluate(const Context *ctx, const EvalContext *evalctx) const; virtual std::string dump(const std::string &indent, const std::string &name) const; }; @@ -46,6 +46,6 @@ public: Function() { } virtual ~Function(); - virtual Value evaluate(const Context *ctx, const EvalContext *evalctx) const; + virtual ValuePtr evaluate(const Context *ctx, const EvalContext *evalctx) const; virtual std::string dump(const std::string &indent, const std::string &name) const; }; diff --git a/src/import.cc b/src/import.cc index 3841dc02..79ebb4bc 100644 --- a/src/import.cc +++ b/src/import.cc @@ -91,18 +91,18 @@ AbstractNode *ImportModule::instantiate(const Context *ctx, const ModuleInstanti c.dump(this, inst); #endif - Value v = c.lookup_variable("file"); - if (v.isUndefined()) { + ValuePtr v = c.lookup_variable("file"); + if (v->isUndefined()) { v = c.lookup_variable("filename"); - if (!v.isUndefined()) { + if (!v->isUndefined()) { printDeprecation("DEPRECATED: filename= is deprecated. Please use file="); } } - std::string filename = lookup_file(v.isUndefined() ? "" : v.toString(), inst->path(), ctx->documentPath()); + std::string filename = lookup_file(v->isUndefined() ? "" : v->toString(), inst->path(), ctx->documentPath()); import_type_e actualtype = this->type; if (actualtype == TYPE_UNKNOWN) { - std::string extraw = boosty::extension_str( fs::path(filename) ); - std::string ext = boost::algorithm::to_lower_copy( extraw ); + std::string extraw = boosty::extension_str(fs::path(filename)); + std::string ext = boost::algorithm::to_lower_copy(extraw); if (ext == ".stl") actualtype = TYPE_STL; else if (ext == ".off") actualtype = TYPE_OFF; else if (ext == ".dxf") actualtype = TYPE_DXF; @@ -110,31 +110,30 @@ AbstractNode *ImportModule::instantiate(const Context *ctx, const ModuleInstanti ImportNode *node = new ImportNode(inst, actualtype); - node->fn = c.lookup_variable("$fn").toDouble(); - node->fs = c.lookup_variable("$fs").toDouble(); - node->fa = c.lookup_variable("$fa").toDouble(); + node->fn = c.lookup_variable("$fn")->toDouble(); + node->fs = c.lookup_variable("$fs")->toDouble(); + node->fa = c.lookup_variable("$fa")->toDouble(); node->filename = filename; - Value layerval = c.lookup_variable("layer", true); + Value layerval = *c.lookup_variable("layer", true); if (layerval.isUndefined()) { - layerval = c.lookup_variable("layername"); + layerval = *c.lookup_variable("layername"); if (!layerval.isUndefined()) { printDeprecation("DEPRECATED: layername= is deprecated. Please use layer="); } } node->layername = layerval.isUndefined() ? "" : layerval.toString(); - node->convexity = c.lookup_variable("convexity", true).toDouble(); + node->convexity = c.lookup_variable("convexity", true)->toDouble(); if (node->convexity <= 0) node->convexity = 1; - Value origin = c.lookup_variable("origin", true); + ValuePtr origin = c.lookup_variable("origin", true); node->origin_x = node->origin_y = 0; - origin.getVec2(node->origin_x, node->origin_y); + origin->getVec2(node->origin_x, node->origin_y); - node->scale = c.lookup_variable("scale", true).toDouble(); + node->scale = c.lookup_variable("scale", true)->toDouble(); - if (node->scale <= 0) - node->scale = 1; + if (node->scale <= 0) node->scale = 1; return node; } diff --git a/src/linearextrude.cc b/src/linearextrude.cc index c3ba1ee6..c6bd8256 100644 --- a/src/linearextrude.cc +++ b/src/linearextrude.cc @@ -59,46 +59,46 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI Context c(ctx); c.setVariables(args, evalctx); - node->fn = c.lookup_variable("$fn").toDouble(); - node->fs = c.lookup_variable("$fs").toDouble(); - node->fa = c.lookup_variable("$fa").toDouble(); + node->fn = c.lookup_variable("$fn")->toDouble(); + node->fs = c.lookup_variable("$fs")->toDouble(); + node->fa = c.lookup_variable("$fa")->toDouble(); - Value file = c.lookup_variable("file"); - Value layer = c.lookup_variable("layer", true); - Value height = c.lookup_variable("height", true); - Value convexity = c.lookup_variable("convexity", true); - Value origin = c.lookup_variable("origin", true); - Value scale = c.lookup_variable("scale", true); - Value center = c.lookup_variable("center", true); - Value twist = c.lookup_variable("twist", true); - Value slices = c.lookup_variable("slices", true); + ValuePtr file = c.lookup_variable("file"); + ValuePtr layer = c.lookup_variable("layer", true); + ValuePtr height = c.lookup_variable("height", true); + ValuePtr convexity = c.lookup_variable("convexity", true); + ValuePtr origin = c.lookup_variable("origin", true); + ValuePtr scale = c.lookup_variable("scale", true); + ValuePtr center = c.lookup_variable("center", true); + ValuePtr twist = c.lookup_variable("twist", true); + ValuePtr slices = c.lookup_variable("slices", true); - if (!file.isUndefined() && file.type() == Value::STRING) { + if (!file->isUndefined() && file->type() == Value::STRING) { printDeprecation("DEPRECATED: Support for reading files in linear_extrude will be removed in future releases. Use a child import() instead."); - node->filename = lookup_file(file.toString(), inst->path(), c.documentPath()); + node->filename = lookup_file(file->toString(), inst->path(), c.documentPath()); } // if height not given, and first argument is a number, // then assume it should be the height. - if (c.lookup_variable("height").isUndefined() && + if (c.lookup_variable("height")->isUndefined() && evalctx->numArgs() > 0 && evalctx->getArgName(0) == "") { - const Value &val = evalctx->getArgValue(0); - if (val.type() == Value::NUMBER) height = val; + ValuePtr val = evalctx->getArgValue(0); + if (val->type() == Value::NUMBER) height = val; } - node->layername = layer.isUndefined() ? "" : layer.toString(); + node->layername = layer->isUndefined() ? "" : layer->toString(); node->height = 100; - height.getDouble(node->height); - node->convexity = (int)convexity.toDouble(); - origin.getVec2(node->origin_x, node->origin_y); + height->getDouble(node->height); + node->convexity = (int)convexity->toDouble(); + origin->getVec2(node->origin_x, node->origin_y); node->scale_x = node->scale_y = 1; - scale.getDouble(node->scale_x); - scale.getDouble(node->scale_y); - scale.getVec2(node->scale_x, node->scale_y); + scale->getDouble(node->scale_x); + scale->getDouble(node->scale_y); + scale->getVec2(node->scale_x, node->scale_y); - if (center.type() == Value::BOOL) - node->center = center.toBool(); + if (center->type() == Value::BOOL) + node->center = center->toBool(); if (node->height <= 0) node->height = 0; @@ -108,10 +108,10 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI if (node->scale_x < 0) node->scale_x = 0; if (node->scale_y < 0) node->scale_y = 0; - if (slices.type() == Value::NUMBER) node->slices = (int)slices.toDouble(); + if (slices->type() == Value::NUMBER) node->slices = (int)slices->toDouble(); - if (twist.type() == Value::NUMBER) { - node->twist = twist.toDouble(); + if (twist->type() == Value::NUMBER) { + node->twist = twist->toDouble(); if (node->twist != 0.0) { if (node->slices == 0) { node->slices = (int)fmax(2, fabs(Calc::get_fragments_from_r(node->height, diff --git a/src/mainwin.cc b/src/mainwin.cc index 776a46ed..4d830742 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1485,7 +1485,7 @@ bool MainWindow::eventFilter(QObject* obj, QEvent *event) void MainWindow::updateTemporalVariables() { - this->top_ctx.set_variable("$t", Value(this->e_tval->text().toDouble())); + this->top_ctx.set_variable("$t", ValuePtr(this->e_tval->text().toDouble())); Value::VectorType vpt; vpt.push_back(Value(-qglview->cam.object_trans.x())); @@ -1497,9 +1497,9 @@ void MainWindow::updateTemporalVariables() vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.x() + 90, 360))); vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.y(), 360))); vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.z(), 360))); - top_ctx.set_variable("$vpr", Value(vpr)); + top_ctx.set_variable("$vpr", ValuePtr(vpr)); - top_ctx.set_variable("$vpd", Value(qglview->cam.viewer_distance)); + top_ctx.set_variable("$vpd", ValuePtr(qglview->cam.viewer_distance)); } @@ -1531,25 +1531,25 @@ void MainWindow::updateCamera() BOOST_FOREACH(const Assignment &a, root_module->scope.assignments) { double x, y, z; if ("$vpr" == a.first) { - const Value vpr = a.second.get()->evaluate(&mc); - if (vpr.getVec3(x, y, z)) { + ValuePtr vpr = a.second.get()->evaluate(&mc); + if (vpr->getVec3(x, y, z)) { rx = x; ry = y; rz = z; camera_set = true; } } else if ("$vpt" == a.first) { - const Value vpt = a.second.get()->evaluate(&mc); - if (vpt.getVec3(x, y, z)) { + ValuePtr vpt = a.second.get()->evaluate(&mc); + if (vpt->getVec3(x, y, z)) { tx = x; ty = y; tz = z; camera_set = true; } } else if ("$vpd" == a.first) { - const Value vpd = a.second.get()->evaluate(&mc); - if (vpd.type() == Value::NUMBER) { - d = vpd.toDouble(); + ValuePtr vpd = a.second.get()->evaluate(&mc); + if (vpd->type() == Value::NUMBER) { + d = vpd->toDouble(); camera_set = true; } } diff --git a/src/memory.h b/src/memory.h index 1f54e4b3..86cd6aba 100644 --- a/src/memory.h +++ b/src/memory.h @@ -1,6 +1,8 @@ #pragma once #include +#include using boost::shared_ptr; +using boost::make_shared; using boost::dynamic_pointer_cast; using boost::static_pointer_cast; diff --git a/src/modcontext.cc b/src/modcontext.cc index c6210f42..7269f6e0 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -24,8 +24,8 @@ void ModuleContext::evaluateAssignments(const AssignmentList &assignments) // First, assign all simple variables std::list undefined_vars; BOOST_FOREACH(const Assignment &ass, assignments) { - Value tmpval = ass.second->evaluate(this); - if (tmpval.isUndefined()) undefined_vars.push_back(ass.first); + ValuePtr tmpval = ass.second->evaluate(this); + if (tmpval->isUndefined()) undefined_vars.push_back(ass.first); else this->set_variable(ass.first, tmpval); } @@ -46,12 +46,12 @@ void ModuleContext::evaluateAssignments(const AssignmentList &assignments) boost::unordered_map::iterator found = tmpass.find(*curr); if (found != tmpass.end()) { const Expression *expr = found->second; - Value tmpval = expr->evaluate(this); + ValuePtr tmpval = expr->evaluate(this); // FIXME: it's not enough to check for undefined; // we need to check for any undefined variable in the subexpression // For now, ignore this and revisit the validity and order of variable // assignments later - if (!tmpval.isUndefined()) { + if (!tmpval->isUndefined()) { changed = true; this->set_variable(*curr, tmpval); undefined_vars.erase(curr); @@ -89,7 +89,7 @@ void ModuleContext::registerBuiltin() this->set_variable(ass.first, ass.second->evaluate(this)); } - this->set_constant("PI",Value(M_PI)); + this->set_constant("PI", ValuePtr(M_PI)); } const AbstractFunction *ModuleContext::findLocalFunction(const std::string &name) const @@ -122,7 +122,8 @@ const AbstractModule *ModuleContext::findLocalModule(const std::string &name) co return NULL; } -Value ModuleContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const +ValuePtr ModuleContext::evaluate_function(const std::string &name, + const EvalContext *evalctx) const { const AbstractFunction *foundf = findLocalFunction(name); if (foundf) return foundf->evaluate(this, evalctx); @@ -156,7 +157,7 @@ std::string ModuleContext::dump(const AbstractModule *mod, const ModuleInstantia } } } - typedef std::pair ValueMapType; + typedef std::pair ValueMapType; s << " vars:"; BOOST_FOREACH(const ValueMapType &v, constants) { s << boost::format(" %s = %s") % v.first % v.second; @@ -177,9 +178,9 @@ FileContext::FileContext(const class FileModule &module, const Context *parent) if (!module.modulePath().empty()) this->document_path = module.modulePath(); } -Value FileContext::sub_evaluate_function(const std::string &name, const EvalContext *evalctx, - - FileModule *usedmod) const +ValuePtr FileContext::sub_evaluate_function(const std::string &name, + const EvalContext *evalctx, + FileModule *usedmod) const { FileContext ctx(*usedmod, this->parent); @@ -192,7 +193,8 @@ Value FileContext::sub_evaluate_function(const std::string &name, const EvalCont return usedmod->scope.functions[name]->evaluate(&ctx, evalctx); } -Value FileContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const +ValuePtr FileContext::evaluate_function(const std::string &name, + const EvalContext *evalctx) const { const AbstractFunction *foundf = findLocalFunction(name); if (foundf) return foundf->evaluate(this, evalctx); diff --git a/src/modcontext.h b/src/modcontext.h index 2e33c962..ce6a9d51 100644 --- a/src/modcontext.h +++ b/src/modcontext.h @@ -18,8 +18,8 @@ public: void initializeModule(const Module &m); void registerBuiltin(); - virtual Value evaluate_function(const std::string &name, - const EvalContext *evalctx) const; + virtual ValuePtr evaluate_function(const std::string &name, + const EvalContext *evalctx) const; virtual AbstractNode *instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const; @@ -45,7 +45,8 @@ class FileContext : public ModuleContext public: FileContext(const class FileModule &module, const Context *parent); virtual ~FileContext() {} - virtual Value evaluate_function(const std::string &name, const EvalContext *evalctx) const; + virtual ValuePtr evaluate_function(const std::string &name, + const EvalContext *evalctx) const; virtual AbstractNode *instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const; @@ -53,5 +54,7 @@ private: const FileModule::ModuleContainer &usedlibs; // This sub_* method is needed to minimize stack usage only. - Value sub_evaluate_function(const std::string &name, const EvalContext *evalctx, FileModule *usedmod) const; + ValuePtr sub_evaluate_function(const std::string &name, + const EvalContext *evalctx, + FileModule *usedmod) const; }; diff --git a/src/module.cc b/src/module.cc index 95224be8..82a16320 100644 --- a/src/module.cc +++ b/src/module.cc @@ -59,14 +59,14 @@ AbstractNode *AbstractModule::instantiate(const Context *ctx, const ModuleInstan double AbstractModule::lookup_double_variable_with_default(Context &c, std::string variable, double def) const { - const Value v = c.lookup_variable(variable, true); - return (v.type() == Value::NUMBER) ? v.toDouble() : def; + ValuePtr v = c.lookup_variable(variable, true); + return (v->type() == Value::NUMBER) ? v->toDouble() : def; } std::string AbstractModule::lookup_string_variable_with_default(Context &c, std::string variable, std::string def) const { - const Value v = c.lookup_variable(variable, true); - return (v.type() == Value::STRING) ? v.toString() : def; + ValuePtr v = c.lookup_variable(variable, true); + return (v->type() == Value::STRING) ? v->toString() : def; } std::string AbstractModule::dump(const std::string &indent, const std::string &name) const @@ -195,9 +195,9 @@ AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation ModuleContext c(ctx, evalctx); // set $children first since we might have variables depending on it - c.set_variable("$children", Value(double(inst->scope.children.size()))); + c.set_variable("$children", ValuePtr(double(inst->scope.children.size()))); module_stack.push_back(inst->name()); - c.set_variable("$parent_modules", Value(double(module_stack.size()))); + c.set_variable("$parent_modules", ValuePtr(double(module_stack.size()))); c.initializeModule(*this); // FIXME: Set document path to the path of the module #if 0 && DEBUG diff --git a/src/offset.cc b/src/offset.cc index 1b2c7160..a5803430 100644 --- a/src/offset.cc +++ b/src/offset.cc @@ -59,21 +59,21 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti Context c(ctx); c.setVariables(args, evalctx); - node->fn = c.lookup_variable("$fn").toDouble(); - node->fs = c.lookup_variable("$fs").toDouble(); - node->fa = c.lookup_variable("$fa").toDouble(); + node->fn = c.lookup_variable("$fn")->toDouble(); + node->fs = c.lookup_variable("$fs")->toDouble(); + node->fa = c.lookup_variable("$fa")->toDouble(); - Value delta = c.lookup_variable("delta"); + ValuePtr delta = c.lookup_variable("delta"); node->delta = 1; - delta.getDouble(node->delta); + delta->getDouble(node->delta); - Value miter_limit = c.lookup_variable("miter_limit", true); + ValuePtr miter_limit = c.lookup_variable("miter_limit", true); node->miter_limit = 2; - miter_limit.getDouble(node->miter_limit); + miter_limit->getDouble(node->miter_limit); - Value join_type = c.lookup_variable("join_type", true); - if (join_type.type() == Value::STRING) { - std::string jt = join_type.toString(); + ValuePtr join_type = c.lookup_variable("join_type", true); + if (join_type->type() == Value::STRING) { + std::string jt = join_type->toString(); if (std::string("bevel") == jt) { node->join_type = ClipperLib::jtSquare; } else if (std::string("round") == jt) { @@ -84,7 +84,7 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti PRINTB("WARNING: Unknown join_type for offset(): '%s'", jt); } - if ((node->join_type != ClipperLib::jtMiter) && !miter_limit.isUndefined()) { + if ((node->join_type != ClipperLib::jtMiter) && !miter_limit->isUndefined()) { PRINTB("WARNING: miter_limit is ignored in offset() for join_type: '%s'", jt); } } diff --git a/src/parser.y b/src/parser.y index 6c0d5379..79a42a68 100644 --- a/src/parser.y +++ b/src/parser.y @@ -308,15 +308,15 @@ single_module_instantiation: expr: TOK_TRUE { - $$ = new Expression(Value(true)); + $$ = new Expression(ValuePtr(true)); } | TOK_FALSE { - $$ = new Expression(Value(false)); + $$ = new Expression(ValuePtr(false)); } | TOK_UNDEF { - $$ = new Expression(Value::undefined); + $$ = new Expression(ValuePtr::undefined); } | TOK_ID { @@ -333,12 +333,12 @@ expr: } | TOK_STRING { - $$ = new Expression(Value(std::string($1))); + $$ = new Expression(ValuePtr(std::string($1))); free($1); } | TOK_NUMBER { - $$ = new Expression(Value($1)); + $$ = new Expression(ValuePtr($1)); } | TOK_LET '(' arguments_call ')' expr %prec LET { @@ -371,7 +371,7 @@ expr: } | '[' optional_commas ']' { - $$ = new Expression(Value(Value::VectorType())); + $$ = new Expression(ValuePtr(Value::VectorType())); } | '[' vector_expr optional_commas ']' { diff --git a/src/primitives.cc b/src/primitives.cc index 33e59109..ef816b28 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -108,7 +108,7 @@ public: double fn, fs, fa; primitive_type_e type; int convexity; - Value points, paths, faces; + ValuePtr points, paths, faces; virtual Geometry *createGeometry() const; }; @@ -125,19 +125,19 @@ public: */ Value PrimitiveModule::lookup_radius(const Context &ctx, const std::string &diameter_var, const std::string &radius_var) const { - const Value d = ctx.lookup_variable(diameter_var, true); - const Value r = ctx.lookup_variable(radius_var, true); - const bool r_defined = (r.type() == Value::NUMBER); + ValuePtr d = ctx.lookup_variable(diameter_var, true); + ValuePtr r = ctx.lookup_variable(radius_var, true); + const bool r_defined = (r->type() == Value::NUMBER); - if (d.type() == Value::NUMBER) { + if (d->type() == Value::NUMBER) { if (r_defined) { PRINTB("WARNING: Ignoring radius variable '%s' as diameter '%s' is defined too.", radius_var % diameter_var); } - return Value(d.toDouble() / 2.0); + return Value(d->toDouble() / 2.0); } else if (r_defined) { - return r; + return *r; } else { - return Value(); + return Value::undefined; } } @@ -179,9 +179,9 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta Context c(ctx); c.setVariables(args, evalctx); - node->fn = c.lookup_variable("$fn").toDouble(); - node->fs = c.lookup_variable("$fs").toDouble(); - node->fa = c.lookup_variable("$fa").toDouble(); + node->fn = c.lookup_variable("$fn")->toDouble(); + node->fs = c.lookup_variable("$fs")->toDouble(); + node->fa = c.lookup_variable("$fa")->toDouble(); if (node->fs < F_MINIMUM) { PRINTB("WARNING: $fs too small - clamping to %f", F_MINIMUM); @@ -194,14 +194,14 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta switch (this->type) { case CUBE: { - Value size = c.lookup_variable("size"); - Value center = c.lookup_variable("center"); - size.getDouble(node->x); - size.getDouble(node->y); - size.getDouble(node->z); - size.getVec3(node->x, node->y, node->z); - if (center.type() == Value::BOOL) { - node->center = center.toBool(); + ValuePtr size = c.lookup_variable("size"); + ValuePtr center = c.lookup_variable("center"); + size->getDouble(node->x); + size->getDouble(node->y); + size->getDouble(node->z); + size->getVec3(node->x, node->y, node->z); + if (center->type() == Value::BOOL) { + node->center = center->toBool(); } break; } @@ -213,9 +213,9 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta break; } case CYLINDER: { - const Value h = c.lookup_variable("h"); - if (h.type() == Value::NUMBER) { - node->h = h.toDouble(); + ValuePtr h = c.lookup_variable("h"); + if (h->type() == Value::NUMBER) { + node->h = h->toDouble(); } const Value r = lookup_radius(c, "d", "r"); @@ -232,32 +232,32 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta node->r2 = r2.toDouble(); } - const Value center = c.lookup_variable("center"); - if (center.type() == Value::BOOL) { - node->center = center.toBool(); + ValuePtr center = c.lookup_variable("center"); + if (center->type() == Value::BOOL) { + node->center = center->toBool(); } break; } case POLYHEDRON: { node->points = c.lookup_variable("points"); node->faces = c.lookup_variable("faces"); - if (node->faces.type() == Value::UNDEFINED) { + if (node->faces->type() == Value::UNDEFINED) { // backwards compatible node->faces = c.lookup_variable("triangles", true); - if (node->faces.type() != Value::UNDEFINED) { + if (node->faces->type() != Value::UNDEFINED) { printDeprecation("DEPRECATED: polyhedron(triangles=[]) will be removed in future releases. Use polyhedron(faces=[]) instead."); } } break; } case SQUARE: { - Value size = c.lookup_variable("size"); - Value center = c.lookup_variable("center"); - size.getDouble(node->x); - size.getDouble(node->y); - size.getVec2(node->x, node->y); - if (center.type() == Value::BOOL) { - node->center = center.toBool(); + ValuePtr size = c.lookup_variable("size"); + ValuePtr center = c.lookup_variable("center"); + size->getDouble(node->x); + size->getDouble(node->y); + size->getVec2(node->x, node->y); + if (center->type() == Value::BOOL) { + node->center = center->toBool(); } break; } @@ -275,7 +275,7 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta } } - node->convexity = c.lookup_variable("convexity", true).toDouble(); + node->convexity = c.lookup_variable("convexity", true)->toDouble(); if (node->convexity < 1) node->convexity = 1; @@ -505,15 +505,15 @@ Geometry *PrimitiveNode::createGeometry() const PolySet *p = new PolySet(3); g = p; p->setConvexity(this->convexity); - for (size_t i=0; ifaces.toVector().size(); i++) + for (size_t i=0; ifaces->toVector().size(); i++) { p->append_poly(); - const Value::VectorType &vec = this->faces.toVector()[i].toVector(); + const Value::VectorType &vec = this->faces->toVector()[i].toVector(); for (size_t j=0; jpoints.toVector().size()) { + if (pt < this->points->toVector().size()) { double px, py, pz; - if (!this->points.toVector()[pt].getVec3(px, py, pz) || + if (!this->points->toVector()[pt].getVec3(px, py, pz) || isinf(px) || isinf(py) || isinf(pz)) { PRINTB("ERROR: Unable to convert point at index %d to a vec3 of numbers", j); delete p; @@ -571,7 +571,7 @@ Geometry *PrimitiveNode::createGeometry() const Outline2d outline; double x,y; - const Value::VectorType &vec = this->points.toVector(); + const Value::VectorType &vec = this->points->toVector(); for (unsigned int i=0;ipaths.toVector().size() == 0 && outline.vertices.size() > 2) { + if (this->paths->toVector().size() == 0 && outline.vertices.size() > 2) { p->addOutline(outline); } else { - BOOST_FOREACH(const Value &polygon, this->paths.toVector()) { + BOOST_FOREACH(const Value &polygon, this->paths->toVector()) { Outline2d curroutline; BOOST_FOREACH(const Value &index, polygon.toVector()) { unsigned int idx = index.toDouble(); @@ -635,8 +635,8 @@ std::string PrimitiveNode::toString() const << ", r2 = " << this->r2 << ", center = " << (center ? "true" : "false") << ")"; break; case POLYHEDRON: - stream << "(points = " << this->points - << ", faces = " << this->faces + stream << "(points = " << *this->points + << ", faces = " << *this->faces << ", convexity = " << this->convexity << ")"; break; case SQUARE: @@ -648,7 +648,7 @@ std::string PrimitiveNode::toString() const << ", $fs = " << this->fs << ", r = " << this->r1 << ")"; break; case POLYGON: - stream << "(points = " << this->points << ", paths = " << this->paths << ", convexity = " << this->convexity << ")"; + stream << "(points = " << *this->points << ", paths = " << *this->paths << ", convexity = " << this->convexity << ")"; break; default: assert(false); diff --git a/src/projection.cc b/src/projection.cc index 7afd0e46..ef9de3df 100644 --- a/src/projection.cc +++ b/src/projection.cc @@ -54,13 +54,13 @@ AbstractNode *ProjectionModule::instantiate(const Context *ctx, const ModuleInst Context c(ctx); c.setVariables(args, evalctx); - Value convexity = c.lookup_variable("convexity", true); - Value cut = c.lookup_variable("cut", true); + ValuePtr convexity = c.lookup_variable("convexity", true); + ValuePtr cut = c.lookup_variable("cut", true); - node->convexity = (int)convexity.toDouble(); + node->convexity = (int)convexity->toDouble(); - if (cut.type() == Value::BOOL) - node->cut_mode = cut.toBool(); + if (cut->type() == Value::BOOL) + node->cut_mode = cut->toBool(); std::vector instantiatednodes = inst->instantiateChildren(evalctx); node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end()); diff --git a/src/render.cc b/src/render.cc index d29a3886..f2bbf22a 100644 --- a/src/render.cc +++ b/src/render.cc @@ -51,9 +51,9 @@ AbstractNode *RenderModule::instantiate(const Context *ctx, const ModuleInstanti Context c(ctx); c.setVariables(args, evalctx); - Value v = c.lookup_variable("convexity"); - if (v.type() == Value::NUMBER) - node->convexity = (int)v.toDouble(); + ValuePtr v = c.lookup_variable("convexity"); + if (v->type() == Value::NUMBER) + node->convexity = (int)v->toDouble(); std::vector instantiatednodes = inst->instantiateChildren(evalctx); node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end()); diff --git a/src/rotateextrude.cc b/src/rotateextrude.cc index ce52fd79..eac1d7b9 100644 --- a/src/rotateextrude.cc +++ b/src/rotateextrude.cc @@ -57,25 +57,25 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI Context c(ctx); c.setVariables(args, evalctx); - node->fn = c.lookup_variable("$fn").toDouble(); - node->fs = c.lookup_variable("$fs").toDouble(); - node->fa = c.lookup_variable("$fa").toDouble(); + node->fn = c.lookup_variable("$fn")->toDouble(); + node->fs = c.lookup_variable("$fs")->toDouble(); + node->fa = c.lookup_variable("$fa")->toDouble(); - Value file = c.lookup_variable("file"); - Value layer = c.lookup_variable("layer", true); - Value convexity = c.lookup_variable("convexity", true); - Value origin = c.lookup_variable("origin", true); - Value scale = c.lookup_variable("scale", true); + ValuePtr file = c.lookup_variable("file"); + ValuePtr layer = c.lookup_variable("layer", true); + ValuePtr convexity = c.lookup_variable("convexity", true); + ValuePtr origin = c.lookup_variable("origin", true); + ValuePtr scale = c.lookup_variable("scale", true); - if (!file.isUndefined()) { + if (!file->isUndefined()) { printDeprecation("DEPRECATED: Support for reading files in rotate_extrude will be removed in future releases. Use a child import() instead."); - node->filename = lookup_file(file.toString(), inst->path(), c.documentPath()); + node->filename = lookup_file(file->toString(), inst->path(), c.documentPath()); } - node->layername = layer.isUndefined() ? "" : layer.toString(); - node->convexity = (int)convexity.toDouble(); - origin.getVec2(node->origin_x, node->origin_y); - node->scale = scale.toDouble(); + node->layername = layer->isUndefined() ? "" : layer->toString(); + node->convexity = (int)convexity->toDouble(); + origin->getVec2(node->origin_x, node->origin_y); + node->scale = scale->toDouble(); if (node->convexity <= 0) node->convexity = 1; diff --git a/src/surface.cc b/src/surface.cc index e8a93355..dbfac901 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -93,22 +93,22 @@ AbstractNode *SurfaceModule::instantiate(const Context *ctx, const ModuleInstant Context c(ctx); c.setVariables(args, evalctx); - Value fileval = c.lookup_variable("file"); - node->filename = lookup_file(fileval.isUndefined() ? "" : fileval.toString(), inst->path(), c.documentPath()); + ValuePtr fileval = c.lookup_variable("file"); + node->filename = lookup_file(fileval->isUndefined() ? "" : fileval->toString(), inst->path(), c.documentPath()); - Value center = c.lookup_variable("center", true); - if (center.type() == Value::BOOL) { - node->center = center.toBool(); + ValuePtr center = c.lookup_variable("center", true); + if (center->type() == Value::BOOL) { + node->center = center->toBool(); } - Value convexity = c.lookup_variable("convexity", true); - if (convexity.type() == Value::NUMBER) { - node->convexity = (int)convexity.toDouble(); + ValuePtr convexity = c.lookup_variable("convexity", true); + if (convexity->type() == Value::NUMBER) { + node->convexity = (int)convexity->toDouble(); } - Value invert = c.lookup_variable("invert", true); - if (invert.type() == Value::BOOL) { - node->invert = invert.toBool(); + ValuePtr invert = c.lookup_variable("invert", true); + if (invert->type() == Value::BOOL) { + node->invert = invert->toBool(); } return node; diff --git a/src/text.cc b/src/text.cc index 64254b90..0cc12889 100644 --- a/src/text.cc +++ b/src/text.cc @@ -54,9 +54,9 @@ AbstractNode *TextModule::instantiate(const Context *ctx, const ModuleInstantiat Context c(ctx); c.setVariables(args, evalctx); - double fn = c.lookup_variable("$fn").toDouble(); - double fa = c.lookup_variable("$fa").toDouble(); - double fs = c.lookup_variable("$fs").toDouble(); + double fn = c.lookup_variable("$fn")->toDouble(); + double fa = c.lookup_variable("$fa")->toDouble(); + double fs = c.lookup_variable("$fs")->toDouble(); node->params.set_fn(fn); node->params.set_fa(fa); diff --git a/src/transform.cc b/src/transform.cc index 25723fec..74a7f7be 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -87,45 +87,45 @@ AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInsta if (this->type == SCALE) { Vector3d scalevec(1,1,1); - Value v = c.lookup_variable("v"); - if (!v.getVec3(scalevec[0], scalevec[1], scalevec[2], 1.0)) { + ValuePtr v = c.lookup_variable("v"); + if (!v->getVec3(scalevec[0], scalevec[1], scalevec[2], 1.0)) { double num; - if (v.getDouble(num)) scalevec.setConstant(num); + if (v->getDouble(num)) scalevec.setConstant(num); } node->matrix.scale(scalevec); } else if (this->type == ROTATE) { - Value val_a = c.lookup_variable("a"); - if (val_a.type() == Value::VECTOR) + ValuePtr val_a = c.lookup_variable("a"); + if (val_a->type() == Value::VECTOR) { Eigen::AngleAxisd rotx(0, Vector3d::UnitX()); Eigen::AngleAxisd roty(0, Vector3d::UnitY()); Eigen::AngleAxisd rotz(0, Vector3d::UnitZ()); double a; - if (val_a.toVector().size() > 0) { - val_a.toVector()[0].getDouble(a); + if (val_a->toVector().size() > 0) { + val_a->toVector()[0].getDouble(a); rotx = Eigen::AngleAxisd(a*M_PI/180, Vector3d::UnitX()); } - if (val_a.toVector().size() > 1) { - val_a.toVector()[1].getDouble(a); + if (val_a->toVector().size() > 1) { + val_a->toVector()[1].getDouble(a); roty = Eigen::AngleAxisd(a*M_PI/180, Vector3d::UnitY()); } - if (val_a.toVector().size() > 2) { - val_a.toVector()[2].getDouble(a); + if (val_a->toVector().size() > 2) { + val_a->toVector()[2].getDouble(a); rotz = Eigen::AngleAxisd(a*M_PI/180, Vector3d::UnitZ()); } node->matrix.rotate(rotz * roty * rotx); } else { - Value val_v = c.lookup_variable("v"); + ValuePtr val_v = c.lookup_variable("v"); double a = 0; - val_a.getDouble(a); + val_a->getDouble(a); Vector3d axis(0,0,1); - if (val_v.getVec3(axis[0], axis[1], axis[2])) { + if (val_v->getVec3(axis[0], axis[1], axis[2])) { if (axis.squaredNorm() > 0) axis.normalize(); } @@ -136,10 +136,10 @@ AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInsta } else if (this->type == MIRROR) { - Value val_v = c.lookup_variable("v"); + ValuePtr val_v = c.lookup_variable("v"); double x = 1, y = 0, z = 0; - if (val_v.getVec3(x, y, z)) { + if (val_v->getVec3(x, y, z)) { if (x != 0.0 || y != 0.0 || z != 0.0) { double sn = 1.0 / sqrt(x*x + y*y + z*z); x *= sn, y *= sn, z *= sn; @@ -158,19 +158,20 @@ AbstractNode *TransformModule::instantiate(const Context *ctx, const ModuleInsta } else if (this->type == TRANSLATE) { - Value v = c.lookup_variable("v"); + ValuePtr v = c.lookup_variable("v"); Vector3d translatevec(0,0,0); - v.getVec3(translatevec[0], translatevec[1], translatevec[2]); + v->getVec3(translatevec[0], translatevec[1], translatevec[2]); node->matrix.translate(translatevec); } else if (this->type == MULTMATRIX) { - Value v = c.lookup_variable("m"); - if (v.type() == Value::VECTOR) { + ValuePtr v = c.lookup_variable("m"); + if (v->type() == Value::VECTOR) { 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)); + 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)); } } } @@ -189,7 +190,7 @@ std::string TransformNode::toString() const for (int j=0;j<4;j++) { stream << "["; for (int i=0;i<4;i++) { - Value v( this->matrix(j, i) ); + Value v(this->matrix(j, i)); stream << v; if (i != 3) stream << ", "; } diff --git a/src/value.cc b/src/value.cc index 66391a95..3180f2b0 100644 --- a/src/value.cc +++ b/src/value.cc @@ -41,6 +41,9 @@ #include +Value Value::undefined; +ValuePtr ValuePtr::undefined; + std::ostream &operator<<(std::ostream &stream, const Filename &filename) { fs::path fnpath = fs::path( (std::string)filename ); @@ -77,8 +80,6 @@ std::ostream &operator<<(std::ostream &stream, const QuotedString &s) return stream; } -Value Value::undefined; - Value::Value() : value(boost::blank()) { // std::cout << "creating undef\n"; @@ -688,7 +689,7 @@ public: } }; -Value Value::operator[](const Value &v) +Value Value::operator[](const Value &v) const { return boost::apply_visitor(bracket_visitor(), this->value, v.value); } @@ -790,3 +791,119 @@ bool Value::RangeType::iterator::operator!=(const self_type &other) const { return !(*this == other); } + +ValuePtr::ValuePtr() +{ + this->reset(new Value()); +} + +ValuePtr::ValuePtr(const Value &v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(bool v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(int v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(double v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(const std::string &v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(const char *v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(const char v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(const Value::VectorType &v) +{ + this->reset(new Value(v)); +} + +ValuePtr::ValuePtr(const Value::RangeType &v) +{ + this->reset(new Value(v)); +} + +bool ValuePtr::operator==(const ValuePtr &v) const +{ + return ValuePtr(**this == *v); +} + +bool ValuePtr::operator!=(const ValuePtr &v) const +{ + return ValuePtr(**this != *v); +} + +bool ValuePtr::operator<(const ValuePtr &v) const +{ + return ValuePtr(**this < *v); +} + +bool ValuePtr::operator<=(const ValuePtr &v) const +{ + return ValuePtr(**this <= *v); +} + +bool ValuePtr::operator>=(const ValuePtr &v) const +{ + return ValuePtr(**this >= *v); +} + +bool ValuePtr::operator>(const ValuePtr &v) const +{ + return ValuePtr(**this > *v); +} + +ValuePtr ValuePtr::operator-() const +{ + return ValuePtr(-**this); +} + +ValuePtr ValuePtr::operator[](const ValuePtr &v) const +{ + return ValuePtr((**this)[*v]); +} + +ValuePtr ValuePtr::operator+(const ValuePtr &v) const +{ + return ValuePtr(**this + *v); +} + +ValuePtr ValuePtr::operator-(const ValuePtr &v) const +{ + return ValuePtr(**this - *v); +} + +ValuePtr ValuePtr::operator*(const ValuePtr &v) const +{ + return ValuePtr(**this * *v); +} + +ValuePtr ValuePtr::operator/(const ValuePtr &v) const +{ + return ValuePtr(**this / *v); +} + +ValuePtr ValuePtr::operator%(const ValuePtr &v) const +{ + return ValuePtr(**this % *v); +} + diff --git a/src/value.h b/src/value.h index 6c59ef2c..bfd08376 100644 --- a/src/value.h +++ b/src/value.h @@ -11,6 +11,7 @@ #include #endif #include +#include "memory.h" class QuotedString : public std::string { @@ -138,7 +139,7 @@ public: bool operator>=(const Value &v) const; bool operator>(const Value &v) const; Value operator-() const; - Value operator[](const Value &v); + Value operator[](const Value &v) const; Value operator+(const Value &v) const; Value operator-(const Value &v) const; Value operator*(const Value &v) const; @@ -160,3 +161,40 @@ private: Variant value; }; + +class ValuePtr : public shared_ptr +{ +public: + static ValuePtr undefined; + + ValuePtr(); + explicit ValuePtr(const Value &v); + ValuePtr(bool v); + ValuePtr(int v); + ValuePtr(double v); + ValuePtr(const std::string &v); + ValuePtr(const char *v); + ValuePtr(const char v); + ValuePtr(const Value::VectorType &v); + ValuePtr(const Value::RangeType &v); + + operator bool() const { return **this; } + + bool operator==(const ValuePtr &v) const; + bool operator!=(const ValuePtr &v) const; + bool operator<(const ValuePtr &v) const; + bool operator<=(const ValuePtr &v) const; + bool operator>=(const ValuePtr &v) const; + bool operator>(const ValuePtr &v) const; + ValuePtr operator-() const; + ValuePtr operator[](const ValuePtr &v) const; + ValuePtr operator+(const ValuePtr &v) const; + ValuePtr operator-(const ValuePtr &v) const; + ValuePtr operator*(const ValuePtr &v) const; + ValuePtr operator/(const ValuePtr &v) const; + ValuePtr operator%(const ValuePtr &v) const; + + const Value &operator*() const { return *this->get(); } + +private: +}; From 1f7380709739d3314d88faca5cf9647340c06aba Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 23 Nov 2014 20:29:33 +0100 Subject: [PATCH 035/263] Hack to track stack size in function evaluation. --- src/context.cc | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/context.h | 6 ++++++ src/expr.cc | 13 ++++++++----- src/func.cc | 11 ++++++++++- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/context.cc b/src/context.cc index fdbe9990..1b7995b8 100644 --- a/src/context.cc +++ b/src/context.cc @@ -49,7 +49,7 @@ static bool is_config_variable(const std::string &name) { created, and all children will share the root parent's stack. */ Context::Context(const Context *parent) - : parent(parent) + : parent(parent), stack_ptr(0), stack_max(0) { if (parent) { assert(parent->ctx_stack && "Parent context stack was null!"); @@ -70,6 +70,49 @@ Context::~Context() if (!parent) delete this->ctx_stack; } +unsigned long Context::stackUsage() const +{ + if (parent == NULL) { + unsigned long ret = std::abs((unsigned long)stack_ptr - (unsigned long)stack_max); + ((Context *)this)->stack_ptr = 0; + ((Context *)this)->stack_max = 0; + return ret; + } else { + return parent->stackUsage(); + } +} + +bool Context::setStack(const void* stack_cur) const +{ + if (parent == NULL) { + bool ret = this->stack_ptr == 0; + if (ret) { + ((Context *)this)->stack_ptr = stack_cur; + ((Context *)this)->stack_max = stack_cur; + } + return ret; + } else { + return parent->setStack(stack_cur); + } +} + +void Context::checkStack(const void *stack_cur) const +{ + if (parent == NULL) { + if (stack_cur < this->stack_ptr) { + if (stack_cur < this->stack_max) { + ((Context *)this)->stack_max = stack_cur; + } + } else { + if (stack_cur > this->stack_max) { + ((Context *)this)->stack_max = stack_cur; + } + } + } else { + parent->checkStack(stack_cur); + } +} + /*! Initialize context from a module argument list and a evaluation context which may pass variables which will be preferred over default values. diff --git a/src/context.h b/src/context.h index d80c0bef..9caae1d7 100644 --- a/src/context.h +++ b/src/context.h @@ -32,12 +32,18 @@ public: void setDocumentPath(const std::string &path) { this->document_path = path; } const std::string &documentPath() const { return this->document_path; } std::string getAbsolutePath(const std::string &filename) const; + + unsigned long stackUsage() const; + bool setStack(const void *stack_cur) const; + void checkStack(const void *stack_cur) const; public: protected: const Context *parent; Stack *ctx_stack; + const void *stack_ptr; + const void *stack_max; typedef boost::unordered_map ValueMap; ValueMap constants; diff --git a/src/expr.cc b/src/expr.cc index b2fa061d..22aeb1be 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -109,11 +109,11 @@ ValuePtr Expression::sub_evaluate_vector(const Context *context) const ValuePtr Expression::sub_evaluate_function(const Context *context) const { - if (this->recursioncount >= 1000) { - PRINTB("ERROR: Recursion detected calling function '%s'", this->call_funcname); - // TO DO: throw function_recursion_detected(); - return ValuePtr::undefined; - } +// if (this->recursioncount >= 1000) { +// PRINTB("ERROR: Recursion detected calling function '%s'", this->call_funcname); +// // TO DO: throw function_recursion_detected(); +// return Value(); +// } this->recursioncount += 1; EvalContext c(context, this->call_arguments); ValuePtr result = context->evaluate_function(this->call_funcname, &c); @@ -242,6 +242,9 @@ ValuePtr Expression::sub_evaluate_list_comprehension(const Context *context) con ValuePtr Expression::evaluate(const Context *context) const { + char _c; + context->checkStack(&_c); + switch (type2int(this->type.c_str())) { case '!': return ! this->children[0]->evaluate(context); diff --git a/src/func.cc b/src/func.cc index f1c9ada4..b781e48c 100644 --- a/src/func.cc +++ b/src/func.cc @@ -88,12 +88,21 @@ Function::~Function() delete expr; } +static const char *txt = "stack usage: "; ValuePtr Function::evaluate(const Context *ctx, const EvalContext *evalctx) const { + char _c; + bool set = ctx->setStack(&_c); + if (!expr) return ValuePtr::undefined; Context c(ctx); c.setVariables(definition_arguments, evalctx); - return expr->evaluate(&c); + ValuePtr result = expr->evaluate(&c); + + if (set) { + std::cout << txt << ctx->stackUsage() << std::endl; + } + return result; } std::string Function::dump(const std::string &indent, const std::string &name) const From 609f665406829f1d69a822e929b3611d1d4fd133 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 24 Nov 2014 00:50:15 +0100 Subject: [PATCH 036/263] Extract PRINTB() from recursion stack. --- src/context.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/context.cc b/src/context.cc index 1b7995b8..6e6f91eb 100644 --- a/src/context.cc +++ b/src/context.cc @@ -198,17 +198,22 @@ bool Context::has_local_variable(const std::string &name) const return variables.find(name) != variables.end(); } +static void print_ignore_warning(const char *what, const char *name) +{ + PRINTB("WARNING: Ignoring unknown %s '%s'.", what % name); +} + ValuePtr Context::evaluate_function(const std::string &name, const EvalContext *evalctx) const { if (this->parent) return this->parent->evaluate_function(name, evalctx); - PRINTB("WARNING: Ignoring unknown function '%s'.", name); + print_ignore_warning("function", name.c_str()); return ValuePtr::undefined; } AbstractNode *Context::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const { if (this->parent) return this->parent->instantiate_module(inst, evalctx); - PRINTB("WARNING: Ignoring unknown module '%s'.", inst.name()); + print_ignore_warning("module", inst.name().c_str()); return NULL; } From 69451af578b91bb69fad49fbcc0a0ccb3c4a727c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 24 Nov 2014 00:51:00 +0100 Subject: [PATCH 037/263] Use heap for Context object. --- src/func.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/func.cc b/src/func.cc index b781e48c..168499cf 100644 --- a/src/func.cc +++ b/src/func.cc @@ -95,10 +95,11 @@ ValuePtr Function::evaluate(const Context *ctx, const EvalContext *evalctx) cons bool set = ctx->setStack(&_c); if (!expr) return ValuePtr::undefined; - Context c(ctx); - c.setVariables(definition_arguments, evalctx); - ValuePtr result = expr->evaluate(&c); - + Context *c = new Context(ctx); + c->setVariables(definition_arguments, evalctx); + ValuePtr result = expr->evaluate(c); + delete c; + if (set) { std::cout << txt << ctx->stackUsage() << std::endl; } From 6ed14dafb0fe3865fb127822eb5f181dde27d86a Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 24 Nov 2014 00:52:46 +0100 Subject: [PATCH 038/263] Remove big switch statement from expression evaluation. The switch statement causes a huge stack overhead that is very bad for evaluating recursive functions. --- src/expr.cc | 595 ++++++++++++++++++++++++++++++----------------- src/expression.h | 84 +++++-- src/parser.y | 63 +++-- 3 files changed, 471 insertions(+), 271 deletions(-) diff --git a/src/expr.cc b/src/expr.cc index 22aeb1be..eb0c27d2 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -35,120 +35,21 @@ #include #include -Expression::Expression() : recursioncount(0) -{ -} +ExpressionEvaluator * Expression::evaluators[256]; -Expression::Expression(const std::string &type, Expression *left, Expression *right) - : type(type), recursioncount(0) -{ - this->children.push_back(left); - this->children.push_back(right); -} - -Expression::Expression(const std::string &type, Expression *expr) - : type(type), recursioncount(0) -{ - this->children.push_back(expr); -} - -Expression::Expression(const ValuePtr &val) : const_value(val), type("C"), recursioncount(0) -{ -} - -Expression::~Expression() -{ - std::for_each(this->children.begin(), this->children.end(), del_fun()); -} - -ValuePtr Expression::sub_evaluate_range(const Context *context) const -{ - ValuePtr v1 = this->children[0]->evaluate(context); - if (v1->type() == Value::NUMBER) { - ValuePtr v2 = this->children[1]->evaluate(context); - if (v2->type() == Value::NUMBER) { - if (this->children.size() == 2) { - Value::RangeType range(v1->toDouble(), v2->toDouble()); - return ValuePtr(range); - } else { - ValuePtr v3 = this->children[2]->evaluate(context); - if (v3->type() == Value::NUMBER) { - Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble()); - return ValuePtr(range); - } - } - } - } - return ValuePtr::undefined; -} - -ValuePtr Expression::sub_evaluate_member(const Context *context) const -{ - ValuePtr v = this->children[0]->evaluate(context); - - if (v->type() == Value::VECTOR) { - if (this->var_name == "x") return v[0]; - if (this->var_name == "y") return v[1]; - if (this->var_name == "z") return v[2]; - } else if (v->type() == Value::RANGE) { - if (this->var_name == "begin") return v[0]; - if (this->var_name == "step") return v[1]; - if (this->var_name == "end") return v[2]; - } - return ValuePtr::undefined; -} - -ValuePtr Expression::sub_evaluate_vector(const Context *context) const -{ - Value::VectorType vec; - BOOST_FOREACH(const Expression *e, this->children) { - vec.push_back(*(e->evaluate(context))); - } - return ValuePtr(vec); -} - -ValuePtr Expression::sub_evaluate_function(const Context *context) const -{ -// if (this->recursioncount >= 1000) { -// PRINTB("ERROR: Recursion detected calling function '%s'", this->call_funcname); -// // TO DO: throw function_recursion_detected(); -// return Value(); -// } - this->recursioncount += 1; - EvalContext c(context, this->call_arguments); - ValuePtr result = context->evaluate_function(this->call_funcname, &c); - this->recursioncount -= 1; - return result; -} - -#define TYPE2INT(c,c1) ((int)(c) | ((int)(c1)<<8)) - -static inline int type2int(register const char *typestr) -{ - // the following asserts basic ASCII only so sign extension does not matter - // utilize the fact that type strings must have one or two non-null characters -#if 0 // defined(DEBUG) // may need this code as template for future development - register int c1, result = *typestr; - if (result && 0 != (c1 = typestr[1])) { - // take the third character for error checking only - result |= (c1 << 8) | ((int)typestr[2] << 16); - } - return result; -#else - return TYPE2INT(typestr[0], typestr[1]); -#endif -} +// static initializer for the expression evaluator lookup table +ExpressionEvaluatorInit Expression::evaluatorInit; // unnamed namespace namespace { Value::VectorType flatten(Value::VectorType const& vec) { int n = 0; - for (int i = 0; i < vec.size(); i++) { + for (unsigned int i = 0; i < vec.size(); i++) { assert(vec[i].type() == Value::VECTOR); n += vec[i].toVector().size(); } Value::VectorType ret; ret.reserve(n); - for (int i = 0; i < vec.size(); i++) { + for (unsigned int i = 0; i < vec.size(); i++) { std::copy(vec[i].toVector().begin(),vec[i].toVector().end(),std::back_inserter(ret)); } return ret; @@ -159,7 +60,7 @@ namespace { const bool allow_reassignment = false; - for (int i = 0; i < let_context.numArgs(); i++) { + for (unsigned int i = 0; i < let_context.numArgs(); i++) { if (!allow_reassignment && context->has_local_variable(let_context.getArgName(i))) { PRINTB("WARNING: Ignoring duplicate variable assignment %s = %s", let_context.getArgName(i) % let_context.getArgValue(i, context)->toString()); } else { @@ -170,29 +71,253 @@ namespace { } } -ValuePtr Expression::sub_evaluate_let_expression(const Context *context) const +class ExpressionEvaluatorAbort : public ExpressionEvaluator { - Context c(context); - evaluate_sequential_assignment(this->call_arguments, &c); + ValuePtr evaluate(const class Expression *, const class Context *) const { + abort(); + } +}; - return this->children[0]->evaluate(&c); +class ExpressionEvaluatorNot : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return ! expr->children[0]->evaluate(context); + } +}; + +class ExpressionEvaluatorLogicalAnd : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) && expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorLogicalOr : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) || expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorMultiply : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) * expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorDivision : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) / expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorModulo : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) % expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorPlus : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) + expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorMinus : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) - expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorLess : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) < expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorLessOrEqual : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) <= expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorEqual : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) == expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorNotEqual : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children.at(0)->evaluate(context) != expr->children.at(1)->evaluate(context); + } +}; + +class ExpressionEvaluatorGreaterOrEqual : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) >= expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorGreater : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context) > expr->children[1]->evaluate(context); + } +}; + +class ExpressionEvaluatorTernary : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[expr->children[0]->evaluate(context) ? 1 : 2]->evaluate(context); + } +}; + +class ExpressionEvaluatorArray : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context)[expr->children[1]->evaluate(context)]; + } +}; + +class ExpressionEvaluatorInvert : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return -expr->children[0]->evaluate(context); + } +}; + +class ExpressionEvaluatorConst : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *) const { + return ValuePtr(expr->const_value); + } +}; + +class ExpressionEvaluatorRange : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + ValuePtr v1 = expr->children[0]->evaluate(context); + if (v1->type() == Value::NUMBER) { + ValuePtr v2 = expr->children[1]->evaluate(context); + if (v2->type() == Value::NUMBER) { + if (expr->children.size() == 2) { + Value::RangeType range(v1->toDouble(), v2->toDouble()); + return ValuePtr(range); + } else { + ValuePtr v3 = expr->children[2]->evaluate(context); + if (v3->type() == Value::NUMBER) { + Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble()); + return ValuePtr(range); + } + } + } + } + return ValuePtr::undefined; + } +}; + +class ExpressionEvaluatorVector : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + Value::VectorType vec; + BOOST_FOREACH(const Expression *e, expr->children) { + vec.push_back(*(e->evaluate(context))); + } + return ValuePtr(vec); + } +}; + +class ExpressionEvaluatorLookup : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return context->lookup_variable(expr->var_name); + } +}; + +class ExpressionEvaluatorMember : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + ValuePtr v = expr->children[0]->evaluate(context); + + if (v->type() == Value::VECTOR) { + if (expr->var_name == "x") return v[0]; + if (expr->var_name == "y") return v[1]; + if (expr->var_name == "z") return v[2]; + } else if (v->type() == Value::RANGE) { + if (expr->var_name == "begin") return v[0]; + if (expr->var_name == "step") return v[1]; + if (expr->var_name == "end") return v[2]; + } + return ValuePtr::undefined; + } +}; + +static void function_recursion_detected(const char *func) +{ + PRINTB("ERROR: Recursion detected calling function '%s'", func); } -ValuePtr Expression::sub_evaluate_list_comprehension(const Context *context) const +class ExpressionEvaluatorFunction : public ExpressionEvaluator { + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + if (expr->recursioncount >= 1000) { + function_recursion_detected(expr->call_funcname.c_str()); + // TO DO: throw function_recursion_detected(); + return ValuePtr::undefined; + } + expr->recursioncount += 1; + EvalContext *c = new EvalContext(context, expr->call_arguments); + ValuePtr result = context->evaluate_function(expr->call_funcname, c); + delete c; + expr->recursioncount -= 1; + return result; + } +}; + +class ExpressionEvaluatorLet : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + Context c(context); + evaluate_sequential_assignment(expr->call_arguments, &c); + + return expr->children[0]->evaluate(&c); + } +}; + +class ExpressionEvaluatorLcExpression : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + return expr->children[0]->evaluate(context); + } +}; + +class ExpressionEvaluatorLc : public ExpressionEvaluator +{ + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { Value::VectorType vec; - if (this->call_funcname == "if") { - if (this->children[0]->evaluate(context)) { - if (this->children[1]->type == "c") { - return this->children[1]->evaluate(context); + if (expr->call_funcname == "if") { + if (expr->children[0]->evaluate(context)) { + if (expr->children[1]->type == EXPRESSION_TYPE_LC) { + return expr->children[1]->evaluate(context); } else { - vec.push_back((*this->children[1]->evaluate(context))); + vec.push_back((*expr->children[1]->evaluate(context))); } } return ValuePtr(vec); - } else if (this->call_funcname == "for") { - EvalContext for_context(context, this->call_arguments); + } else if (expr->call_funcname == "for") { + EvalContext for_context(context, expr->call_arguments); Context assign_context(context); @@ -210,96 +335,113 @@ ValuePtr Expression::sub_evaluate_list_comprehension(const Context *context) con } else { for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { c.set_variable(it_name, ValuePtr(*it)); - vec.push_back((*this->children[0]->evaluate(&c))); + vec.push_back((*expr->children[0]->evaluate(&c))); } } } else if (it_values->type() == Value::VECTOR) { for (size_t i = 0; i < it_values->toVector().size(); i++) { c.set_variable(it_name, it_values->toVector()[i]); - vec.push_back((*this->children[0]->evaluate(&c))); + vec.push_back((*expr->children[0]->evaluate(&c))); } } else if (it_values->type() != Value::UNDEFINED) { c.set_variable(it_name, it_values); - vec.push_back((*this->children[0]->evaluate(&c))); + vec.push_back((*expr->children[0]->evaluate(&c))); } - if (this->children[0]->type == "c") { + if (expr->children[0]->type == EXPRESSION_TYPE_LC) { return ValuePtr(flatten(vec)); } else { return ValuePtr(vec); } - } else if (this->call_funcname == "let") { + } else if (expr->call_funcname == "let") { Context c(context); - evaluate_sequential_assignment(this->call_arguments, &c); + evaluate_sequential_assignment(expr->call_arguments, &c); - return this->children[0]->evaluate(&c); + return expr->children[0]->evaluate(&c); } else { abort(); } + } +}; + +ExpressionEvaluatorInit::ExpressionEvaluatorInit() +{ + ExpressionEvaluator *abort = new ExpressionEvaluatorAbort(); + for (int a = 0;a < 256;a++) { + Expression::evaluators[a] = abort; + } + + Expression::evaluators[EXPRESSION_TYPE_NOT] = new ExpressionEvaluatorNot(); + Expression::evaluators[EXPRESSION_TYPE_LOGICAL_AND] = new ExpressionEvaluatorLogicalAnd(); + Expression::evaluators[EXPRESSION_TYPE_LOGICAL_OR] = new ExpressionEvaluatorLogicalOr(); + Expression::evaluators[EXPRESSION_TYPE_MULTIPLY] = new ExpressionEvaluatorMultiply(); + Expression::evaluators[EXPRESSION_TYPE_DIVISION] = new ExpressionEvaluatorDivision(); + Expression::evaluators[EXPRESSION_TYPE_MODULO] = new ExpressionEvaluatorModulo(); + Expression::evaluators[EXPRESSION_TYPE_PLUS] = new ExpressionEvaluatorPlus(); + Expression::evaluators[EXPRESSION_TYPE_MINUS] = new ExpressionEvaluatorMinus(); + Expression::evaluators[EXPRESSION_TYPE_LESS] = new ExpressionEvaluatorLess(); + Expression::evaluators[EXPRESSION_TYPE_LESS_OR_EQUAL] = new ExpressionEvaluatorLessOrEqual(); + Expression::evaluators[EXPRESSION_TYPE_EQUAL] = new ExpressionEvaluatorEqual(); + Expression::evaluators[EXPRESSION_TYPE_NOT_EQUAL] = new ExpressionEvaluatorNotEqual(); + Expression::evaluators[EXPRESSION_TYPE_GREATER_OR_EQUAL] = new ExpressionEvaluatorGreaterOrEqual(); + Expression::evaluators[EXPRESSION_TYPE_GREATER] = new ExpressionEvaluatorGreater(); + Expression::evaluators[EXPRESSION_TYPE_TERNARY] = new ExpressionEvaluatorTernary(); + Expression::evaluators[EXPRESSION_TYPE_ARRAY_ACCESS] = new ExpressionEvaluatorArray(); + Expression::evaluators[EXPRESSION_TYPE_INVERT] = new ExpressionEvaluatorInvert(); + Expression::evaluators[EXPRESSION_TYPE_CONST] = new ExpressionEvaluatorConst(); + Expression::evaluators[EXPRESSION_TYPE_RANGE] = new ExpressionEvaluatorRange(); + Expression::evaluators[EXPRESSION_TYPE_VECTOR] = new ExpressionEvaluatorVector(); + Expression::evaluators[EXPRESSION_TYPE_LOOKUP] = new ExpressionEvaluatorLookup(); + Expression::evaluators[EXPRESSION_TYPE_MEMBER] = new ExpressionEvaluatorMember(); + Expression::evaluators[EXPRESSION_TYPE_FUNCTION] = new ExpressionEvaluatorFunction(); + Expression::evaluators[EXPRESSION_TYPE_LET] = new ExpressionEvaluatorLet(); + Expression::evaluators[EXPRESSION_TYPE_LC_EXPRESSION] = new ExpressionEvaluatorLcExpression(); + Expression::evaluators[EXPRESSION_TYPE_LC] = new ExpressionEvaluatorLc(); } +Expression::Expression(const unsigned char type) : recursioncount(0) +{ + setType(type); +} + +Expression::Expression(const unsigned char type, Expression *left, Expression *right) + : recursioncount(0) +{ + setType(type); + this->children.push_back(left); + this->children.push_back(right); +} + +Expression::Expression(const unsigned char type, Expression *expr) + : recursioncount(0) +{ + setType(type); + this->children.push_back(expr); +} + +Expression::Expression(const ValuePtr &val) : const_value(val), recursioncount(0) +{ + setType(EXPRESSION_TYPE_CONST); +} + +Expression::~Expression() +{ + std::for_each(this->children.begin(), this->children.end(), del_fun()); +} + +void Expression::setType(const unsigned char type) +{ + this->type = type; + this->evaluator = evaluators[type]; +} ValuePtr Expression::evaluate(const Context *context) const { char _c; context->checkStack(&_c); - - switch (type2int(this->type.c_str())) { - case '!': - return ! this->children[0]->evaluate(context); - case TYPE2INT('&','&'): - return this->children[0]->evaluate(context) && this->children[1]->evaluate(context); - case TYPE2INT('|','|'): - return this->children[0]->evaluate(context) || this->children[1]->evaluate(context); - case '*': - return this->children[0]->evaluate(context) * this->children[1]->evaluate(context); - case '/': - return this->children[0]->evaluate(context) / this->children[1]->evaluate(context); - case '%': - return this->children[0]->evaluate(context) % this->children[1]->evaluate(context); - case '+': - return this->children[0]->evaluate(context) + this->children[1]->evaluate(context); - case '-': - return this->children[0]->evaluate(context) - this->children[1]->evaluate(context); - case '<': - return this->children[0]->evaluate(context) < this->children[1]->evaluate(context); - case TYPE2INT('<','='): - return this->children[0]->evaluate(context) <= this->children[1]->evaluate(context); - case TYPE2INT('=','='): - return this->children[0]->evaluate(context) == this->children[1]->evaluate(context); - case TYPE2INT('!','='): - return this->children[0]->evaluate(context) != this->children[1]->evaluate(context); - case TYPE2INT('>','='): - return this->children[0]->evaluate(context) >= this->children[1]->evaluate(context); - case '>': - return this->children[0]->evaluate(context) > this->children[1]->evaluate(context); - case TYPE2INT('?',':'): - return this->children[this->children[0]->evaluate(context) ? 1 : 2]->evaluate(context); - case TYPE2INT('[',']'): - return this->children[0]->evaluate(context)[this->children[1]->evaluate(context)]; - case 'I': - return -this->children[0]->evaluate(context); - case 'C': - return this->const_value; - case 'R': - return sub_evaluate_range(context); - case 'V': - return sub_evaluate_vector(context); - case 'L': - return context->lookup_variable(this->var_name); - case 'N': - return sub_evaluate_member(context); - case 'F': - return sub_evaluate_function(context); - case 'l': - return sub_evaluate_let_expression(context); - case 'i': // list comprehension expression - return this->children[0]->evaluate(context); - case 'c': - return sub_evaluate_list_comprehension(context); - } - abort(); + + return evaluator->evaluate(this, context); } namespace /* anonymous*/ { @@ -320,55 +462,79 @@ std::string Expression::toString() const { std::stringstream stream; - if (this->type == "*" || this->type == "/" || this->type == "%" || this->type == "+" || - this->type == "-" || this->type == "<" || this->type == "<=" || this->type == "==" || - this->type == "!=" || this->type == ">=" || this->type == ">" || - this->type == "&&" || this->type == "||") { + switch (this->type) { + case EXPRESSION_TYPE_MULTIPLY: + case EXPRESSION_TYPE_DIVISION: + case EXPRESSION_TYPE_MODULO: + case EXPRESSION_TYPE_PLUS: + case EXPRESSION_TYPE_MINUS: + case EXPRESSION_TYPE_LESS: + case EXPRESSION_TYPE_GREATER: stream << "(" << *this->children[0] << " " << this->type << " " << *this->children[1] << ")"; - } - else if (this->type == "?:") { - stream << "(" << *this->children[0] << " ? " << *this->children[1] << " : " << *this->children[2] << ")"; - } - else if (this->type == "[]") { - stream << *this->children[0] << "[" << *this->children[1] << "]"; - } - else if (this->type == "I") { - stream << "-" << *this->children[0]; - } - else if (this->type == "!") { + break; + case EXPRESSION_TYPE_NOT: stream << "!" << *this->children[0]; - } - else if (this->type == "C") { + break; + case EXPRESSION_TYPE_LOGICAL_AND: + stream << "(" << *this->children[0] << " && " << *this->children[1] << ")"; + break; + case EXPRESSION_TYPE_LOGICAL_OR: + stream << "(" << *this->children[0] << " || " << *this->children[1] << ")"; + break; + case EXPRESSION_TYPE_LESS_OR_EQUAL: + stream << "(" << *this->children[0] << " <= " << *this->children[1] << ")"; + break; + case EXPRESSION_TYPE_EQUAL: + stream << "(" << *this->children[0] << " == " << *this->children[1] << ")"; + break; + case EXPRESSION_TYPE_NOT_EQUAL: + stream << "(" << *this->children[0] << " != " << *this->children[1] << ")"; + break; + case EXPRESSION_TYPE_GREATER_OR_EQUAL: + stream << "(" << *this->children[0] << " >= " << *this->children[1] << ")"; + break; + case EXPRESSION_TYPE_TERNARY: + stream << "(" << *this->children[0] << " ? " << *this->children[1] << " : " << *this->children[2] << ")"; + break; + case EXPRESSION_TYPE_ARRAY_ACCESS: + stream << *this->children[0] << "[" << *this->children[1] << "]"; + break; + case EXPRESSION_TYPE_INVERT: + stream << "-" << *this->children[0]; + break; + case EXPRESSION_TYPE_CONST: stream << *this->const_value; - } - else if (this->type == "R") { + break; + case EXPRESSION_TYPE_RANGE: stream << "[" << *this->children[0] << " : " << *this->children[1]; if (this->children.size() > 2) { stream << " : " << *this->children[2]; } stream << "]"; - } - else if (this->type == "V") { + break; + case EXPRESSION_TYPE_VECTOR: stream << "["; for (size_t i=0; i < this->children.size(); i++) { if (i > 0) stream << ", "; stream << *this->children[i]; } stream << "]"; - } - else if (this->type == "L") { + break; + case EXPRESSION_TYPE_LOOKUP: stream << this->var_name; - } - else if (this->type == "N") { + break; + case EXPRESSION_TYPE_MEMBER: stream << *this->children[0] << "." << this->var_name; - } - else if (this->type == "F") { + break; + case EXPRESSION_TYPE_FUNCTION: stream << this->call_funcname << "(" << this->call_arguments << ")"; - } - else if (this->type == "l") { + break; + case EXPRESSION_TYPE_LET: stream << "let(" << this->call_arguments << ") " << *this->children[0]; - } - else if (this->type == "i") { // list comprehension expression + break; + case EXPRESSION_TYPE_LC_EXPRESSION: // list comprehension expression + //case EXPRESSION_TYPE_LC: + { Expression const* c = this->children[0]; stream << "["; @@ -386,14 +552,15 @@ std::string Expression::toString() const } else { assert(false && "Illegal list comprehension element"); } - } while (c->type == "c"); + } while (c->type == EXPRESSION_TYPE_LC); stream << *c << "]"; + break; } - else { + default: assert(false && "Illegal expression type"); + break; } - return stream.str(); } diff --git a/src/expression.h b/src/expression.h index 07237ab7..a83a75ef 100644 --- a/src/expression.h +++ b/src/expression.h @@ -5,6 +5,45 @@ #include "value.h" #include "typedefs.h" +#define EXPRESSION_TYPE_NOT ('!') +#define EXPRESSION_TYPE_LOGICAL_AND ('&') +#define EXPRESSION_TYPE_LOGICAL_OR ('|') +#define EXPRESSION_TYPE_MULTIPLY ('*') +#define EXPRESSION_TYPE_DIVISION ('/') +#define EXPRESSION_TYPE_MODULO ('%') +#define EXPRESSION_TYPE_PLUS ('+') +#define EXPRESSION_TYPE_MINUS ('-') +#define EXPRESSION_TYPE_LESS ('<') +#define EXPRESSION_TYPE_LESS_OR_EQUAL ('0') +#define EXPRESSION_TYPE_EQUAL ('=') +#define EXPRESSION_TYPE_NOT_EQUAL ('1') +#define EXPRESSION_TYPE_GREATER_OR_EQUAL ('2') +#define EXPRESSION_TYPE_GREATER ('>') +#define EXPRESSION_TYPE_TERNARY ('?') +#define EXPRESSION_TYPE_ARRAY_ACCESS ('[') +#define EXPRESSION_TYPE_INVERT ('I') +#define EXPRESSION_TYPE_CONST ('C') +#define EXPRESSION_TYPE_RANGE ('R') +#define EXPRESSION_TYPE_VECTOR ('V') +#define EXPRESSION_TYPE_LOOKUP ('L') +#define EXPRESSION_TYPE_MEMBER ('N') +#define EXPRESSION_TYPE_FUNCTION ('F') +#define EXPRESSION_TYPE_LET ('l') +#define EXPRESSION_TYPE_LC_EXPRESSION ('i') +#define EXPRESSION_TYPE_LC ('c') + +class ExpressionEvaluator +{ +public: + virtual ValuePtr evaluate(const class Expression *expr, const class Context *context) const = 0; +}; + +class ExpressionEvaluatorInit +{ +public: + ExpressionEvaluatorInit(); +}; + class Expression { public: @@ -16,6 +55,18 @@ public: std::string call_funcname; AssignmentList call_arguments; + Expression(const ValuePtr &val); + Expression(const unsigned char type); + Expression(const unsigned char type, Expression *left, Expression *right); + Expression(const unsigned char type, Expression *expr); + ~Expression(); + + void setType(const unsigned char type); + ValuePtr evaluate(const class Context *context) const; + + std::string toString() const; + +private: // Boolean: ! && || // Operators: * / % + - // Relations: < <= == != >= > @@ -30,30 +81,19 @@ public: // Lookup member per name: N // Function call: F // Let expression: l - // List comprehension expression: i - // List comprehension: c - std::string type; + // List comprehension expression: i + // List comprehension: c + unsigned char type; + ExpressionEvaluator *evaluator; - Expression(); - Expression(const ValuePtr &val); - Expression(const std::string &type, Expression *left, Expression *right); - Expression(const std::string &type, Expression *expr); - ~Expression(); - - ValuePtr evaluate(const class Context *context) const; - - std::string toString() const; - -private: mutable int recursioncount; - - // The following sub_* methods are needed to minimize stack usage only. - ValuePtr sub_evaluate_function(const class Context *context) const; - ValuePtr sub_evaluate_member(const class Context *context) const; - ValuePtr sub_evaluate_range(const class Context *context) const; - ValuePtr sub_evaluate_vector(const class Context *context) const; - ValuePtr sub_evaluate_let_expression(const class Context *context) const; - ValuePtr sub_evaluate_list_comprehension(const class Context *context) const; + + static ExpressionEvaluator *evaluators[256]; + static ExpressionEvaluatorInit evaluatorInit; + + friend class ExpressionEvaluatorInit; + friend class ExpressionEvaluatorLc; // for type + friend class ExpressionEvaluatorFunction; // for recursioncount }; std::ostream &operator<<(std::ostream &stream, const Expression &expr); diff --git a/src/parser.y b/src/parser.y index 79a42a68..9456f662 100644 --- a/src/parser.y +++ b/src/parser.y @@ -320,14 +320,13 @@ expr: } | TOK_ID { - $$ = new Expression(); - $$->type = "L"; + $$ = new Expression(EXPRESSION_TYPE_LOOKUP); $$->var_name = $1; free($1); } | expr '.' TOK_ID { - $$ = new Expression("N", $1); + $$ = new Expression(EXPRESSION_TYPE_MEMBER, $1); $$->var_name = $3; free($3); } @@ -342,31 +341,27 @@ expr: } | TOK_LET '(' arguments_call ')' expr %prec LET { - $$ = new Expression(); - $$->type = "l"; + $$ = new Expression(EXPRESSION_TYPE_LET); $$->call_arguments = *$3; delete $3; $$->children.push_back($5); } | '[' expr ':' expr ']' { - $$ = new Expression(); - $$->type = "R"; + $$ = new Expression(EXPRESSION_TYPE_RANGE); $$->children.push_back($2); $$->children.push_back($4); } | '[' expr ':' expr ':' expr ']' { - $$ = new Expression(); - $$->type = "R"; + $$ = new Expression(EXPRESSION_TYPE_RANGE); $$->children.push_back($2); $$->children.push_back($4); $$->children.push_back($6); } | '[' list_comprehension_elements ']' { - $$ = new Expression(); - $$->type = "i"; + $$ = new Expression(EXPRESSION_TYPE_LC_EXPRESSION); $$->children.push_back($2); } | '[' optional_commas ']' @@ -379,55 +374,55 @@ expr: } | expr '*' expr { - $$ = new Expression("*", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_MULTIPLY, $1, $3); } | expr '/' expr { - $$ = new Expression("/", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_DIVISION, $1, $3); } | expr '%' expr { - $$ = new Expression("%", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_MODULO, $1, $3); } | expr '+' expr { - $$ = new Expression("+", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_PLUS, $1, $3); } | expr '-' expr { - $$ = new Expression("-", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_MINUS, $1, $3); } | expr '<' expr { - $$ = new Expression("<", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_LESS, $1, $3); } | expr LE expr { - $$ = new Expression("<=", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_LESS_OR_EQUAL, $1, $3); } | expr EQ expr { - $$ = new Expression("==", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_EQUAL, $1, $3); } | expr NE expr { - $$ = new Expression("!=", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_NOT_EQUAL, $1, $3); } | expr GE expr { - $$ = new Expression(">=", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_GREATER_OR_EQUAL, $1, $3); } | expr '>' expr { - $$ = new Expression(">", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_GREATER, $1, $3); } | expr AND expr { - $$ = new Expression("&&", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_LOGICAL_AND, $1, $3); } | expr OR expr { - $$ = new Expression("||", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_LOGICAL_OR, $1, $3); } | '+' expr { @@ -435,11 +430,11 @@ expr: } | '-' expr { - $$ = new Expression("I", $2); + $$ = new Expression(EXPRESSION_TYPE_INVERT, $2); } | '!' expr { - $$ = new Expression("!", $2); + $$ = new Expression(EXPRESSION_TYPE_NOT, $2); } | '(' expr ')' { @@ -447,20 +442,18 @@ expr: } | expr '?' expr ':' expr { - $$ = new Expression(); - $$->type = "?:"; + $$ = new Expression(EXPRESSION_TYPE_TERNARY); $$->children.push_back($1); $$->children.push_back($3); $$->children.push_back($5); } | expr '[' expr ']' { - $$ = new Expression("[]", $1, $3); + $$ = new Expression(EXPRESSION_TYPE_ARRAY_ACCESS, $1, $3); } | TOK_ID '(' arguments_call ')' { - $$ = new Expression(); - $$->type = "F"; + $$ = new Expression(EXPRESSION_TYPE_FUNCTION); $$->call_funcname = $1; $$->call_arguments = *$3; free($1); @@ -473,7 +466,7 @@ list_comprehension_elements: be parsed as an expression) */ TOK_LET '(' arguments_call ')' list_comprehension_elements { - $$ = new Expression("c", $5); + $$ = new Expression(EXPRESSION_TYPE_LC, $5); $$->call_funcname = "let"; $$->call_arguments = *$3; delete $3; @@ -484,7 +477,7 @@ list_comprehension_elements: /* transform for(i=...,j=...) -> for(i=...) for(j=...) */ for (int i = $3->size()-1; i >= 0; i--) { - Expression *e = new Expression("c", $$); + Expression *e = new Expression(EXPRESSION_TYPE_LC, $$); e->call_funcname = "for"; e->call_arguments.push_back((*$3)[i]); $$ = e; @@ -493,7 +486,7 @@ list_comprehension_elements: } | TOK_IF '(' expr ')' list_comprehension_elements_or_expr { - $$ = new Expression("c", $3, $5); + $$ = new Expression(EXPRESSION_TYPE_LC, $3, $5); $$->call_funcname = "if"; } ; @@ -511,7 +504,7 @@ optional_commas: vector_expr: expr { - $$ = new Expression("V", $1); + $$ = new Expression(EXPRESSION_TYPE_VECTOR, $1); } | vector_expr ',' optional_commas expr { From 54a111472f21c8e9604612d29371ea9ea5b4cc2d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 12:54:14 -0500 Subject: [PATCH 039/263] Initial experiment with using exceptions to handle stack overflows --- src/context.cc | 2 +- src/evalcontext.cc | 11 ++++++++++- src/expr.cc | 33 ++++++++++++++++----------------- src/function.h | 13 +++++++++++++ 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/context.cc b/src/context.cc index 6e6f91eb..7d324168 100644 --- a/src/context.cc +++ b/src/context.cc @@ -73,7 +73,7 @@ Context::~Context() unsigned long Context::stackUsage() const { if (parent == NULL) { - unsigned long ret = std::abs((unsigned long)stack_ptr - (unsigned long)stack_max); + unsigned long ret = std::labs((unsigned long)stack_ptr - (unsigned long)stack_max); ((Context *)this)->stack_ptr = 0; ((Context *)this)->stack_max = 0; return ret; diff --git a/src/evalcontext.cc b/src/evalcontext.cc index 085a5f8f..d8adb154 100644 --- a/src/evalcontext.cc +++ b/src/evalcontext.cc @@ -18,7 +18,16 @@ ValuePtr EvalContext::getArgValue(size_t i, const Context *ctx) const { assert(i < this->eval_arguments.size()); const Assignment &arg = this->eval_arguments[i]; - return arg.second ? arg.second->evaluate(ctx ? ctx : this) : ValuePtr::undefined; + ValuePtr v; + if (arg.second) { + try { + v = arg.second->evaluate(ctx ? ctx : this); + } + catch (FunctionRecursionException &e) { + PRINT(e.what()); + } + } + return v; } size_t EvalContext::numChildren() const diff --git a/src/expr.cc b/src/expr.cc index eb0c27d2..348187dc 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -32,6 +32,7 @@ #include #include "stl-utils.h" #include "printutils.h" +#include "function.h" #include #include @@ -263,26 +264,24 @@ class ExpressionEvaluatorMember : public ExpressionEvaluator } }; -static void function_recursion_detected(const char *func) -{ - PRINTB("ERROR: Recursion detected calling function '%s'", func); -} - class ExpressionEvaluatorFunction : public ExpressionEvaluator { - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - if (expr->recursioncount >= 1000) { - function_recursion_detected(expr->call_funcname.c_str()); - // TO DO: throw function_recursion_detected(); - return ValuePtr::undefined; + ValuePtr evaluate(const class Expression *expr, const class Context *context) const { + // FIXME: Throw based on stack usage. + // NB! This doesn't currently work since the stack usage isn't initialized at this point + // int su = context->stackUsage(); + // if (su > 1000000) PRINTB("Stack usage: %d", su); + if (expr->recursioncount >= 1000) { + throw FunctionRecursionException(expr->call_funcname.c_str()); + return ValuePtr::undefined; + } + expr->recursioncount += 1; + EvalContext *c = new EvalContext(context, expr->call_arguments); + ValuePtr result = context->evaluate_function(expr->call_funcname, c); + delete c; + expr->recursioncount -= 1; + return result; } - expr->recursioncount += 1; - EvalContext *c = new EvalContext(context, expr->call_arguments); - ValuePtr result = context->evaluate_function(expr->call_funcname, c); - delete c; - expr->recursioncount -= 1; - return result; - } }; class ExpressionEvaluatorLet : public ExpressionEvaluator diff --git a/src/function.h b/src/function.h index fe39f61f..ec594717 100644 --- a/src/function.h +++ b/src/function.h @@ -8,6 +8,19 @@ #include +#include +class FunctionRecursionException: public std::exception { +public: + FunctionRecursionException(const char *funcname) : funcname(funcname) {} + virtual const char *what() const throw() { + std::stringstream out; + out << "ERROR: Recursion detected calling function '" << this->funcname << "'"; + return out.str().c_str(); + } +private: + const char *funcname; +}; + class AbstractFunction { private: From ab96a826291e449bef467129a6095aa2b699bf92 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 17:30:05 -0500 Subject: [PATCH 040/263] Minor cleanup of recursion exception handling --- openscad.pro | 1 + src/evalcontext.cc | 3 ++- src/expr.cc | 4 ++-- src/function.h | 14 -------------- src/module.cc | 3 ++- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/openscad.pro b/openscad.pro index f926ac56..7a06b0be 100644 --- a/openscad.pro +++ b/openscad.pro @@ -246,6 +246,7 @@ HEADERS += src/typedefs.h \ src/export.h \ src/expression.h \ src/function.h \ + src/exceptions.h \ src/grid.h \ src/highlighter.h \ src/localscope.h \ diff --git a/src/evalcontext.cc b/src/evalcontext.cc index d8adb154..395a2329 100644 --- a/src/evalcontext.cc +++ b/src/evalcontext.cc @@ -5,6 +5,7 @@ #include "printutils.h" #include "builtin.h" #include "localscope.h" +#include "exceptions.h" #include @@ -23,7 +24,7 @@ ValuePtr EvalContext::getArgValue(size_t i, const Context *ctx) const try { v = arg.second->evaluate(ctx ? ctx : this); } - catch (FunctionRecursionException &e) { + catch (RecursionException &e) { PRINT(e.what()); } } diff --git a/src/expr.cc b/src/expr.cc index 348187dc..13fa83d8 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -32,7 +32,7 @@ #include #include "stl-utils.h" #include "printutils.h" -#include "function.h" +#include "exceptions.h" #include #include @@ -272,7 +272,7 @@ class ExpressionEvaluatorFunction : public ExpressionEvaluator // int su = context->stackUsage(); // if (su > 1000000) PRINTB("Stack usage: %d", su); if (expr->recursioncount >= 1000) { - throw FunctionRecursionException(expr->call_funcname.c_str()); + throw RecursionException("function", expr->call_funcname.c_str()); return ValuePtr::undefined; } expr->recursioncount += 1; diff --git a/src/function.h b/src/function.h index ec594717..48496518 100644 --- a/src/function.h +++ b/src/function.h @@ -7,20 +7,6 @@ #include #include - -#include -class FunctionRecursionException: public std::exception { -public: - FunctionRecursionException(const char *funcname) : funcname(funcname) {} - virtual const char *what() const throw() { - std::stringstream out; - out << "ERROR: Recursion detected calling function '" << this->funcname << "'"; - return out.str().c_str(); - } -private: - const char *funcname; -}; - class AbstractFunction { private: diff --git a/src/module.cc b/src/module.cc index 82a16320..3bebacb3 100644 --- a/src/module.cc +++ b/src/module.cc @@ -33,6 +33,7 @@ #include "function.h" #include "printutils.h" #include "parsersettings.h" +#include "exceptions.h" #include namespace fs = boost::filesystem; @@ -189,7 +190,7 @@ AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation { ModRecursionGuard g(*inst); if (g.recursion_detected()) { - PRINTB("ERROR: Recursion detected calling module '%s'", inst->name()); + throw RecursionException("module", inst->name().c_str()); return NULL; } From ba4c50c6318dd839263f0179c000d3da497e0f6f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 24 Nov 2014 23:34:57 +0100 Subject: [PATCH 041/263] Add function to retrieve the maximum stack size. --- src/PlatformUtils-mac.mm | 5 +++++ src/PlatformUtils-posix.cc | 19 +++++++++++++++++++ src/PlatformUtils-win.cc | 5 +++++ src/PlatformUtils.h | 11 +++++++++++ 4 files changed, 40 insertions(+) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index c6ba6277..b0b7778b 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -18,5 +18,10 @@ std::string PlatformUtils::userConfigPath() return std::string([[appSupportDir path] UTF8String]) + std::string("/") + PlatformUtils::OPENSCAD_FOLDER_NAME; } +unsigned long PlatformUtils::stackLimit() +{ + return STACK_LIMIT_DEFAULT; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index 64cc5dbe..3854a5e7 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -1,3 +1,5 @@ +#include + #include "PlatformUtils.h" #include "boosty.h" @@ -41,5 +43,22 @@ std::string PlatformUtils::userConfigPath() return ""; } +unsigned long PlatformUtils::stackLimit() +{ + struct rlimit limit; + + int ret = getrlimit(RLIMIT_STACK, &limit); + if (ret == 0) { + if (limit.rlim_cur > STACK_BUFFER_SIZE) { + return limit.rlim_cur - STACK_BUFFER_SIZE; + } + if (limit.rlim_max > STACK_BUFFER_SIZE) { + return limit.rlim_max - STACK_BUFFER_SIZE; + } + } + + return STACK_LIMIT_DEFAULT; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index a504bb1f..c94a2a67 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -92,6 +92,11 @@ std::string PlatformUtils::userConfigPath() return retval + std::string("/") + PlatformUtils::OPENSCAD_FOLDER_NAME; } +unsigned long PlatformUtils::stackLimit() +{ + return STACK_LIMIT_DEFAULT; +} + #include #include #include diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index 11b58b08..82a84b17 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -2,6 +2,9 @@ #include +#define STACK_BUFFER_SIZE (64 * 1024) +#define STACK_LIMIT_DEFAULT (8 * 1024 * 1024 - STACK_BUFFER_SIZE) + namespace PlatformUtils { extern const char *OPENSCAD_FOLDER_NAME; @@ -38,6 +41,14 @@ namespace PlatformUtils { */ int setenv(const char *name, const char *value, int overwrite); + /** + * Return system defined stack limit. If the system does not define + * a specific limit, the platform specific code will select a value. + * + * @return maximum stack size in bytes. + */ + unsigned long stackLimit(); + /** * Single character separating path specifications in a list * (e.g. OPENSCADPATH). On Windows that's ';' and on most other From 756f8079d8e375238a1e547c8c508f13bddbf23f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 24 Nov 2014 23:36:29 +0100 Subject: [PATCH 042/263] Add class to determine the current stack size. --- openscad.pro | 2 ++ src/stackcheck.cc | 37 +++++++++++++++++++++++++++++++++++++ src/stackcheck.h | 21 +++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/stackcheck.cc create mode 100644 src/stackcheck.h diff --git a/openscad.pro b/openscad.pro index f926ac56..b74ac37f 100644 --- a/openscad.pro +++ b/openscad.pro @@ -245,6 +245,7 @@ HEADERS += src/typedefs.h \ src/dxfdim.h \ src/export.h \ src/expression.h \ + src/stackcheck.h \ src/function.h \ src/grid.h \ src/highlighter.h \ @@ -321,6 +322,7 @@ SOURCES += src/version_check.cc \ src/handle_dep.cc \ src/value.cc \ src/expr.cc \ + src/stackcheck.cc \ src/func.cc \ src/localscope.cc \ src/module.cc \ diff --git a/src/stackcheck.cc b/src/stackcheck.cc new file mode 100644 index 00000000..5471c043 --- /dev/null +++ b/src/stackcheck.cc @@ -0,0 +1,37 @@ +#include + +#include "stackcheck.h" +#include "PlatformUtils.h" + +StackCheck * StackCheck::self = 0; + +StackCheck::StackCheck() : ptr(0) +{ +} + +StackCheck::~StackCheck() +{ +} + +void StackCheck::init() +{ + ptr = sp(); +} + +unsigned long StackCheck::size() +{ + return std::labs(ptr - sp()); +} + +bool StackCheck::check() +{ + return size() >= PlatformUtils::stackLimit(); +} + +StackCheck * StackCheck::inst() +{ + if (self == 0) { + self = new StackCheck(); + } + return self; +} diff --git a/src/stackcheck.h b/src/stackcheck.h new file mode 100644 index 00000000..60ae5cd3 --- /dev/null +++ b/src/stackcheck.h @@ -0,0 +1,21 @@ +#pragma once + +class StackCheck +{ +public: + StackCheck(); + virtual ~StackCheck(); + + static StackCheck * inst(); + + void init(); + bool check(); + unsigned long size(); + +private: + unsigned char * sp() { unsigned char c; return &c; }; + + unsigned char * ptr; + + static StackCheck *self; +}; From dc8f559b85c022d1b6db05c93510e4faef0af7a3 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 24 Nov 2014 23:37:42 +0100 Subject: [PATCH 043/263] Use class hierarchy for the different types of expressions. --- src/builtin.cc | 14 +- src/expr.cc | 743 ++++++++++++++++++++++++----------------------- src/expression.h | 271 ++++++++++++----- src/func.cc | 8 +- src/openscad.cc | 3 + src/parser.y | 79 +++-- 6 files changed, 628 insertions(+), 490 deletions(-) diff --git a/src/builtin.cc b/src/builtin.cc index b04d2b53..76b76b90 100644 --- a/src/builtin.cc +++ b/src/builtin.cc @@ -94,19 +94,19 @@ std::string Builtins::isDeprecated(const std::string &name) Builtins::Builtins() { - this->globalscope.assignments.push_back(Assignment("$fn", boost::shared_ptr(new Expression(ValuePtr(0.0))))); - this->globalscope.assignments.push_back(Assignment("$fs", boost::shared_ptr(new Expression(ValuePtr(2.0))))); - this->globalscope.assignments.push_back(Assignment("$fa", boost::shared_ptr(new Expression(ValuePtr(12.0))))); - this->globalscope.assignments.push_back(Assignment("$t", boost::shared_ptr(new Expression(ValuePtr(0.0))))); + this->globalscope.assignments.push_back(Assignment("$fn", boost::shared_ptr(new ExpressionConst(ValuePtr(0.0))))); + this->globalscope.assignments.push_back(Assignment("$fs", boost::shared_ptr(new ExpressionConst(ValuePtr(2.0))))); + this->globalscope.assignments.push_back(Assignment("$fa", boost::shared_ptr(new ExpressionConst(ValuePtr(12.0))))); + this->globalscope.assignments.push_back(Assignment("$t", boost::shared_ptr(new ExpressionConst(ValuePtr(0.0))))); Value::VectorType zero3; zero3.push_back(Value(0.0)); zero3.push_back(Value(0.0)); zero3.push_back(Value(0.0)); ValuePtr zero3val(zero3); - this->globalscope.assignments.push_back(Assignment("$vpt", boost::shared_ptr(new Expression(zero3val)))); - this->globalscope.assignments.push_back(Assignment("$vpr", boost::shared_ptr(new Expression(zero3val)))); - this->globalscope.assignments.push_back(Assignment("$vpd", boost::shared_ptr(new Expression(ValuePtr(500))))); + this->globalscope.assignments.push_back(Assignment("$vpt", boost::shared_ptr(new ExpressionConst(zero3val)))); + this->globalscope.assignments.push_back(Assignment("$vpr", boost::shared_ptr(new ExpressionConst(zero3val)))); + this->globalscope.assignments.push_back(Assignment("$vpd", boost::shared_ptr(new ExpressionConst(ValuePtr(500))))); } Builtins::~Builtins() diff --git a/src/expr.cc b/src/expr.cc index eb0c27d2..2be6e6cb 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -23,7 +23,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ - #include "expression.h" #include "value.h" #include "evalcontext.h" @@ -32,14 +31,10 @@ #include #include "stl-utils.h" #include "printutils.h" +#include "stackcheck.h" #include #include -ExpressionEvaluator * Expression::evaluators[256]; - -// static initializer for the expression evaluator lookup table -ExpressionEvaluatorInit Expression::evaluatorInit; - // unnamed namespace namespace { Value::VectorType flatten(Value::VectorType const& vec) { @@ -71,358 +66,49 @@ namespace { } } -class ExpressionEvaluatorAbort : public ExpressionEvaluator +Expression::Expression() { - ValuePtr evaluate(const class Expression *, const class Context *) const { - abort(); - } -}; - -class ExpressionEvaluatorNot : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return ! expr->children[0]->evaluate(context); - } -}; - -class ExpressionEvaluatorLogicalAnd : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) && expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorLogicalOr : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) || expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorMultiply : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) * expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorDivision : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) / expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorModulo : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) % expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorPlus : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) + expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorMinus : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) - expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorLess : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) < expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorLessOrEqual : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) <= expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorEqual : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) == expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorNotEqual : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children.at(0)->evaluate(context) != expr->children.at(1)->evaluate(context); - } -}; - -class ExpressionEvaluatorGreaterOrEqual : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) >= expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorGreater : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context) > expr->children[1]->evaluate(context); - } -}; - -class ExpressionEvaluatorTernary : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[expr->children[0]->evaluate(context) ? 1 : 2]->evaluate(context); - } -}; - -class ExpressionEvaluatorArray : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context)[expr->children[1]->evaluate(context)]; - } -}; - -class ExpressionEvaluatorInvert : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return -expr->children[0]->evaluate(context); - } -}; - -class ExpressionEvaluatorConst : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *) const { - return ValuePtr(expr->const_value); - } -}; - -class ExpressionEvaluatorRange : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - ValuePtr v1 = expr->children[0]->evaluate(context); - if (v1->type() == Value::NUMBER) { - ValuePtr v2 = expr->children[1]->evaluate(context); - if (v2->type() == Value::NUMBER) { - if (expr->children.size() == 2) { - Value::RangeType range(v1->toDouble(), v2->toDouble()); - return ValuePtr(range); - } else { - ValuePtr v3 = expr->children[2]->evaluate(context); - if (v3->type() == Value::NUMBER) { - Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble()); - return ValuePtr(range); - } - } - } - } - return ValuePtr::undefined; - } -}; - -class ExpressionEvaluatorVector : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - Value::VectorType vec; - BOOST_FOREACH(const Expression *e, expr->children) { - vec.push_back(*(e->evaluate(context))); - } - return ValuePtr(vec); - } -}; - -class ExpressionEvaluatorLookup : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return context->lookup_variable(expr->var_name); - } -}; - -class ExpressionEvaluatorMember : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - ValuePtr v = expr->children[0]->evaluate(context); - - if (v->type() == Value::VECTOR) { - if (expr->var_name == "x") return v[0]; - if (expr->var_name == "y") return v[1]; - if (expr->var_name == "z") return v[2]; - } else if (v->type() == Value::RANGE) { - if (expr->var_name == "begin") return v[0]; - if (expr->var_name == "step") return v[1]; - if (expr->var_name == "end") return v[2]; - } - return ValuePtr::undefined; - } -}; - -static void function_recursion_detected(const char *func) -{ - PRINTB("ERROR: Recursion detected calling function '%s'", func); } -class ExpressionEvaluatorFunction : public ExpressionEvaluator +Expression::Expression(const ValuePtr &val) { - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - if (expr->recursioncount >= 1000) { - function_recursion_detected(expr->call_funcname.c_str()); - // TO DO: throw function_recursion_detected(); - return ValuePtr::undefined; - } - expr->recursioncount += 1; - EvalContext *c = new EvalContext(context, expr->call_arguments); - ValuePtr result = context->evaluate_function(expr->call_funcname, c); - delete c; - expr->recursioncount -= 1; - return result; - } -}; - -class ExpressionEvaluatorLet : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - Context c(context); - evaluate_sequential_assignment(expr->call_arguments, &c); - - return expr->children[0]->evaluate(&c); - } -}; - -class ExpressionEvaluatorLcExpression : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - return expr->children[0]->evaluate(context); - } -}; - -class ExpressionEvaluatorLc : public ExpressionEvaluator -{ - ValuePtr evaluate(const class Expression *expr, const class Context *context) const { - Value::VectorType vec; - - if (expr->call_funcname == "if") { - if (expr->children[0]->evaluate(context)) { - if (expr->children[1]->type == EXPRESSION_TYPE_LC) { - return expr->children[1]->evaluate(context); - } else { - vec.push_back((*expr->children[1]->evaluate(context))); - } - } - return ValuePtr(vec); - } else if (expr->call_funcname == "for") { - EvalContext for_context(context, expr->call_arguments); - - Context assign_context(context); - - // comprehension for statements are by the parser reduced to only contain one single element - const std::string &it_name = for_context.getArgName(0); - ValuePtr it_values = for_context.getArgValue(0, &assign_context); - - Context c(context); - - if (it_values->type() == Value::RANGE) { - Value::RangeType range = it_values->toRange(); - boost::uint32_t steps = range.nbsteps(); - if (steps >= 1000000) { - PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps); - } else { - for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { - c.set_variable(it_name, ValuePtr(*it)); - vec.push_back((*expr->children[0]->evaluate(&c))); - } - } - } - else if (it_values->type() == Value::VECTOR) { - for (size_t i = 0; i < it_values->toVector().size(); i++) { - c.set_variable(it_name, it_values->toVector()[i]); - vec.push_back((*expr->children[0]->evaluate(&c))); - } - } - else if (it_values->type() != Value::UNDEFINED) { - c.set_variable(it_name, it_values); - vec.push_back((*expr->children[0]->evaluate(&c))); - } - if (expr->children[0]->type == EXPRESSION_TYPE_LC) { - return ValuePtr(flatten(vec)); - } else { - return ValuePtr(vec); - } - } else if (expr->call_funcname == "let") { - Context c(context); - evaluate_sequential_assignment(expr->call_arguments, &c); - - return expr->children[0]->evaluate(&c); - } else { - abort(); - } - } -}; - -ExpressionEvaluatorInit::ExpressionEvaluatorInit() -{ - ExpressionEvaluator *abort = new ExpressionEvaluatorAbort(); - for (int a = 0;a < 256;a++) { - Expression::evaluators[a] = abort; - } - - Expression::evaluators[EXPRESSION_TYPE_NOT] = new ExpressionEvaluatorNot(); - Expression::evaluators[EXPRESSION_TYPE_LOGICAL_AND] = new ExpressionEvaluatorLogicalAnd(); - Expression::evaluators[EXPRESSION_TYPE_LOGICAL_OR] = new ExpressionEvaluatorLogicalOr(); - Expression::evaluators[EXPRESSION_TYPE_MULTIPLY] = new ExpressionEvaluatorMultiply(); - Expression::evaluators[EXPRESSION_TYPE_DIVISION] = new ExpressionEvaluatorDivision(); - Expression::evaluators[EXPRESSION_TYPE_MODULO] = new ExpressionEvaluatorModulo(); - Expression::evaluators[EXPRESSION_TYPE_PLUS] = new ExpressionEvaluatorPlus(); - Expression::evaluators[EXPRESSION_TYPE_MINUS] = new ExpressionEvaluatorMinus(); - Expression::evaluators[EXPRESSION_TYPE_LESS] = new ExpressionEvaluatorLess(); - Expression::evaluators[EXPRESSION_TYPE_LESS_OR_EQUAL] = new ExpressionEvaluatorLessOrEqual(); - Expression::evaluators[EXPRESSION_TYPE_EQUAL] = new ExpressionEvaluatorEqual(); - Expression::evaluators[EXPRESSION_TYPE_NOT_EQUAL] = new ExpressionEvaluatorNotEqual(); - Expression::evaluators[EXPRESSION_TYPE_GREATER_OR_EQUAL] = new ExpressionEvaluatorGreaterOrEqual(); - Expression::evaluators[EXPRESSION_TYPE_GREATER] = new ExpressionEvaluatorGreater(); - Expression::evaluators[EXPRESSION_TYPE_TERNARY] = new ExpressionEvaluatorTernary(); - Expression::evaluators[EXPRESSION_TYPE_ARRAY_ACCESS] = new ExpressionEvaluatorArray(); - Expression::evaluators[EXPRESSION_TYPE_INVERT] = new ExpressionEvaluatorInvert(); - Expression::evaluators[EXPRESSION_TYPE_CONST] = new ExpressionEvaluatorConst(); - Expression::evaluators[EXPRESSION_TYPE_RANGE] = new ExpressionEvaluatorRange(); - Expression::evaluators[EXPRESSION_TYPE_VECTOR] = new ExpressionEvaluatorVector(); - Expression::evaluators[EXPRESSION_TYPE_LOOKUP] = new ExpressionEvaluatorLookup(); - Expression::evaluators[EXPRESSION_TYPE_MEMBER] = new ExpressionEvaluatorMember(); - Expression::evaluators[EXPRESSION_TYPE_FUNCTION] = new ExpressionEvaluatorFunction(); - Expression::evaluators[EXPRESSION_TYPE_LET] = new ExpressionEvaluatorLet(); - Expression::evaluators[EXPRESSION_TYPE_LC_EXPRESSION] = new ExpressionEvaluatorLcExpression(); - Expression::evaluators[EXPRESSION_TYPE_LC] = new ExpressionEvaluatorLc(); + const_value = val; } -Expression::Expression(const unsigned char type) : recursioncount(0) +Expression::Expression(const std::string &val) { - setType(type); + var_name = val; } -Expression::Expression(const unsigned char type, Expression *left, Expression *right) - : recursioncount(0) +Expression::Expression(const std::string &val, Expression *expr) { - setType(type); - this->children.push_back(left); - this->children.push_back(right); + var_name = val; + children.push_back(expr); + first = expr; } -Expression::Expression(const unsigned char type, Expression *expr) - : recursioncount(0) +Expression::Expression(Expression *expr) { - setType(type); - this->children.push_back(expr); + children.push_back(expr); + first = expr; } -Expression::Expression(const ValuePtr &val) : const_value(val), recursioncount(0) +Expression::Expression(Expression *left, Expression *right) { - setType(EXPRESSION_TYPE_CONST); + children.push_back(left); + children.push_back(right); + first = left; + second = right; +} + +Expression::Expression(Expression *expr1, Expression *expr2, Expression *expr3) +{ + children.push_back(expr1); + children.push_back(expr2); + children.push_back(expr3); + first = expr1; + second = expr2; + third = expr3; } Expression::~Expression() @@ -430,20 +116,6 @@ Expression::~Expression() std::for_each(this->children.begin(), this->children.end(), del_fun()); } -void Expression::setType(const unsigned char type) -{ - this->type = type; - this->evaluator = evaluators[type]; -} - -ValuePtr Expression::evaluate(const Context *context) const -{ - char _c; - context->checkStack(&_c); - - return evaluator->evaluate(this, context); -} - namespace /* anonymous*/ { std::ostream &operator << (std::ostream &o, AssignmentList const& l) { @@ -458,10 +130,15 @@ namespace /* anonymous*/ { } +bool Expression::isListComprehension() +{ + return false; +} + std::string Expression::toString() const { std::stringstream stream; - +/* switch (this->type) { case EXPRESSION_TYPE_MULTIPLY: case EXPRESSION_TYPE_DIVISION: @@ -561,9 +238,361 @@ std::string Expression::toString() const assert(false && "Illegal expression type"); break; } + */ return stream.str(); } +ExpressionNot::ExpressionNot(Expression *expr) : Expression(expr) +{ +} + +ValuePtr ExpressionNot::evaluate(const Context *context) const +{ + return !first->evaluate(context); +} + +ExpressionLogicalAnd::ExpressionLogicalAnd(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionLogicalAnd::evaluate(const Context *context) const +{ + return this->first->evaluate(context) && this->second->evaluate(context); +} + +ExpressionLogicalOr::ExpressionLogicalOr(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionLogicalOr::evaluate(const Context *context) const +{ + return this->first->evaluate(context) || this->second->evaluate(context); +} + +ExpressionMultiply::ExpressionMultiply(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionMultiply::evaluate(const Context *context) const +{ + return this->first->evaluate(context) * this->second->evaluate(context); +} + +ExpressionDivision::ExpressionDivision(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionDivision::evaluate(const Context *context) const +{ + return this->first->evaluate(context) / this->second->evaluate(context); +} + +ExpressionModulo::ExpressionModulo(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionModulo::evaluate(const Context *context) const +{ + return this->first->evaluate(context) % this->second->evaluate(context); +} + +ExpressionPlus::ExpressionPlus(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionPlus::evaluate(const Context *context) const +{ + return this->first->evaluate(context) + this->second->evaluate(context); +} + +ExpressionMinus::ExpressionMinus(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionMinus::evaluate(const Context *context) const +{ + return this->first->evaluate(context) - this->second->evaluate(context); +} + +ExpressionLess::ExpressionLess(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionLess::evaluate(const Context *context) const +{ + return this->first->evaluate(context) < this->second->evaluate(context); +} + +ExpressionLessOrEqual::ExpressionLessOrEqual(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionLessOrEqual::evaluate(const Context *context) const +{ + return this->first->evaluate(context) <= this->second->evaluate(context); +} + +ExpressionEqual::ExpressionEqual(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionEqual::evaluate(const Context *context) const +{ + return this->first->evaluate(context) == this->second->evaluate(context); +} + +ExpressionNotEqual::ExpressionNotEqual(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionNotEqual::evaluate(const Context *context) const +{ + return this->first->evaluate(context) != this->second->evaluate(context); +} + +ExpressionGreaterOrEqual::ExpressionGreaterOrEqual(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionGreaterOrEqual::evaluate(const Context *context) const +{ + return this->first->evaluate(context) >= this->second->evaluate(context); +} + +ExpressionGreater::ExpressionGreater(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionGreater::evaluate(const Context *context) const +{ + return this->first->evaluate(context) > this->second->evaluate(context); +} + +ExpressionTernary::ExpressionTernary(Expression *expr1, Expression *expr2, Expression *expr3) : Expression(expr1, expr2, expr3) +{ +} + +ValuePtr ExpressionTernary::evaluate(const Context *context) const +{ + return (this->first->evaluate(context) ? this->second : this->third)->evaluate(context); +} + +ExpressionArray::ExpressionArray(Expression *left, Expression *right) : Expression(left, right) +{ +} + +ValuePtr ExpressionArray::evaluate(const Context *context) const { + return this->first->evaluate(context)[this->second->evaluate(context)]; +} + +ExpressionInvert::ExpressionInvert(Expression *expr) : Expression(expr) +{ +} + +ValuePtr ExpressionInvert::evaluate(const Context *context) const +{ + return -this->first->evaluate(context); +} + +ExpressionConst::ExpressionConst(const ValuePtr &val) : Expression(val) +{ +} + +ValuePtr ExpressionConst::evaluate(const class Context *) const +{ + return ValuePtr(this->const_value); +} + +ExpressionRange::ExpressionRange(Expression *expr1, Expression *expr2) : Expression(expr1, expr2) +{ +} + +ExpressionRange::ExpressionRange(Expression *expr1, Expression *expr2, Expression *expr3) : Expression(expr1, expr2, expr3) +{ +} + +ValuePtr ExpressionRange::evaluate(const Context *context) const +{ + ValuePtr v1 = this->first->evaluate(context); + if (v1->type() == Value::NUMBER) { + ValuePtr v2 = this->second->evaluate(context); + if (v2->type() == Value::NUMBER) { + if (this->children.size() == 2) { + Value::RangeType range(v1->toDouble(), v2->toDouble()); + return ValuePtr(range); + } else { + ValuePtr v3 = this->third->evaluate(context); + if (v3->type() == Value::NUMBER) { + Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble()); + return ValuePtr(range); + } + } + } + } + return ValuePtr::undefined; +} + +ExpressionVector::ExpressionVector(Expression *expr) : Expression(expr) +{ +} + +ValuePtr ExpressionVector::evaluate(const Context *context) const +{ + Value::VectorType vec; + BOOST_FOREACH(const Expression *e, this->children) { + vec.push_back(*(e->evaluate(context))); + } + return ValuePtr(vec); +} + +ExpressionLookup::ExpressionLookup(const std::string &val) : Expression(val) +{ +} + +ValuePtr ExpressionLookup::evaluate(const Context *context) const +{ + return context->lookup_variable(this->var_name); +} + +ExpressionMember::ExpressionMember(const std::string &val, Expression *expr) : Expression(val, expr) +{ +} + +ValuePtr ExpressionMember::evaluate(const Context *context) const +{ + ValuePtr v = this->first->evaluate(context); + + if (v->type() == Value::VECTOR) { + if (this->var_name == "x") return v[0]; + if (this->var_name == "y") return v[1]; + if (this->var_name == "z") return v[2]; + } else if (v->type() == Value::RANGE) { + if (this->var_name == "begin") return v[0]; + if (this->var_name == "step") return v[1]; + if (this->var_name == "end") return v[2]; + } + return ValuePtr::undefined; +} + +static void function_recursion_detected(const char *func) +{ + PRINTB("ERROR: Recursion detected calling function '%s'", func); +} + +ExpressionFunction::ExpressionFunction() +{ +} + +ValuePtr ExpressionFunction::evaluate(const Context *context) const +{ + if (StackCheck::inst()->check()) { + function_recursion_detected(this->call_funcname.c_str()); + // TO DO: throw function_recursion_detected(); + return ValuePtr::undefined; + } + + EvalContext *c = new EvalContext(context, this->call_arguments); + ValuePtr result = context->evaluate_function(this->call_funcname, c); + delete c; + + return result; +} + +ExpressionLet::ExpressionLet() +{ +} + +ValuePtr ExpressionLet::evaluate(const Context *context) const +{ + Context c(context); + evaluate_sequential_assignment(this->call_arguments, &c); + + return this->children[0]->evaluate(&c); +} + +ExpressionLcExpression::ExpressionLcExpression(Expression *expr) : Expression(expr) +{ +} + +ValuePtr ExpressionLcExpression::evaluate(const Context *context) const +{ + return this->children[0]->evaluate(context); +} + +ExpressionLc::ExpressionLc(Expression *expr) : Expression(expr) +{ +} + +ExpressionLc::ExpressionLc(Expression *expr1, Expression *expr2) : Expression(expr1, expr2) +{ +} + +bool ExpressionLc::isListComprehension() +{ + return true; +} + +ValuePtr ExpressionLc::evaluate(const Context *context) const +{ + Value::VectorType vec; + + if (this->call_funcname == "if") { + if (this->children[0]->evaluate(context)) { + if (this->children[1]->isListComprehension()) { + return this->children[1]->evaluate(context); + } else { + vec.push_back((*this->children[1]->evaluate(context))); + } + } + return ValuePtr(vec); + } else if (this->call_funcname == "for") { + EvalContext for_context(context, this->call_arguments); + + Context assign_context(context); + + // comprehension for statements are by the parser reduced to only contain one single element + const std::string &it_name = for_context.getArgName(0); + ValuePtr it_values = for_context.getArgValue(0, &assign_context); + + Context c(context); + + if (it_values->type() == Value::RANGE) { + Value::RangeType range = it_values->toRange(); + boost::uint32_t steps = range.nbsteps(); + if (steps >= 1000000) { + PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps); + } else { + for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { + c.set_variable(it_name, ValuePtr(*it)); + vec.push_back((*this->children[0]->evaluate(&c))); + } + } + } + else if (it_values->type() == Value::VECTOR) { + for (size_t i = 0; i < it_values->toVector().size(); i++) { + c.set_variable(it_name, it_values->toVector()[i]); + vec.push_back((*this->children[0]->evaluate(&c))); + } + } + else if (it_values->type() != Value::UNDEFINED) { + c.set_variable(it_name, it_values); + vec.push_back((*this->children[0]->evaluate(&c))); + } + if (this->children[0]->isListComprehension()) { + return ValuePtr(flatten(vec)); + } else { + return ValuePtr(vec); + } + } else if (this->call_funcname == "let") { + Context c(context); + evaluate_sequential_assignment(this->call_arguments, &c); + + return this->children[0]->evaluate(&c); + } else { + abort(); + } +} + std::ostream &operator<<(std::ostream &stream, const Expression &expr) { stream << expr.toString(); diff --git a/src/expression.h b/src/expression.h index a83a75ef..28ba0378 100644 --- a/src/expression.h +++ b/src/expression.h @@ -5,49 +5,13 @@ #include "value.h" #include "typedefs.h" -#define EXPRESSION_TYPE_NOT ('!') -#define EXPRESSION_TYPE_LOGICAL_AND ('&') -#define EXPRESSION_TYPE_LOGICAL_OR ('|') -#define EXPRESSION_TYPE_MULTIPLY ('*') -#define EXPRESSION_TYPE_DIVISION ('/') -#define EXPRESSION_TYPE_MODULO ('%') -#define EXPRESSION_TYPE_PLUS ('+') -#define EXPRESSION_TYPE_MINUS ('-') -#define EXPRESSION_TYPE_LESS ('<') -#define EXPRESSION_TYPE_LESS_OR_EQUAL ('0') -#define EXPRESSION_TYPE_EQUAL ('=') -#define EXPRESSION_TYPE_NOT_EQUAL ('1') -#define EXPRESSION_TYPE_GREATER_OR_EQUAL ('2') -#define EXPRESSION_TYPE_GREATER ('>') -#define EXPRESSION_TYPE_TERNARY ('?') -#define EXPRESSION_TYPE_ARRAY_ACCESS ('[') -#define EXPRESSION_TYPE_INVERT ('I') -#define EXPRESSION_TYPE_CONST ('C') -#define EXPRESSION_TYPE_RANGE ('R') -#define EXPRESSION_TYPE_VECTOR ('V') -#define EXPRESSION_TYPE_LOOKUP ('L') -#define EXPRESSION_TYPE_MEMBER ('N') -#define EXPRESSION_TYPE_FUNCTION ('F') -#define EXPRESSION_TYPE_LET ('l') -#define EXPRESSION_TYPE_LC_EXPRESSION ('i') -#define EXPRESSION_TYPE_LC ('c') - -class ExpressionEvaluator -{ -public: - virtual ValuePtr evaluate(const class Expression *expr, const class Context *context) const = 0; -}; - -class ExpressionEvaluatorInit -{ -public: - ExpressionEvaluatorInit(); -}; - class Expression { public: std::vector children; + Expression *first; + Expression *second; + Expression *third; ValuePtr const_value; std::string var_name; @@ -55,45 +19,204 @@ public: std::string call_funcname; AssignmentList call_arguments; + Expression(); Expression(const ValuePtr &val); - Expression(const unsigned char type); - Expression(const unsigned char type, Expression *left, Expression *right); - Expression(const unsigned char type, Expression *expr); - ~Expression(); + Expression(const std::string &val); + Expression(const std::string &val, Expression *expr); + Expression(Expression *expr); + Expression(Expression *left, Expression *right); + Expression(Expression *expr1, Expression *expr2, Expression *expr3); + virtual ~Expression(); - void setType(const unsigned char type); - ValuePtr evaluate(const class Context *context) const; + virtual bool isListComprehension(); + virtual ValuePtr evaluate(const class Context *context) const = 0; std::string toString() const; - -private: - // Boolean: ! && || - // Operators: * / % + - - // Relations: < <= == != >= > - // Vector element: [] - // Condition operator: ?: - // Invert (prefix '-'): I - // Constant value: C - // Create Range: R - // Create Vector: V - // Create Matrix: M - // Lookup Variable: L - // Lookup member per name: N - // Function call: F - // Let expression: l - // List comprehension expression: i - // List comprehension: c - unsigned char type; - ExpressionEvaluator *evaluator; - - mutable int recursioncount; - - static ExpressionEvaluator *evaluators[256]; - static ExpressionEvaluatorInit evaluatorInit; - - friend class ExpressionEvaluatorInit; - friend class ExpressionEvaluatorLc; // for type - friend class ExpressionEvaluatorFunction; // for recursioncount }; std::ostream &operator<<(std::ostream &stream, const Expression &expr); + +class ExpressionNot : public Expression +{ +public: + ExpressionNot(Expression *expr); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLogicalAnd : public Expression +{ +public: + ExpressionLogicalAnd(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLogicalOr : public Expression +{ +public: + ExpressionLogicalOr(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionMultiply : public Expression +{ +public: + ExpressionMultiply(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionDivision : public Expression +{ +public: + ExpressionDivision(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionModulo : public Expression +{ +public: + ExpressionModulo(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionPlus : public Expression +{ +public: + ExpressionPlus(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionMinus : public Expression +{ +public: + ExpressionMinus(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLess : public Expression +{ +public: + ExpressionLess(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLessOrEqual : public Expression +{ +public: + ExpressionLessOrEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionEqual : public Expression +{ +public: + ExpressionEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionNotEqual : public Expression +{ +public: + ExpressionNotEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionGreaterOrEqual : public Expression +{ +public: + ExpressionGreaterOrEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionGreater : public Expression +{ +public: + ExpressionGreater(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionTernary : public Expression +{ +public: + ExpressionTernary(Expression *expr1, Expression *expr2, Expression *expr3); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionArray : public Expression +{ +public: + ExpressionArray(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionInvert : public Expression +{ +public: + ExpressionInvert(Expression *expr); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionConst : public Expression +{ +public: + ExpressionConst(const ValuePtr &val); + ValuePtr evaluate(const class Context *) const; +}; + +class ExpressionRange : public Expression +{ +public: + ExpressionRange(Expression *expr1, Expression *expr2); + ExpressionRange(Expression *expr1, Expression *expr2, Expression *expr3); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionVector : public Expression +{ +public: + ExpressionVector(Expression *expr); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLookup : public Expression +{ +public: + ExpressionLookup(const std::string &val); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionMember : public Expression +{ +public: + ExpressionMember(const std::string &val, Expression *expr); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionFunction : public Expression +{ +public: + ExpressionFunction(); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLet : public Expression +{ +public: + ExpressionLet(); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLcExpression : public Expression +{ +public: + ExpressionLcExpression(Expression *expr); + ValuePtr evaluate(const class Context *context) const; +}; + +class ExpressionLc : public Expression +{ + bool isListComprehension(); +public: + ExpressionLc(Expression *expr); + ExpressionLc(Expression *expr1, Expression *expr2); + ValuePtr evaluate(const class Context *context) const; +}; diff --git a/src/func.cc b/src/func.cc index 168499cf..11faa327 100644 --- a/src/func.cc +++ b/src/func.cc @@ -35,6 +35,7 @@ #include #include "stl-utils.h" #include "printutils.h" +#include "stackcheck.h" #include #include @@ -88,21 +89,14 @@ Function::~Function() delete expr; } -static const char *txt = "stack usage: "; ValuePtr Function::evaluate(const Context *ctx, const EvalContext *evalctx) const { - char _c; - bool set = ctx->setStack(&_c); - if (!expr) return ValuePtr::undefined; Context *c = new Context(ctx); c->setVariables(definition_arguments, evalctx); ValuePtr result = expr->evaluate(c); delete c; - if (set) { - std::cout << txt << ctx->stackUsage() << std::endl; - } return result; } diff --git a/src/openscad.cc b/src/openscad.cc index bbd6c265..5b1c7c8a 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -39,6 +39,7 @@ #include "PlatformUtils.h" #include "LibraryInfo.h" #include "nodedumper.h" +#include "stackcheck.h" #include "CocoaUtils.h" #include @@ -655,6 +656,8 @@ int main(int argc, char **argv) { int rc = 0; bool isGuiLaunched = getenv("GUI_LAUNCHED") != 0; + StackCheck::inst()->init(); + #ifdef Q_OS_MAC if (isGuiLaunched) set_output_handler(CocoaUtils::nslog, NULL); #else diff --git a/src/parser.y b/src/parser.y index 9456f662..8ed27b85 100644 --- a/src/parser.y +++ b/src/parser.y @@ -308,65 +308,57 @@ single_module_instantiation: expr: TOK_TRUE { - $$ = new Expression(ValuePtr(true)); + $$ = new ExpressionConst(ValuePtr(true)); } | TOK_FALSE { - $$ = new Expression(ValuePtr(false)); + $$ = new ExpressionConst(ValuePtr(false)); } | TOK_UNDEF { - $$ = new Expression(ValuePtr::undefined); + $$ = new ExpressionConst(ValuePtr::undefined); } | TOK_ID { - $$ = new Expression(EXPRESSION_TYPE_LOOKUP); - $$->var_name = $1; + $$ = new ExpressionLookup($1); free($1); } | expr '.' TOK_ID { - $$ = new Expression(EXPRESSION_TYPE_MEMBER, $1); - $$->var_name = $3; + $$ = new ExpressionMember($3, $1); free($3); } | TOK_STRING { - $$ = new Expression(ValuePtr(std::string($1))); + $$ = new ExpressionConst(ValuePtr(std::string($1))); free($1); } | TOK_NUMBER { - $$ = new Expression(ValuePtr($1)); + $$ = new ExpressionConst(ValuePtr($1)); } | TOK_LET '(' arguments_call ')' expr %prec LET { - $$ = new Expression(EXPRESSION_TYPE_LET); + $$ = new ExpressionLet(); $$->call_arguments = *$3; delete $3; $$->children.push_back($5); } | '[' expr ':' expr ']' { - $$ = new Expression(EXPRESSION_TYPE_RANGE); - $$->children.push_back($2); - $$->children.push_back($4); + $$ = new ExpressionRange($2, $4); } | '[' expr ':' expr ':' expr ']' { - $$ = new Expression(EXPRESSION_TYPE_RANGE); - $$->children.push_back($2); - $$->children.push_back($4); - $$->children.push_back($6); + $$ = new ExpressionRange($2, $4, $6); } | '[' list_comprehension_elements ']' { - $$ = new Expression(EXPRESSION_TYPE_LC_EXPRESSION); - $$->children.push_back($2); + $$ = new ExpressionLcExpression($2); } | '[' optional_commas ']' { - $$ = new Expression(ValuePtr(Value::VectorType())); + $$ = new ExpressionConst(ValuePtr(Value::VectorType())); } | '[' vector_expr optional_commas ']' { @@ -374,55 +366,55 @@ expr: } | expr '*' expr { - $$ = new Expression(EXPRESSION_TYPE_MULTIPLY, $1, $3); + $$ = new ExpressionMultiply($1, $3); } | expr '/' expr { - $$ = new Expression(EXPRESSION_TYPE_DIVISION, $1, $3); + $$ = new ExpressionDivision($1, $3); } | expr '%' expr { - $$ = new Expression(EXPRESSION_TYPE_MODULO, $1, $3); + $$ = new ExpressionModulo($1, $3); } | expr '+' expr { - $$ = new Expression(EXPRESSION_TYPE_PLUS, $1, $3); + $$ = new ExpressionPlus($1, $3); } | expr '-' expr { - $$ = new Expression(EXPRESSION_TYPE_MINUS, $1, $3); + $$ = new ExpressionMinus($1, $3); } | expr '<' expr { - $$ = new Expression(EXPRESSION_TYPE_LESS, $1, $3); + $$ = new ExpressionLess($1, $3); } | expr LE expr { - $$ = new Expression(EXPRESSION_TYPE_LESS_OR_EQUAL, $1, $3); + $$ = new ExpressionLessOrEqual($1, $3); } | expr EQ expr { - $$ = new Expression(EXPRESSION_TYPE_EQUAL, $1, $3); + $$ = new ExpressionEqual($1, $3); } | expr NE expr { - $$ = new Expression(EXPRESSION_TYPE_NOT_EQUAL, $1, $3); + $$ = new ExpressionNotEqual($1, $3); } | expr GE expr { - $$ = new Expression(EXPRESSION_TYPE_GREATER_OR_EQUAL, $1, $3); + $$ = new ExpressionGreaterOrEqual($1, $3); } | expr '>' expr { - $$ = new Expression(EXPRESSION_TYPE_GREATER, $1, $3); + $$ = new ExpressionGreater($1, $3); } | expr AND expr { - $$ = new Expression(EXPRESSION_TYPE_LOGICAL_AND, $1, $3); + $$ = new ExpressionLogicalAnd($1, $3); } | expr OR expr { - $$ = new Expression(EXPRESSION_TYPE_LOGICAL_OR, $1, $3); + $$ = new ExpressionLogicalOr($1, $3); } | '+' expr { @@ -430,11 +422,11 @@ expr: } | '-' expr { - $$ = new Expression(EXPRESSION_TYPE_INVERT, $2); + $$ = new ExpressionInvert($2); } | '!' expr { - $$ = new Expression(EXPRESSION_TYPE_NOT, $2); + $$ = new ExpressionNot($2); } | '(' expr ')' { @@ -442,18 +434,15 @@ expr: } | expr '?' expr ':' expr { - $$ = new Expression(EXPRESSION_TYPE_TERNARY); - $$->children.push_back($1); - $$->children.push_back($3); - $$->children.push_back($5); + $$ = new ExpressionTernary($1, $3, $5); } | expr '[' expr ']' { - $$ = new Expression(EXPRESSION_TYPE_ARRAY_ACCESS, $1, $3); + $$ = new ExpressionArray($1, $3); } | TOK_ID '(' arguments_call ')' { - $$ = new Expression(EXPRESSION_TYPE_FUNCTION); + $$ = new ExpressionFunction(); $$->call_funcname = $1; $$->call_arguments = *$3; free($1); @@ -466,7 +455,7 @@ list_comprehension_elements: be parsed as an expression) */ TOK_LET '(' arguments_call ')' list_comprehension_elements { - $$ = new Expression(EXPRESSION_TYPE_LC, $5); + $$ = new ExpressionLc($5); $$->call_funcname = "let"; $$->call_arguments = *$3; delete $3; @@ -477,7 +466,7 @@ list_comprehension_elements: /* transform for(i=...,j=...) -> for(i=...) for(j=...) */ for (int i = $3->size()-1; i >= 0; i--) { - Expression *e = new Expression(EXPRESSION_TYPE_LC, $$); + Expression *e = new ExpressionLc($$); e->call_funcname = "for"; e->call_arguments.push_back((*$3)[i]); $$ = e; @@ -486,7 +475,7 @@ list_comprehension_elements: } | TOK_IF '(' expr ')' list_comprehension_elements_or_expr { - $$ = new Expression(EXPRESSION_TYPE_LC, $3, $5); + $$ = new ExpressionLc($3, $5); $$->call_funcname = "if"; } ; @@ -504,7 +493,7 @@ optional_commas: vector_expr: expr { - $$ = new Expression(EXPRESSION_TYPE_VECTOR, $1); + $$ = new ExpressionVector($1); } | vector_expr ',' optional_commas expr { From edc64bdbe9c35798d0ffa03e4db9abb26445f31c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 17:43:13 -0500 Subject: [PATCH 044/263] forgot exceptions.h --- src/exceptions.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/exceptions.h diff --git a/src/exceptions.h b/src/exceptions.h new file mode 100644 index 00000000..1df1c535 --- /dev/null +++ b/src/exceptions.h @@ -0,0 +1,15 @@ +#include + +class RecursionException: public std::exception { +public: + RecursionException(const char *recursiontype, const char *funcname) + : rectype(recursiontype), funcname(funcname) {} + virtual const char *what() const throw() { + std::stringstream out; + out << "ERROR: Recursion detected calling " << this->rectype << " '" << this->funcname << "'"; + return out.str().c_str(); + } +private: + const char *rectype; + const char *funcname; +}; From 5debac7de0491bee0fb939a0df388fbb2a4adb54 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 17:44:39 -0500 Subject: [PATCH 045/263] Throw and catch RecursionException on module recursion --- src/module.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/module.cc b/src/module.cc index 3bebacb3..8139fa39 100644 --- a/src/module.cc +++ b/src/module.cc @@ -354,8 +354,12 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat #endif AbstractNode *node = new AbstractNode(inst); - std::vector instantiatednodes = this->scope.instantiateChildren(ctx, &c); - node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end()); - + try { + std::vector instantiatednodes = this->scope.instantiateChildren(ctx, &c); + node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end()); + } + catch (RecursionException &e) { + PRINT(e.what()); + } return node; } From aa586136ae8e38713b3453e7fd2e091eba232b7a Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 24 Nov 2014 23:52:07 +0100 Subject: [PATCH 046/263] Remove duplicate warning message. --- src/expr.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/expr.cc b/src/expr.cc index ba09cd36..4a608efa 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -475,11 +475,6 @@ ValuePtr ExpressionMember::evaluate(const Context *context) const return ValuePtr::undefined; } -static void function_recursion_detected(const char *func) -{ - PRINTB("ERROR: Recursion detected calling function '%s'", func); -} - ExpressionFunction::ExpressionFunction() { } @@ -487,7 +482,6 @@ ExpressionFunction::ExpressionFunction() ValuePtr ExpressionFunction::evaluate(const Context *context) const { if (StackCheck::inst()->check()) { - function_recursion_detected(this->call_funcname.c_str()); throw RecursionException("function", call_funcname.c_str()); } From e0fbeb8d9569e555c6b833be53df74aaa361aafa Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 18:12:58 -0500 Subject: [PATCH 047/263] Use StackCheck to detect module recursion --- src/module.cc | 18 ++---------------- src/module.h | 3 +-- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/module.cc b/src/module.cc index 8139fa39..a4b2278c 100644 --- a/src/module.cc +++ b/src/module.cc @@ -34,6 +34,7 @@ #include "printutils.h" #include "parsersettings.h" #include "exceptions.h" +#include "stackcheck.h" #include namespace fs = boost::filesystem; @@ -172,24 +173,9 @@ Module::~Module() { } -class ModRecursionGuard -{ -public: - ModRecursionGuard(const ModuleInstantiation &inst) : inst(inst) { - inst.recursioncount++; - } - ~ModRecursionGuard() { - inst.recursioncount--; - } - bool recursion_detected() const { return (inst.recursioncount > 1000); } -private: - const ModuleInstantiation &inst; -}; - AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const { - ModRecursionGuard g(*inst); - if (g.recursion_detected()) { + if (StackCheck::inst()->check()) { throw RecursionException("module", inst->name().c_str()); return NULL; } diff --git a/src/module.h b/src/module.h index 7962ec26..597c3b95 100644 --- a/src/module.h +++ b/src/module.h @@ -18,7 +18,7 @@ class ModuleInstantiation { public: ModuleInstantiation(const std::string &name = "") - : tag_root(false), tag_highlight(false), tag_background(false), recursioncount(0), modname(name) { } + : tag_root(false), tag_highlight(false), tag_background(false), modname(name) { } virtual ~ModuleInstantiation(); virtual std::string dump(const std::string &indent) const; @@ -40,7 +40,6 @@ public: bool tag_root; bool tag_highlight; bool tag_background; - mutable int recursioncount; protected: std::string modname; std::string modpath; From d8010a0659ec716ad0011a895518d924e144df67 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 18:25:38 -0500 Subject: [PATCH 048/263] Take a copy of the name of the recursive component, don't use a pointer to a temporary string --- src/exceptions.h | 9 +++++---- src/expr.cc | 2 +- src/module.cc | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/exceptions.h b/src/exceptions.h index 1df1c535..21c4a2ed 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -2,14 +2,15 @@ class RecursionException: public std::exception { public: - RecursionException(const char *recursiontype, const char *funcname) - : rectype(recursiontype), funcname(funcname) {} + RecursionException(const char *recursiontype, const std::string &name) + : rectype(recursiontype), name(name) {} + virtual ~RecursionException() throw() {} virtual const char *what() const throw() { std::stringstream out; - out << "ERROR: Recursion detected calling " << this->rectype << " '" << this->funcname << "'"; + out << "ERROR: Recursion detected calling " << this->rectype << " '" << this->name << "'"; return out.str().c_str(); } private: const char *rectype; - const char *funcname; + const std::string name; }; diff --git a/src/expr.cc b/src/expr.cc index 4a608efa..7f4afad1 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -482,7 +482,7 @@ ExpressionFunction::ExpressionFunction() ValuePtr ExpressionFunction::evaluate(const Context *context) const { if (StackCheck::inst()->check()) { - throw RecursionException("function", call_funcname.c_str()); + throw RecursionException("function", call_funcname); } EvalContext *c = new EvalContext(context, this->call_arguments); diff --git a/src/module.cc b/src/module.cc index a4b2278c..f2c738a0 100644 --- a/src/module.cc +++ b/src/module.cc @@ -176,7 +176,7 @@ Module::~Module() AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const { if (StackCheck::inst()->check()) { - throw RecursionException("module", inst->name().c_str()); + throw RecursionException("module", inst->name()); return NULL; } From 15835271c201409731a674cde4e3c51c5b13ecdb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 18:29:13 -0500 Subject: [PATCH 049/263] Implemented stackLimit() for Mac OS X --- src/PlatformUtils-mac.mm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index b0b7778b..cb93e522 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -20,7 +20,19 @@ std::string PlatformUtils::userConfigPath() unsigned long PlatformUtils::stackLimit() { - return STACK_LIMIT_DEFAULT; + struct rlimit limit; + + int ret = getrlimit(RLIMIT_STACK, &limit); + if (ret == 0) { + if (limit.rlim_cur > STACK_BUFFER_SIZE) { + return limit.rlim_cur - STACK_BUFFER_SIZE; + } + if (limit.rlim_max > STACK_BUFFER_SIZE) { + return limit.rlim_max - STACK_BUFFER_SIZE; + } + } + + return STACK_LIMIT_DEFAULT; } void PlatformUtils::ensureStdIO(void) {} From f1b29e1db9749579153b23313753b4bed7b75dba Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 18:54:51 -0500 Subject: [PATCH 050/263] Removed old stack measurement code --- src/context.cc | 45 +-------------------------------------------- src/context.h | 6 ------ 2 files changed, 1 insertion(+), 50 deletions(-) diff --git a/src/context.cc b/src/context.cc index 7d324168..29914d9a 100644 --- a/src/context.cc +++ b/src/context.cc @@ -49,7 +49,7 @@ static bool is_config_variable(const std::string &name) { created, and all children will share the root parent's stack. */ Context::Context(const Context *parent) - : parent(parent), stack_ptr(0), stack_max(0) + : parent(parent) { if (parent) { assert(parent->ctx_stack && "Parent context stack was null!"); @@ -70,49 +70,6 @@ Context::~Context() if (!parent) delete this->ctx_stack; } -unsigned long Context::stackUsage() const -{ - if (parent == NULL) { - unsigned long ret = std::labs((unsigned long)stack_ptr - (unsigned long)stack_max); - ((Context *)this)->stack_ptr = 0; - ((Context *)this)->stack_max = 0; - return ret; - } else { - return parent->stackUsage(); - } -} - -bool Context::setStack(const void* stack_cur) const -{ - if (parent == NULL) { - bool ret = this->stack_ptr == 0; - if (ret) { - ((Context *)this)->stack_ptr = stack_cur; - ((Context *)this)->stack_max = stack_cur; - } - return ret; - } else { - return parent->setStack(stack_cur); - } -} - -void Context::checkStack(const void *stack_cur) const -{ - if (parent == NULL) { - if (stack_cur < this->stack_ptr) { - if (stack_cur < this->stack_max) { - ((Context *)this)->stack_max = stack_cur; - } - } else { - if (stack_cur > this->stack_max) { - ((Context *)this)->stack_max = stack_cur; - } - } - } else { - parent->checkStack(stack_cur); - } -} - /*! Initialize context from a module argument list and a evaluation context which may pass variables which will be preferred over default values. diff --git a/src/context.h b/src/context.h index 9caae1d7..639973bb 100644 --- a/src/context.h +++ b/src/context.h @@ -33,17 +33,11 @@ public: const std::string &documentPath() const { return this->document_path; } std::string getAbsolutePath(const std::string &filename) const; - unsigned long stackUsage() const; - bool setStack(const void *stack_cur) const; - void checkStack(const void *stack_cur) const; - public: protected: const Context *parent; Stack *ctx_stack; - const void *stack_ptr; - const void *stack_max; typedef boost::unordered_map ValueMap; ValueMap constants; From 3612db6a2f0017268b507949a82d8a1db4ee2934 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 24 Nov 2014 20:44:39 -0500 Subject: [PATCH 051/263] Fixes crash during the second run of a failing recursive module --- src/localscope.cc | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/localscope.cc b/src/localscope.cc index 4f31a54b..e8f9947c 100644 --- a/src/localscope.cc +++ b/src/localscope.cc @@ -42,33 +42,13 @@ std::string LocalScope::dump(const std::string &indent) const return dump.str(); } -// FIXME: Two parameters here is a hack. Rather have separate types of scopes, or check the type of the first parameter. Note const vs. non-const std::vector LocalScope::instantiateChildren(const Context *evalctx, FileContext *filectx) const { - Context *c = filectx; - - if (!c) { - c = new Context(evalctx); - - // FIXME: If we make c a ModuleContext, child() doesn't work anymore - // c->functions_p = &this->functions; - // c->modules_p = &this->modules; - - // Uncommenting the following would allow assignments in local scopes, - // but would cause duplicate evaluation of module scopes - // BOOST_FOREACH (const Assignment &ass, this->assignments) { - // c->set_variable(ass.first, ass.second->evaluate(c)); - // } - } - std::vector childnodes; BOOST_FOREACH (ModuleInstantiation *modinst, this->children) { - AbstractNode *node = modinst->evaluate(c); + AbstractNode *node = modinst->evaluate(filectx ? filectx : evalctx); if (node) childnodes.push_back(node); } - if (c != filectx) delete c; - return childnodes; } - From be9b0ee925714c34e4ca706dfe92639c52fed3a3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 11:26:14 -0500 Subject: [PATCH 052/263] indentation --- src/expr.cc | 398 +++++++++++++++++++++++------------------------ src/expression.h | 119 +++++++------- 2 files changed, 258 insertions(+), 259 deletions(-) diff --git a/src/expr.cc b/src/expr.cc index 7f4afad1..f348f4cd 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -73,43 +73,43 @@ Expression::Expression() Expression::Expression(const ValuePtr &val) { - const_value = val; + const_value = val; } Expression::Expression(const std::string &val) { - var_name = val; + var_name = val; } Expression::Expression(const std::string &val, Expression *expr) { - var_name = val; - children.push_back(expr); - first = expr; + var_name = val; + children.push_back(expr); + first = expr; } Expression::Expression(Expression *expr) { - children.push_back(expr); - first = expr; + children.push_back(expr); + first = expr; } Expression::Expression(Expression *left, Expression *right) { - children.push_back(left); - children.push_back(right); - first = left; - second = right; + children.push_back(left); + children.push_back(right); + first = left; + second = right; } Expression::Expression(Expression *expr1, Expression *expr2, Expression *expr3) { - children.push_back(expr1); - children.push_back(expr2); - children.push_back(expr3); - first = expr1; - second = expr2; - third = expr3; + children.push_back(expr1); + children.push_back(expr2); + children.push_back(expr3); + first = expr1; + second = expr2; + third = expr3; } Expression::~Expression() @@ -133,7 +133,7 @@ namespace /* anonymous*/ { bool Expression::isListComprehension() { - return false; + return false; } std::string Expression::toString() const @@ -148,98 +148,98 @@ std::string Expression::toString() const case EXPRESSION_TYPE_MINUS: case EXPRESSION_TYPE_LESS: case EXPRESSION_TYPE_GREATER: - stream << "(" << *this->children[0] << " " << this->type << " " << *this->children[1] << ")"; - break; + stream << "(" << *this->children[0] << " " << this->type << " " << *this->children[1] << ")"; + break; case EXPRESSION_TYPE_NOT: - stream << "!" << *this->children[0]; - break; + stream << "!" << *this->children[0]; + break; case EXPRESSION_TYPE_LOGICAL_AND: - stream << "(" << *this->children[0] << " && " << *this->children[1] << ")"; - break; + stream << "(" << *this->children[0] << " && " << *this->children[1] << ")"; + break; case EXPRESSION_TYPE_LOGICAL_OR: - stream << "(" << *this->children[0] << " || " << *this->children[1] << ")"; - break; + stream << "(" << *this->children[0] << " || " << *this->children[1] << ")"; + break; case EXPRESSION_TYPE_LESS_OR_EQUAL: - stream << "(" << *this->children[0] << " <= " << *this->children[1] << ")"; - break; + stream << "(" << *this->children[0] << " <= " << *this->children[1] << ")"; + break; case EXPRESSION_TYPE_EQUAL: - stream << "(" << *this->children[0] << " == " << *this->children[1] << ")"; - break; + stream << "(" << *this->children[0] << " == " << *this->children[1] << ")"; + break; case EXPRESSION_TYPE_NOT_EQUAL: - stream << "(" << *this->children[0] << " != " << *this->children[1] << ")"; - break; + stream << "(" << *this->children[0] << " != " << *this->children[1] << ")"; + break; case EXPRESSION_TYPE_GREATER_OR_EQUAL: - stream << "(" << *this->children[0] << " >= " << *this->children[1] << ")"; - break; + stream << "(" << *this->children[0] << " >= " << *this->children[1] << ")"; + break; case EXPRESSION_TYPE_TERNARY: - stream << "(" << *this->children[0] << " ? " << *this->children[1] << " : " << *this->children[2] << ")"; - break; + stream << "(" << *this->children[0] << " ? " << *this->children[1] << " : " << *this->children[2] << ")"; + break; case EXPRESSION_TYPE_ARRAY_ACCESS: - stream << *this->children[0] << "[" << *this->children[1] << "]"; - break; + stream << *this->children[0] << "[" << *this->children[1] << "]"; + break; case EXPRESSION_TYPE_INVERT: - stream << "-" << *this->children[0]; - break; + stream << "-" << *this->children[0]; + break; case EXPRESSION_TYPE_CONST: - stream << *this->const_value; - break; + stream << *this->const_value; + break; case EXPRESSION_TYPE_RANGE: - stream << "[" << *this->children[0] << " : " << *this->children[1]; - if (this->children.size() > 2) { - stream << " : " << *this->children[2]; - } - stream << "]"; - break; + stream << "[" << *this->children[0] << " : " << *this->children[1]; + if (this->children.size() > 2) { + stream << " : " << *this->children[2]; + } + stream << "]"; + break; case EXPRESSION_TYPE_VECTOR: - stream << "["; - for (size_t i=0; i < this->children.size(); i++) { - if (i > 0) stream << ", "; - stream << *this->children[i]; - } - stream << "]"; - break; + stream << "["; + for (size_t i=0; i < this->children.size(); i++) { + if (i > 0) stream << ", "; + stream << *this->children[i]; + } + stream << "]"; + break; case EXPRESSION_TYPE_LOOKUP: - stream << this->var_name; - break; + stream << this->var_name; + break; case EXPRESSION_TYPE_MEMBER: - stream << *this->children[0] << "." << this->var_name; - break; + stream << *this->children[0] << "." << this->var_name; + break; case EXPRESSION_TYPE_FUNCTION: - stream << this->call_funcname << "(" << this->call_arguments << ")"; - break; + stream << this->call_funcname << "(" << this->call_arguments << ")"; + break; case EXPRESSION_TYPE_LET: - stream << "let(" << this->call_arguments << ") " << *this->children[0]; - break; + stream << "let(" << this->call_arguments << ") " << *this->children[0]; + break; case EXPRESSION_TYPE_LC_EXPRESSION: // list comprehension expression //case EXPRESSION_TYPE_LC: { - Expression const* c = this->children[0]; + Expression const* c = this->children[0]; - stream << "["; + stream << "["; - do { - if (c->call_funcname == "for") { - stream << "for(" << c->call_arguments << ") "; - c = c->children[0]; - } else if (c->call_funcname == "if") { - stream << "if(" << c->children[0] << ") "; - c = c->children[1]; - } else if (c->call_funcname == "let") { - stream << "let(" << c->call_arguments << ") "; - c = c->children[0]; - } else { - assert(false && "Illegal list comprehension element"); - } - } while (c->type == EXPRESSION_TYPE_LC); + do { + if (c->call_funcname == "for") { + stream << "for(" << c->call_arguments << ") "; + c = c->children[0]; + } else if (c->call_funcname == "if") { + stream << "if(" << c->children[0] << ") "; + c = c->children[1]; + } else if (c->call_funcname == "let") { + stream << "let(" << c->call_arguments << ") "; + c = c->children[0]; + } else { + assert(false && "Illegal list comprehension element"); + } + } while (c->type == EXPRESSION_TYPE_LC); - stream << *c << "]"; - break; + stream << *c << "]"; + break; } default: - assert(false && "Illegal expression type"); - break; + assert(false && "Illegal expression type"); + break; } - */ +*/ return stream.str(); } @@ -249,7 +249,7 @@ ExpressionNot::ExpressionNot(Expression *expr) : Expression(expr) ValuePtr ExpressionNot::evaluate(const Context *context) const { - return !first->evaluate(context); + return !first->evaluate(context); } ExpressionLogicalAnd::ExpressionLogicalAnd(Expression *left, Expression *right) : Expression(left, right) @@ -258,7 +258,7 @@ ExpressionLogicalAnd::ExpressionLogicalAnd(Expression *left, Expression *right) ValuePtr ExpressionLogicalAnd::evaluate(const Context *context) const { - return this->first->evaluate(context) && this->second->evaluate(context); + return this->first->evaluate(context) && this->second->evaluate(context); } ExpressionLogicalOr::ExpressionLogicalOr(Expression *left, Expression *right) : Expression(left, right) @@ -267,7 +267,7 @@ ExpressionLogicalOr::ExpressionLogicalOr(Expression *left, Expression *right) : ValuePtr ExpressionLogicalOr::evaluate(const Context *context) const { - return this->first->evaluate(context) || this->second->evaluate(context); + return this->first->evaluate(context) || this->second->evaluate(context); } ExpressionMultiply::ExpressionMultiply(Expression *left, Expression *right) : Expression(left, right) @@ -276,7 +276,7 @@ ExpressionMultiply::ExpressionMultiply(Expression *left, Expression *right) : Ex ValuePtr ExpressionMultiply::evaluate(const Context *context) const { - return this->first->evaluate(context) * this->second->evaluate(context); + return this->first->evaluate(context) * this->second->evaluate(context); } ExpressionDivision::ExpressionDivision(Expression *left, Expression *right) : Expression(left, right) @@ -285,7 +285,7 @@ ExpressionDivision::ExpressionDivision(Expression *left, Expression *right) : Ex ValuePtr ExpressionDivision::evaluate(const Context *context) const { - return this->first->evaluate(context) / this->second->evaluate(context); + return this->first->evaluate(context) / this->second->evaluate(context); } ExpressionModulo::ExpressionModulo(Expression *left, Expression *right) : Expression(left, right) @@ -294,7 +294,7 @@ ExpressionModulo::ExpressionModulo(Expression *left, Expression *right) : Expres ValuePtr ExpressionModulo::evaluate(const Context *context) const { - return this->first->evaluate(context) % this->second->evaluate(context); + return this->first->evaluate(context) % this->second->evaluate(context); } ExpressionPlus::ExpressionPlus(Expression *left, Expression *right) : Expression(left, right) @@ -303,7 +303,7 @@ ExpressionPlus::ExpressionPlus(Expression *left, Expression *right) : Expression ValuePtr ExpressionPlus::evaluate(const Context *context) const { - return this->first->evaluate(context) + this->second->evaluate(context); + return this->first->evaluate(context) + this->second->evaluate(context); } ExpressionMinus::ExpressionMinus(Expression *left, Expression *right) : Expression(left, right) @@ -312,7 +312,7 @@ ExpressionMinus::ExpressionMinus(Expression *left, Expression *right) : Expressi ValuePtr ExpressionMinus::evaluate(const Context *context) const { - return this->first->evaluate(context) - this->second->evaluate(context); + return this->first->evaluate(context) - this->second->evaluate(context); } ExpressionLess::ExpressionLess(Expression *left, Expression *right) : Expression(left, right) @@ -321,7 +321,7 @@ ExpressionLess::ExpressionLess(Expression *left, Expression *right) : Expression ValuePtr ExpressionLess::evaluate(const Context *context) const { - return this->first->evaluate(context) < this->second->evaluate(context); + return this->first->evaluate(context) < this->second->evaluate(context); } ExpressionLessOrEqual::ExpressionLessOrEqual(Expression *left, Expression *right) : Expression(left, right) @@ -330,7 +330,7 @@ ExpressionLessOrEqual::ExpressionLessOrEqual(Expression *left, Expression *right ValuePtr ExpressionLessOrEqual::evaluate(const Context *context) const { - return this->first->evaluate(context) <= this->second->evaluate(context); + return this->first->evaluate(context) <= this->second->evaluate(context); } ExpressionEqual::ExpressionEqual(Expression *left, Expression *right) : Expression(left, right) @@ -339,7 +339,7 @@ ExpressionEqual::ExpressionEqual(Expression *left, Expression *right) : Expressi ValuePtr ExpressionEqual::evaluate(const Context *context) const { - return this->first->evaluate(context) == this->second->evaluate(context); + return this->first->evaluate(context) == this->second->evaluate(context); } ExpressionNotEqual::ExpressionNotEqual(Expression *left, Expression *right) : Expression(left, right) @@ -348,7 +348,7 @@ ExpressionNotEqual::ExpressionNotEqual(Expression *left, Expression *right) : Ex ValuePtr ExpressionNotEqual::evaluate(const Context *context) const { - return this->first->evaluate(context) != this->second->evaluate(context); + return this->first->evaluate(context) != this->second->evaluate(context); } ExpressionGreaterOrEqual::ExpressionGreaterOrEqual(Expression *left, Expression *right) : Expression(left, right) @@ -357,7 +357,7 @@ ExpressionGreaterOrEqual::ExpressionGreaterOrEqual(Expression *left, Expression ValuePtr ExpressionGreaterOrEqual::evaluate(const Context *context) const { - return this->first->evaluate(context) >= this->second->evaluate(context); + return this->first->evaluate(context) >= this->second->evaluate(context); } ExpressionGreater::ExpressionGreater(Expression *left, Expression *right) : Expression(left, right) @@ -366,7 +366,7 @@ ExpressionGreater::ExpressionGreater(Expression *left, Expression *right) : Expr ValuePtr ExpressionGreater::evaluate(const Context *context) const { - return this->first->evaluate(context) > this->second->evaluate(context); + return this->first->evaluate(context) > this->second->evaluate(context); } ExpressionTernary::ExpressionTernary(Expression *expr1, Expression *expr2, Expression *expr3) : Expression(expr1, expr2, expr3) @@ -375,7 +375,7 @@ ExpressionTernary::ExpressionTernary(Expression *expr1, Expression *expr2, Expre ValuePtr ExpressionTernary::evaluate(const Context *context) const { - return (this->first->evaluate(context) ? this->second : this->third)->evaluate(context); + return (this->first->evaluate(context) ? this->second : this->third)->evaluate(context); } ExpressionArray::ExpressionArray(Expression *left, Expression *right) : Expression(left, right) @@ -383,7 +383,7 @@ ExpressionArray::ExpressionArray(Expression *left, Expression *right) : Expressi } ValuePtr ExpressionArray::evaluate(const Context *context) const { - return this->first->evaluate(context)[this->second->evaluate(context)]; + return this->first->evaluate(context)[this->second->evaluate(context)]; } ExpressionInvert::ExpressionInvert(Expression *expr) : Expression(expr) @@ -392,7 +392,7 @@ ExpressionInvert::ExpressionInvert(Expression *expr) : Expression(expr) ValuePtr ExpressionInvert::evaluate(const Context *context) const { - return -this->first->evaluate(context); + return -this->first->evaluate(context); } ExpressionConst::ExpressionConst(const ValuePtr &val) : Expression(val) @@ -401,7 +401,7 @@ ExpressionConst::ExpressionConst(const ValuePtr &val) : Expression(val) ValuePtr ExpressionConst::evaluate(const class Context *) const { - return ValuePtr(this->const_value); + return ValuePtr(this->const_value); } ExpressionRange::ExpressionRange(Expression *expr1, Expression *expr2) : Expression(expr1, expr2) @@ -414,23 +414,23 @@ ExpressionRange::ExpressionRange(Expression *expr1, Expression *expr2, Expressio ValuePtr ExpressionRange::evaluate(const Context *context) const { - ValuePtr v1 = this->first->evaluate(context); - if (v1->type() == Value::NUMBER) { - ValuePtr v2 = this->second->evaluate(context); - if (v2->type() == Value::NUMBER) { - if (this->children.size() == 2) { - Value::RangeType range(v1->toDouble(), v2->toDouble()); - return ValuePtr(range); - } else { - ValuePtr v3 = this->third->evaluate(context); - if (v3->type() == Value::NUMBER) { - Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble()); - return ValuePtr(range); - } - } - } - } - return ValuePtr::undefined; + ValuePtr v1 = this->first->evaluate(context); + if (v1->type() == Value::NUMBER) { + ValuePtr v2 = this->second->evaluate(context); + if (v2->type() == Value::NUMBER) { + if (this->children.size() == 2) { + Value::RangeType range(v1->toDouble(), v2->toDouble()); + return ValuePtr(range); + } else { + ValuePtr v3 = this->third->evaluate(context); + if (v3->type() == Value::NUMBER) { + Value::RangeType range(v1->toDouble(), v2->toDouble(), v3->toDouble()); + return ValuePtr(range); + } + } + } + } + return ValuePtr::undefined; } ExpressionVector::ExpressionVector(Expression *expr) : Expression(expr) @@ -439,11 +439,11 @@ ExpressionVector::ExpressionVector(Expression *expr) : Expression(expr) ValuePtr ExpressionVector::evaluate(const Context *context) const { - Value::VectorType vec; - BOOST_FOREACH(const Expression *e, this->children) { - vec.push_back(*(e->evaluate(context))); - } - return ValuePtr(vec); + Value::VectorType vec; + BOOST_FOREACH(const Expression *e, this->children) { + vec.push_back(*(e->evaluate(context))); + } + return ValuePtr(vec); } ExpressionLookup::ExpressionLookup(const std::string &val) : Expression(val) @@ -452,7 +452,7 @@ ExpressionLookup::ExpressionLookup(const std::string &val) : Expression(val) ValuePtr ExpressionLookup::evaluate(const Context *context) const { - return context->lookup_variable(this->var_name); + return context->lookup_variable(this->var_name); } ExpressionMember::ExpressionMember(const std::string &val, Expression *expr) : Expression(val, expr) @@ -461,18 +461,18 @@ ExpressionMember::ExpressionMember(const std::string &val, Expression *expr) : E ValuePtr ExpressionMember::evaluate(const Context *context) const { - ValuePtr v = this->first->evaluate(context); + ValuePtr v = this->first->evaluate(context); - if (v->type() == Value::VECTOR) { - if (this->var_name == "x") return v[0]; - if (this->var_name == "y") return v[1]; - if (this->var_name == "z") return v[2]; - } else if (v->type() == Value::RANGE) { - if (this->var_name == "begin") return v[0]; - if (this->var_name == "step") return v[1]; - if (this->var_name == "end") return v[2]; - } - return ValuePtr::undefined; + if (v->type() == Value::VECTOR) { + if (this->var_name == "x") return v[0]; + if (this->var_name == "y") return v[1]; + if (this->var_name == "z") return v[2]; + } else if (v->type() == Value::RANGE) { + if (this->var_name == "begin") return v[0]; + if (this->var_name == "step") return v[1]; + if (this->var_name == "end") return v[2]; + } + return ValuePtr::undefined; } ExpressionFunction::ExpressionFunction() @@ -481,15 +481,15 @@ ExpressionFunction::ExpressionFunction() ValuePtr ExpressionFunction::evaluate(const Context *context) const { - if (StackCheck::inst()->check()) { - throw RecursionException("function", call_funcname); - } + if (StackCheck::inst()->check()) { + throw RecursionException("function", call_funcname); + } - EvalContext *c = new EvalContext(context, this->call_arguments); - ValuePtr result = context->evaluate_function(this->call_funcname, c); - delete c; + EvalContext *c = new EvalContext(context, this->call_arguments); + ValuePtr result = context->evaluate_function(this->call_funcname, c); + delete c; - return result; + return result; } ExpressionLet::ExpressionLet() @@ -498,10 +498,10 @@ ExpressionLet::ExpressionLet() ValuePtr ExpressionLet::evaluate(const Context *context) const { - Context c(context); - evaluate_sequential_assignment(this->call_arguments, &c); + Context c(context); + evaluate_sequential_assignment(this->call_arguments, &c); - return this->children[0]->evaluate(&c); + return this->children[0]->evaluate(&c); } ExpressionLcExpression::ExpressionLcExpression(Expression *expr) : Expression(expr) @@ -510,7 +510,7 @@ ExpressionLcExpression::ExpressionLcExpression(Expression *expr) : Expression(ex ValuePtr ExpressionLcExpression::evaluate(const Context *context) const { - return this->children[0]->evaluate(context); + return this->children[0]->evaluate(context); } ExpressionLc::ExpressionLc(Expression *expr) : Expression(expr) @@ -523,68 +523,68 @@ ExpressionLc::ExpressionLc(Expression *expr1, Expression *expr2) : Expression(ex bool ExpressionLc::isListComprehension() { - return true; + return true; } ValuePtr ExpressionLc::evaluate(const Context *context) const { - Value::VectorType vec; + Value::VectorType vec; - if (this->call_funcname == "if") { - if (this->children[0]->evaluate(context)) { - if (this->children[1]->isListComprehension()) { - return this->children[1]->evaluate(context); - } else { - vec.push_back((*this->children[1]->evaluate(context))); - } - } - return ValuePtr(vec); - } else if (this->call_funcname == "for") { - EvalContext for_context(context, this->call_arguments); + if (this->call_funcname == "if") { + if (this->children[0]->evaluate(context)) { + if (this->children[1]->isListComprehension()) { + return this->children[1]->evaluate(context); + } else { + vec.push_back((*this->children[1]->evaluate(context))); + } + } + return ValuePtr(vec); + } else if (this->call_funcname == "for") { + EvalContext for_context(context, this->call_arguments); - Context assign_context(context); + Context assign_context(context); - // comprehension for statements are by the parser reduced to only contain one single element - const std::string &it_name = for_context.getArgName(0); - ValuePtr it_values = for_context.getArgValue(0, &assign_context); + // comprehension for statements are by the parser reduced to only contain one single element + const std::string &it_name = for_context.getArgName(0); + ValuePtr it_values = for_context.getArgValue(0, &assign_context); - Context c(context); + Context c(context); - if (it_values->type() == Value::RANGE) { - Value::RangeType range = it_values->toRange(); - boost::uint32_t steps = range.nbsteps(); - if (steps >= 1000000) { - PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps); - } else { - for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { - c.set_variable(it_name, ValuePtr(*it)); - vec.push_back((*this->children[0]->evaluate(&c))); - } - } - } - else if (it_values->type() == Value::VECTOR) { - for (size_t i = 0; i < it_values->toVector().size(); i++) { - c.set_variable(it_name, it_values->toVector()[i]); - vec.push_back((*this->children[0]->evaluate(&c))); - } - } - else if (it_values->type() != Value::UNDEFINED) { - c.set_variable(it_name, it_values); - vec.push_back((*this->children[0]->evaluate(&c))); - } - if (this->children[0]->isListComprehension()) { - return ValuePtr(flatten(vec)); - } else { - return ValuePtr(vec); - } - } else if (this->call_funcname == "let") { - Context c(context); - evaluate_sequential_assignment(this->call_arguments, &c); + if (it_values->type() == Value::RANGE) { + Value::RangeType range = it_values->toRange(); + boost::uint32_t steps = range.nbsteps(); + if (steps >= 1000000) { + PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps); + } else { + for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { + c.set_variable(it_name, ValuePtr(*it)); + vec.push_back((*this->children[0]->evaluate(&c))); + } + } + } + else if (it_values->type() == Value::VECTOR) { + for (size_t i = 0; i < it_values->toVector().size(); i++) { + c.set_variable(it_name, it_values->toVector()[i]); + vec.push_back((*this->children[0]->evaluate(&c))); + } + } + else if (it_values->type() != Value::UNDEFINED) { + c.set_variable(it_name, it_values); + vec.push_back((*this->children[0]->evaluate(&c))); + } + if (this->children[0]->isListComprehension()) { + return ValuePtr(flatten(vec)); + } else { + return ValuePtr(vec); + } + } else if (this->call_funcname == "let") { + Context c(context); + evaluate_sequential_assignment(this->call_arguments, &c); - return this->children[0]->evaluate(&c); - } else { - abort(); - } + return this->children[0]->evaluate(&c); + } else { + abort(); + } } std::ostream &operator<<(std::ostream &stream, const Expression &expr) diff --git a/src/expression.h b/src/expression.h index 28ba0378..08629e94 100644 --- a/src/expression.h +++ b/src/expression.h @@ -9,9 +9,9 @@ class Expression { public: std::vector children; - Expression *first; - Expression *second; - Expression *third; + Expression *first; + Expression *second; + Expression *third; ValuePtr const_value; std::string var_name; @@ -28,9 +28,8 @@ public: Expression(Expression *expr1, Expression *expr2, Expression *expr3); virtual ~Expression(); - virtual bool isListComprehension(); + virtual bool isListComprehension(); virtual ValuePtr evaluate(const class Context *context) const = 0; - std::string toString() const; }; @@ -39,184 +38,184 @@ std::ostream &operator<<(std::ostream &stream, const Expression &expr); class ExpressionNot : public Expression { public: - ExpressionNot(Expression *expr); - ValuePtr evaluate(const class Context *context) const; + ExpressionNot(Expression *expr); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLogicalAnd : public Expression { public: - ExpressionLogicalAnd(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionLogicalAnd(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLogicalOr : public Expression { public: - ExpressionLogicalOr(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionLogicalOr(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionMultiply : public Expression { public: - ExpressionMultiply(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionMultiply(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionDivision : public Expression { public: - ExpressionDivision(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionDivision(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionModulo : public Expression { public: - ExpressionModulo(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionModulo(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionPlus : public Expression { public: - ExpressionPlus(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionPlus(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionMinus : public Expression { public: - ExpressionMinus(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionMinus(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLess : public Expression { public: - ExpressionLess(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionLess(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLessOrEqual : public Expression { public: - ExpressionLessOrEqual(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionLessOrEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionEqual : public Expression { public: - ExpressionEqual(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionNotEqual : public Expression { public: - ExpressionNotEqual(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionNotEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionGreaterOrEqual : public Expression { public: - ExpressionGreaterOrEqual(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionGreaterOrEqual(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionGreater : public Expression { public: - ExpressionGreater(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionGreater(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionTernary : public Expression { public: - ExpressionTernary(Expression *expr1, Expression *expr2, Expression *expr3); - ValuePtr evaluate(const class Context *context) const; + ExpressionTernary(Expression *expr1, Expression *expr2, Expression *expr3); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionArray : public Expression { public: - ExpressionArray(Expression *left, Expression *right); - ValuePtr evaluate(const class Context *context) const; + ExpressionArray(Expression *left, Expression *right); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionInvert : public Expression { public: - ExpressionInvert(Expression *expr); - ValuePtr evaluate(const class Context *context) const; + ExpressionInvert(Expression *expr); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionConst : public Expression { public: - ExpressionConst(const ValuePtr &val); - ValuePtr evaluate(const class Context *) const; + ExpressionConst(const ValuePtr &val); + ValuePtr evaluate(const class Context *) const; }; class ExpressionRange : public Expression { public: - ExpressionRange(Expression *expr1, Expression *expr2); - ExpressionRange(Expression *expr1, Expression *expr2, Expression *expr3); - ValuePtr evaluate(const class Context *context) const; + ExpressionRange(Expression *expr1, Expression *expr2); + ExpressionRange(Expression *expr1, Expression *expr2, Expression *expr3); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionVector : public Expression { public: - ExpressionVector(Expression *expr); - ValuePtr evaluate(const class Context *context) const; + ExpressionVector(Expression *expr); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLookup : public Expression { public: - ExpressionLookup(const std::string &val); - ValuePtr evaluate(const class Context *context) const; + ExpressionLookup(const std::string &val); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionMember : public Expression { public: - ExpressionMember(const std::string &val, Expression *expr); - ValuePtr evaluate(const class Context *context) const; + ExpressionMember(const std::string &val, Expression *expr); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionFunction : public Expression { public: - ExpressionFunction(); - ValuePtr evaluate(const class Context *context) const; + ExpressionFunction(); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLet : public Expression { public: - ExpressionLet(); - ValuePtr evaluate(const class Context *context) const; + ExpressionLet(); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLcExpression : public Expression { public: - ExpressionLcExpression(Expression *expr); - ValuePtr evaluate(const class Context *context) const; + ExpressionLcExpression(Expression *expr); + ValuePtr evaluate(const class Context *context) const; }; class ExpressionLc : public Expression { - bool isListComprehension(); + bool isListComprehension(); public: - ExpressionLc(Expression *expr); - ExpressionLc(Expression *expr1, Expression *expr2); - ValuePtr evaluate(const class Context *context) const; + ExpressionLc(Expression *expr); + ExpressionLc(Expression *expr1, Expression *expr2); + ValuePtr evaluate(const class Context *context) const; }; From 5680dfc0e44f0bc569bbec037bdc8446d74c5db1 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 25 Nov 2014 20:41:32 +0100 Subject: [PATCH 053/263] Fix test build. --- tests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 88253bb9..6be6d4c9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -620,6 +620,7 @@ set(CORE_SOURCES ../src/calc.cc ../src/expr.cc ../src/func.cc + ../src/stackcheck.cc ../src/localscope.cc ../src/module.cc ../src/ModuleCache.cc From 259d1b64350c75eb608fa928afae9a00c9a6981a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 15:04:00 -0500 Subject: [PATCH 054/263] Initialize StackCheck for all test drivers --- tests/cgalcachetest.cc | 3 +++ tests/csgtexttest.cc | 2 ++ tests/modulecachetest.cc | 2 ++ 3 files changed, 7 insertions(+) diff --git a/tests/cgalcachetest.cc b/tests/cgalcachetest.cc index 97aa5be1..c6de48db 100644 --- a/tests/cgalcachetest.cc +++ b/tests/cgalcachetest.cc @@ -38,6 +38,7 @@ #include "CGAL_Nef_polyhedron.h" #include "GeometryEvaluator.h" #include "CGALCache.h" +#include "stackcheck.h" #ifndef _MSC_VER #include @@ -87,6 +88,8 @@ int main(int argc, char **argv) { const char *filename, *outfilename = NULL; size_t cgalcachesize = 1*1024*1024; + StackCheck::inst()->init(); + po::variables_map vm; try { vm = parse_options(argc, argv); diff --git a/tests/csgtexttest.cc b/tests/csgtexttest.cc index 70c246dc..f241b3c0 100644 --- a/tests/csgtexttest.cc +++ b/tests/csgtexttest.cc @@ -37,6 +37,7 @@ #include "builtin.h" #include "Tree.h" #include "PlatformUtils.h" +#include "stackcheck.h" #ifndef _MSC_VER #include @@ -72,6 +73,7 @@ int main(int argc, char **argv) int rc = 0; + StackCheck::inst()->init(); Builtins::instance()->initialize(); fs::path original_path = fs::current_path(); diff --git a/tests/modulecachetest.cc b/tests/modulecachetest.cc index 5531461c..f9d4b214 100644 --- a/tests/modulecachetest.cc +++ b/tests/modulecachetest.cc @@ -34,6 +34,7 @@ #include "export.h" #include "builtin.h" #include "Tree.h" +#include "stackcheck.h" #ifndef _MSC_VER #include @@ -67,6 +68,7 @@ int main(int argc, char **argv) int rc = 0; + StackCheck::inst()->init(); Builtins::instance()->initialize(); fs::path original_path = fs::current_path(); From 2644b19ce7e84613d25283ea538b549d3bea4675 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 15:05:36 -0500 Subject: [PATCH 055/263] Reimplemented serialization of expression to string after last refactoring --- src/expr.cc | 275 ++++++++++++++++++++++++++++------------------- src/expression.h | 40 +++++-- src/parser.y | 5 +- 3 files changed, 197 insertions(+), 123 deletions(-) diff --git a/src/expr.cc b/src/expr.cc index f348f4cd..b6dadc99 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -131,118 +131,11 @@ namespace /* anonymous*/ { } -bool Expression::isListComprehension() +bool Expression::isListComprehension() const { return false; } -std::string Expression::toString() const -{ - std::stringstream stream; -/* - switch (this->type) { - case EXPRESSION_TYPE_MULTIPLY: - case EXPRESSION_TYPE_DIVISION: - case EXPRESSION_TYPE_MODULO: - case EXPRESSION_TYPE_PLUS: - case EXPRESSION_TYPE_MINUS: - case EXPRESSION_TYPE_LESS: - case EXPRESSION_TYPE_GREATER: - stream << "(" << *this->children[0] << " " << this->type << " " << *this->children[1] << ")"; - break; - case EXPRESSION_TYPE_NOT: - stream << "!" << *this->children[0]; - break; - case EXPRESSION_TYPE_LOGICAL_AND: - stream << "(" << *this->children[0] << " && " << *this->children[1] << ")"; - break; - case EXPRESSION_TYPE_LOGICAL_OR: - stream << "(" << *this->children[0] << " || " << *this->children[1] << ")"; - break; - case EXPRESSION_TYPE_LESS_OR_EQUAL: - stream << "(" << *this->children[0] << " <= " << *this->children[1] << ")"; - break; - case EXPRESSION_TYPE_EQUAL: - stream << "(" << *this->children[0] << " == " << *this->children[1] << ")"; - break; - case EXPRESSION_TYPE_NOT_EQUAL: - stream << "(" << *this->children[0] << " != " << *this->children[1] << ")"; - break; - case EXPRESSION_TYPE_GREATER_OR_EQUAL: - stream << "(" << *this->children[0] << " >= " << *this->children[1] << ")"; - break; - case EXPRESSION_TYPE_TERNARY: - stream << "(" << *this->children[0] << " ? " << *this->children[1] << " : " << *this->children[2] << ")"; - break; - case EXPRESSION_TYPE_ARRAY_ACCESS: - stream << *this->children[0] << "[" << *this->children[1] << "]"; - break; - case EXPRESSION_TYPE_INVERT: - stream << "-" << *this->children[0]; - break; - case EXPRESSION_TYPE_CONST: - stream << *this->const_value; - break; - case EXPRESSION_TYPE_RANGE: - stream << "[" << *this->children[0] << " : " << *this->children[1]; - if (this->children.size() > 2) { - stream << " : " << *this->children[2]; - } - stream << "]"; - break; - case EXPRESSION_TYPE_VECTOR: - stream << "["; - for (size_t i=0; i < this->children.size(); i++) { - if (i > 0) stream << ", "; - stream << *this->children[i]; - } - stream << "]"; - break; - case EXPRESSION_TYPE_LOOKUP: - stream << this->var_name; - break; - case EXPRESSION_TYPE_MEMBER: - stream << *this->children[0] << "." << this->var_name; - break; - case EXPRESSION_TYPE_FUNCTION: - stream << this->call_funcname << "(" << this->call_arguments << ")"; - break; - case EXPRESSION_TYPE_LET: - stream << "let(" << this->call_arguments << ") " << *this->children[0]; - break; - case EXPRESSION_TYPE_LC_EXPRESSION: // list comprehension expression - //case EXPRESSION_TYPE_LC: - { - Expression const* c = this->children[0]; - - stream << "["; - - do { - if (c->call_funcname == "for") { - stream << "for(" << c->call_arguments << ") "; - c = c->children[0]; - } else if (c->call_funcname == "if") { - stream << "if(" << c->children[0] << ") "; - c = c->children[1]; - } else if (c->call_funcname == "let") { - stream << "let(" << c->call_arguments << ") "; - c = c->children[0]; - } else { - assert(false && "Illegal list comprehension element"); - } - } while (c->type == EXPRESSION_TYPE_LC); - - stream << *c << "]"; - break; - } - default: - assert(false && "Illegal expression type"); - break; - } -*/ - return stream.str(); -} - ExpressionNot::ExpressionNot(Expression *expr) : Expression(expr) { } @@ -252,6 +145,11 @@ ValuePtr ExpressionNot::evaluate(const Context *context) const return !first->evaluate(context); } +void ExpressionNot::print(std::ostream &stream) const +{ + stream << "!" << *first; +} + ExpressionLogicalAnd::ExpressionLogicalAnd(Expression *left, Expression *right) : Expression(left, right) { } @@ -261,6 +159,11 @@ ValuePtr ExpressionLogicalAnd::evaluate(const Context *context) const return this->first->evaluate(context) && this->second->evaluate(context); } +void ExpressionLogicalAnd::print(std::ostream &stream) const +{ + stream << "(" << *first << " && " << *second << ")"; +} + ExpressionLogicalOr::ExpressionLogicalOr(Expression *left, Expression *right) : Expression(left, right) { } @@ -270,6 +173,11 @@ ValuePtr ExpressionLogicalOr::evaluate(const Context *context) const return this->first->evaluate(context) || this->second->evaluate(context); } +void ExpressionLogicalOr::print(std::ostream &stream) const +{ + stream << "(" << *first << " || " << *second << ")"; +} + ExpressionMultiply::ExpressionMultiply(Expression *left, Expression *right) : Expression(left, right) { } @@ -279,6 +187,11 @@ ValuePtr ExpressionMultiply::evaluate(const Context *context) const return this->first->evaluate(context) * this->second->evaluate(context); } +void ExpressionMultiply::print(std::ostream &stream) const +{ + stream << "(" << *first << " * " << *second << ")"; +} + ExpressionDivision::ExpressionDivision(Expression *left, Expression *right) : Expression(left, right) { } @@ -288,6 +201,11 @@ ValuePtr ExpressionDivision::evaluate(const Context *context) const return this->first->evaluate(context) / this->second->evaluate(context); } +void ExpressionDivision::print(std::ostream &stream) const +{ + stream << "(" << *first << " / " << *second << ")"; +} + ExpressionModulo::ExpressionModulo(Expression *left, Expression *right) : Expression(left, right) { } @@ -297,6 +215,11 @@ ValuePtr ExpressionModulo::evaluate(const Context *context) const return this->first->evaluate(context) % this->second->evaluate(context); } +void ExpressionModulo::print(std::ostream &stream) const +{ + stream << "(" << *first << " % " << *second << ")"; +} + ExpressionPlus::ExpressionPlus(Expression *left, Expression *right) : Expression(left, right) { } @@ -306,6 +229,11 @@ ValuePtr ExpressionPlus::evaluate(const Context *context) const return this->first->evaluate(context) + this->second->evaluate(context); } +void ExpressionPlus::print(std::ostream &stream) const +{ + stream << "(" << *first << " + " << *second << ")"; +} + ExpressionMinus::ExpressionMinus(Expression *left, Expression *right) : Expression(left, right) { } @@ -315,6 +243,11 @@ ValuePtr ExpressionMinus::evaluate(const Context *context) const return this->first->evaluate(context) - this->second->evaluate(context); } +void ExpressionMinus::print(std::ostream &stream) const +{ + stream << "(" << *first << " - " << *second << ")"; +} + ExpressionLess::ExpressionLess(Expression *left, Expression *right) : Expression(left, right) { } @@ -324,6 +257,11 @@ ValuePtr ExpressionLess::evaluate(const Context *context) const return this->first->evaluate(context) < this->second->evaluate(context); } +void ExpressionLess::print(std::ostream &stream) const +{ + stream << "(" << *first << " < " << *second << ")"; +} + ExpressionLessOrEqual::ExpressionLessOrEqual(Expression *left, Expression *right) : Expression(left, right) { } @@ -333,6 +271,11 @@ ValuePtr ExpressionLessOrEqual::evaluate(const Context *context) const return this->first->evaluate(context) <= this->second->evaluate(context); } +void ExpressionLessOrEqual::print(std::ostream &stream) const +{ + stream << "(" << *first << " <= " << *second << ")"; +} + ExpressionEqual::ExpressionEqual(Expression *left, Expression *right) : Expression(left, right) { } @@ -342,6 +285,11 @@ ValuePtr ExpressionEqual::evaluate(const Context *context) const return this->first->evaluate(context) == this->second->evaluate(context); } +void ExpressionEqual::print(std::ostream &stream) const +{ + stream << "(" << *first << " == " << *second << ")"; +} + ExpressionNotEqual::ExpressionNotEqual(Expression *left, Expression *right) : Expression(left, right) { } @@ -351,6 +299,11 @@ ValuePtr ExpressionNotEqual::evaluate(const Context *context) const return this->first->evaluate(context) != this->second->evaluate(context); } +void ExpressionNotEqual::print(std::ostream &stream) const +{ + stream << "(" << *first << " != " << *second << ")"; +} + ExpressionGreaterOrEqual::ExpressionGreaterOrEqual(Expression *left, Expression *right) : Expression(left, right) { } @@ -360,6 +313,11 @@ ValuePtr ExpressionGreaterOrEqual::evaluate(const Context *context) const return this->first->evaluate(context) >= this->second->evaluate(context); } +void ExpressionGreaterOrEqual::print(std::ostream &stream) const +{ + stream << "(" << *first << " >= " << *second << ")"; +} + ExpressionGreater::ExpressionGreater(Expression *left, Expression *right) : Expression(left, right) { } @@ -369,6 +327,11 @@ ValuePtr ExpressionGreater::evaluate(const Context *context) const return this->first->evaluate(context) > this->second->evaluate(context); } +void ExpressionGreater::print(std::ostream &stream) const +{ + stream << "(" << *first << " > " << *second << ")"; +} + ExpressionTernary::ExpressionTernary(Expression *expr1, Expression *expr2, Expression *expr3) : Expression(expr1, expr2, expr3) { } @@ -378,14 +341,24 @@ ValuePtr ExpressionTernary::evaluate(const Context *context) const return (this->first->evaluate(context) ? this->second : this->third)->evaluate(context); } -ExpressionArray::ExpressionArray(Expression *left, Expression *right) : Expression(left, right) +void ExpressionTernary::print(std::ostream &stream) const +{ + stream << "(" << *first << " ? " << *second << " : " << *third << ")"; +} + +ExpressionArrayLookup::ExpressionArrayLookup(Expression *left, Expression *right) : Expression(left, right) { } -ValuePtr ExpressionArray::evaluate(const Context *context) const { +ValuePtr ExpressionArrayLookup::evaluate(const Context *context) const { return this->first->evaluate(context)[this->second->evaluate(context)]; } +void ExpressionArrayLookup::print(std::ostream &stream) const +{ + stream << *first << "[" << *second << "]"; +} + ExpressionInvert::ExpressionInvert(Expression *expr) : Expression(expr) { } @@ -395,6 +368,11 @@ ValuePtr ExpressionInvert::evaluate(const Context *context) const return -this->first->evaluate(context); } +void ExpressionInvert::print(std::ostream &stream) const +{ + stream << "-" << *first; +} + ExpressionConst::ExpressionConst(const ValuePtr &val) : Expression(val) { } @@ -404,6 +382,11 @@ ValuePtr ExpressionConst::evaluate(const class Context *) const return ValuePtr(this->const_value); } +void ExpressionConst::print(std::ostream &stream) const +{ + stream << *this->const_value; +} + ExpressionRange::ExpressionRange(Expression *expr1, Expression *expr2) : Expression(expr1, expr2) { } @@ -433,6 +416,13 @@ ValuePtr ExpressionRange::evaluate(const Context *context) const return ValuePtr::undefined; } +void ExpressionRange::print(std::ostream &stream) const +{ + stream << "[" << *first << " : " << *second; + if (this->children.size() > 2) stream << " : " << *third; + stream << "]"; +} + ExpressionVector::ExpressionVector(Expression *expr) : Expression(expr) { } @@ -446,6 +436,16 @@ ValuePtr ExpressionVector::evaluate(const Context *context) const return ValuePtr(vec); } +void ExpressionVector::print(std::ostream &stream) const +{ + stream << "["; + for (size_t i=0; i < this->children.size(); i++) { + if (i > 0) stream << ", "; + stream << *this->children[i]; + } + stream << "]"; +} + ExpressionLookup::ExpressionLookup(const std::string &val) : Expression(val) { } @@ -455,6 +455,11 @@ ValuePtr ExpressionLookup::evaluate(const Context *context) const return context->lookup_variable(this->var_name); } +void ExpressionLookup::print(std::ostream &stream) const +{ + stream << this->var_name; +} + ExpressionMember::ExpressionMember(const std::string &val, Expression *expr) : Expression(val, expr) { } @@ -475,6 +480,11 @@ ValuePtr ExpressionMember::evaluate(const Context *context) const return ValuePtr::undefined; } +void ExpressionMember::print(std::ostream &stream) const +{ + stream << *first << "." << this->var_name; +} + ExpressionFunction::ExpressionFunction() { } @@ -492,7 +502,12 @@ ValuePtr ExpressionFunction::evaluate(const Context *context) const return result; } -ExpressionLet::ExpressionLet() +void ExpressionFunction::print(std::ostream &stream) const +{ + stream << this->call_funcname << "(" << this->call_arguments << ")"; +} + +ExpressionLet::ExpressionLet(Expression *expr) : Expression(expr) { } @@ -504,6 +519,11 @@ ValuePtr ExpressionLet::evaluate(const Context *context) const return this->children[0]->evaluate(&c); } +void ExpressionLet::print(std::ostream &stream) const +{ + stream << "let(" << this->call_arguments << ") " << *first; +} + ExpressionLcExpression::ExpressionLcExpression(Expression *expr) : Expression(expr) { } @@ -513,6 +533,30 @@ ValuePtr ExpressionLcExpression::evaluate(const Context *context) const return this->children[0]->evaluate(context); } +void ExpressionLcExpression::print(std::ostream &stream) const +{ + Expression const* c = this->first; + + stream << "["; + + do { + if (c->call_funcname == "for") { + stream << "for(" << c->call_arguments << ") "; + c = c->children[0]; + } else if (c->call_funcname == "if") { + stream << "if(" << c->children[0] << ") "; + c = c->children[1]; + } else if (c->call_funcname == "let") { + stream << "let(" << c->call_arguments << ") "; + c = c->children[0]; + } else { + assert(false && "Illegal list comprehension element"); + } + } while (c->isListComprehension()); + + stream << *c << "]"; +} + ExpressionLc::ExpressionLc(Expression *expr) : Expression(expr) { } @@ -521,7 +565,7 @@ ExpressionLc::ExpressionLc(Expression *expr1, Expression *expr2) : Expression(ex { } -bool ExpressionLc::isListComprehension() +bool ExpressionLc::isListComprehension() const { return true; } @@ -587,8 +631,13 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const } } +void ExpressionLc::print(std::ostream &stream) const +{ + // FIXME: Implement? +} + std::ostream &operator<<(std::ostream &stream, const Expression &expr) { - stream << expr.toString(); + expr.print(stream); return stream; } diff --git a/src/expression.h b/src/expression.h index 08629e94..2b95ffa0 100644 --- a/src/expression.h +++ b/src/expression.h @@ -28,9 +28,9 @@ public: Expression(Expression *expr1, Expression *expr2, Expression *expr3); virtual ~Expression(); - virtual bool isListComprehension(); + virtual bool isListComprehension() const; virtual ValuePtr evaluate(const class Context *context) const = 0; - std::string toString() const; + virtual void print(std::ostream &stream) const = 0; }; std::ostream &operator<<(std::ostream &stream, const Expression &expr); @@ -39,7 +39,8 @@ class ExpressionNot : public Expression { public: ExpressionNot(Expression *expr); - ValuePtr evaluate(const class Context *context) const; + virtual ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLogicalAnd : public Expression @@ -47,6 +48,7 @@ class ExpressionLogicalAnd : public Expression public: ExpressionLogicalAnd(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLogicalOr : public Expression @@ -54,6 +56,7 @@ class ExpressionLogicalOr : public Expression public: ExpressionLogicalOr(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionMultiply : public Expression @@ -61,6 +64,7 @@ class ExpressionMultiply : public Expression public: ExpressionMultiply(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionDivision : public Expression @@ -68,6 +72,7 @@ class ExpressionDivision : public Expression public: ExpressionDivision(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionModulo : public Expression @@ -75,6 +80,7 @@ class ExpressionModulo : public Expression public: ExpressionModulo(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionPlus : public Expression @@ -82,6 +88,7 @@ class ExpressionPlus : public Expression public: ExpressionPlus(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionMinus : public Expression @@ -89,6 +96,7 @@ class ExpressionMinus : public Expression public: ExpressionMinus(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLess : public Expression @@ -96,6 +104,7 @@ class ExpressionLess : public Expression public: ExpressionLess(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLessOrEqual : public Expression @@ -103,6 +112,7 @@ class ExpressionLessOrEqual : public Expression public: ExpressionLessOrEqual(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionEqual : public Expression @@ -110,6 +120,7 @@ class ExpressionEqual : public Expression public: ExpressionEqual(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionNotEqual : public Expression @@ -117,6 +128,7 @@ class ExpressionNotEqual : public Expression public: ExpressionNotEqual(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionGreaterOrEqual : public Expression @@ -124,6 +136,7 @@ class ExpressionGreaterOrEqual : public Expression public: ExpressionGreaterOrEqual(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionGreater : public Expression @@ -131,6 +144,7 @@ class ExpressionGreater : public Expression public: ExpressionGreater(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionTernary : public Expression @@ -138,13 +152,15 @@ class ExpressionTernary : public Expression public: ExpressionTernary(Expression *expr1, Expression *expr2, Expression *expr3); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; -class ExpressionArray : public Expression +class ExpressionArrayLookup : public Expression { public: - ExpressionArray(Expression *left, Expression *right); + ExpressionArrayLookup(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionInvert : public Expression @@ -152,6 +168,7 @@ class ExpressionInvert : public Expression public: ExpressionInvert(Expression *expr); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionConst : public Expression @@ -159,6 +176,7 @@ class ExpressionConst : public Expression public: ExpressionConst(const ValuePtr &val); ValuePtr evaluate(const class Context *) const; + virtual void print(std::ostream &stream) const; }; class ExpressionRange : public Expression @@ -167,6 +185,7 @@ public: ExpressionRange(Expression *expr1, Expression *expr2); ExpressionRange(Expression *expr1, Expression *expr2, Expression *expr3); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionVector : public Expression @@ -174,6 +193,7 @@ class ExpressionVector : public Expression public: ExpressionVector(Expression *expr); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLookup : public Expression @@ -181,6 +201,7 @@ class ExpressionLookup : public Expression public: ExpressionLookup(const std::string &val); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionMember : public Expression @@ -188,6 +209,7 @@ class ExpressionMember : public Expression public: ExpressionMember(const std::string &val, Expression *expr); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionFunction : public Expression @@ -195,13 +217,15 @@ class ExpressionFunction : public Expression public: ExpressionFunction(); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLet : public Expression { public: - ExpressionLet(); + ExpressionLet(Expression *expr); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLcExpression : public Expression @@ -209,13 +233,15 @@ class ExpressionLcExpression : public Expression public: ExpressionLcExpression(Expression *expr); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; class ExpressionLc : public Expression { - bool isListComprehension(); + virtual bool isListComprehension() const; public: ExpressionLc(Expression *expr); ExpressionLc(Expression *expr1, Expression *expr2); ValuePtr evaluate(const class Context *context) const; + virtual void print(std::ostream &stream) const; }; diff --git a/src/parser.y b/src/parser.y index f1505de1..04dbdb8f 100644 --- a/src/parser.y +++ b/src/parser.y @@ -333,10 +333,9 @@ expr: } | TOK_LET '(' arguments_call ')' expr %prec LET { - $$ = new ExpressionLet(); + $$ = new ExpressionLet($5); $$->call_arguments = *$3; delete $3; - $$->children.push_back($5); } | '[' expr ':' expr ']' { @@ -432,7 +431,7 @@ expr: } | expr '[' expr ']' { - $$ = new ExpressionArray($1, $3); + $$ = new ExpressionArrayLookup($1, $3); } | TOK_ID '(' arguments_call ')' { From 32bc6ae516228b447fde5c4729e34a12167d979d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 15:06:20 -0500 Subject: [PATCH 056/263] inlined stack pointer retrieval to silence compiler warning --- src/stackcheck.cc | 6 ++++-- src/stackcheck.h | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stackcheck.cc b/src/stackcheck.cc index 5471c043..0f8ca2a8 100644 --- a/src/stackcheck.cc +++ b/src/stackcheck.cc @@ -15,12 +15,14 @@ StackCheck::~StackCheck() void StackCheck::init() { - ptr = sp(); + unsigned char c; + ptr = &c; } unsigned long StackCheck::size() { - return std::labs(ptr - sp()); + unsigned char c; + return std::labs(ptr - &c); } bool StackCheck::check() diff --git a/src/stackcheck.h b/src/stackcheck.h index 60ae5cd3..a2bfae22 100644 --- a/src/stackcheck.h +++ b/src/stackcheck.h @@ -13,8 +13,6 @@ public: unsigned long size(); private: - unsigned char * sp() { unsigned char c; return &c; }; - unsigned char * ptr; static StackCheck *self; From 8ca812ac1a126328a984956b789210dbe4b0e51e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 15:28:48 -0500 Subject: [PATCH 057/263] Added infinite module recursion test --- testdata/scad/misc/recursion-tests.scad | 3 +++ tests/regression/echotest/recursion-tests-expected.echo | 1 + 2 files changed, 4 insertions(+) diff --git a/testdata/scad/misc/recursion-tests.scad b/testdata/scad/misc/recursion-tests.scad index 2a07b915..78b31e35 100644 --- a/testdata/scad/misc/recursion-tests.scad +++ b/testdata/scad/misc/recursion-tests.scad @@ -1,2 +1,5 @@ function crash() = crash(); echo(crash()); + +module crash() crash(); +crash(); diff --git a/tests/regression/echotest/recursion-tests-expected.echo b/tests/regression/echotest/recursion-tests-expected.echo index e5c99b1e..4bf735f7 100644 --- a/tests/regression/echotest/recursion-tests-expected.echo +++ b/tests/regression/echotest/recursion-tests-expected.echo @@ -1,2 +1,3 @@ ERROR: Recursion detected calling function 'crash' ECHO: undef +ERROR: Recursion detected calling module 'crash' From d99dea1db2c8923282098d073dc1b2b4316ec890 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 15:53:44 -0500 Subject: [PATCH 058/263] bugfix after merging master - dynamic memory caused contexts not to be destructed --- src/expr.cc | 5 ++--- src/func.cc | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/expr.cc b/src/expr.cc index b6dadc99..6131984e 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -495,9 +495,8 @@ ValuePtr ExpressionFunction::evaluate(const Context *context) const throw RecursionException("function", call_funcname); } - EvalContext *c = new EvalContext(context, this->call_arguments); - ValuePtr result = context->evaluate_function(this->call_funcname, c); - delete c; + EvalContext c(context, this->call_arguments); + ValuePtr result = context->evaluate_function(this->call_funcname, &c); return result; } diff --git a/src/func.cc b/src/func.cc index 11faa327..ed03fac8 100644 --- a/src/func.cc +++ b/src/func.cc @@ -92,10 +92,9 @@ Function::~Function() ValuePtr Function::evaluate(const Context *ctx, const EvalContext *evalctx) const { if (!expr) return ValuePtr::undefined; - Context *c = new Context(ctx); - c->setVariables(definition_arguments, evalctx); - ValuePtr result = expr->evaluate(c); - delete c; + Context c(ctx); + c.setVariables(definition_arguments, evalctx); + ValuePtr result = expr->evaluate(&c); return result; } From 2e8d93d5be57ef7b57d11f7ad19b278be0798557 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 17:08:14 -0500 Subject: [PATCH 059/263] Some Expression refactoring --- src/expr.cc | 135 +++++++++++++++++++---------------------------- src/expression.h | 40 ++++++++------ src/parser.y | 22 +++----- 3 files changed, 87 insertions(+), 110 deletions(-) diff --git a/src/expr.cc b/src/expr.cc index 6131984e..77c5ac77 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -67,49 +67,27 @@ namespace { } } -Expression::Expression() +Expression::Expression() : first(NULL), second(NULL), third(NULL) { } -Expression::Expression(const ValuePtr &val) -{ - const_value = val; -} - -Expression::Expression(const std::string &val) -{ - var_name = val; -} - -Expression::Expression(const std::string &val, Expression *expr) -{ - var_name = val; - children.push_back(expr); - first = expr; -} - -Expression::Expression(Expression *expr) +Expression::Expression(Expression *expr) : first(expr), second(NULL), third(NULL) { children.push_back(expr); - first = expr; } -Expression::Expression(Expression *left, Expression *right) +Expression::Expression(Expression *left, Expression *right) : first(left), second(right), third(NULL) { children.push_back(left); children.push_back(right); - first = left; - second = right; } Expression::Expression(Expression *expr1, Expression *expr2, Expression *expr3) + : first(expr1), second(expr2), third(expr3) { children.push_back(expr1); children.push_back(expr2); children.push_back(expr3); - first = expr1; - second = expr2; - third = expr3; } Expression::~Expression() @@ -373,7 +351,7 @@ void ExpressionInvert::print(std::ostream &stream) const stream << "-" << *first; } -ExpressionConst::ExpressionConst(const ValuePtr &val) : Expression(val) +ExpressionConst::ExpressionConst(const ValuePtr &val) : const_value(val) { } @@ -446,7 +424,7 @@ void ExpressionVector::print(std::ostream &stream) const stream << "]"; } -ExpressionLookup::ExpressionLookup(const std::string &val) : Expression(val) +ExpressionLookup::ExpressionLookup(const std::string &var_name) : var_name(var_name) { } @@ -460,7 +438,8 @@ void ExpressionLookup::print(std::ostream &stream) const stream << this->var_name; } -ExpressionMember::ExpressionMember(const std::string &val, Expression *expr) : Expression(val, expr) +ExpressionMember::ExpressionMember(Expression *expr, const std::string &member) + : Expression(expr), member(member) { } @@ -469,44 +448,47 @@ ValuePtr ExpressionMember::evaluate(const Context *context) const ValuePtr v = this->first->evaluate(context); if (v->type() == Value::VECTOR) { - if (this->var_name == "x") return v[0]; - if (this->var_name == "y") return v[1]; - if (this->var_name == "z") return v[2]; + if (this->member == "x") return v[0]; + if (this->member == "y") return v[1]; + if (this->member == "z") return v[2]; } else if (v->type() == Value::RANGE) { - if (this->var_name == "begin") return v[0]; - if (this->var_name == "step") return v[1]; - if (this->var_name == "end") return v[2]; + if (this->member == "begin") return v[0]; + if (this->member == "step") return v[1]; + if (this->member == "end") return v[2]; } return ValuePtr::undefined; } void ExpressionMember::print(std::ostream &stream) const { - stream << *first << "." << this->var_name; + stream << *first << "." << this->member; } -ExpressionFunction::ExpressionFunction() +ExpressionFunctionCall::ExpressionFunctionCall(const std::string &funcname, + const AssignmentList &arglist) + : funcname(funcname), call_arguments(arglist) { } -ValuePtr ExpressionFunction::evaluate(const Context *context) const +ValuePtr ExpressionFunctionCall::evaluate(const Context *context) const { if (StackCheck::inst()->check()) { - throw RecursionException("function", call_funcname); + throw RecursionException("function", funcname); } EvalContext c(context, this->call_arguments); - ValuePtr result = context->evaluate_function(this->call_funcname, &c); + ValuePtr result = context->evaluate_function(this->funcname, &c); return result; } -void ExpressionFunction::print(std::ostream &stream) const +void ExpressionFunctionCall::print(std::ostream &stream) const { - stream << this->call_funcname << "(" << this->call_arguments << ")"; + stream << this->funcname << "(" << this->call_arguments << ")"; } -ExpressionLet::ExpressionLet(Expression *expr) : Expression(expr) +ExpressionLet::ExpressionLet(const AssignmentList &arglist, Expression *expr) + : Expression(expr), call_arguments(arglist) { } @@ -515,7 +497,7 @@ ValuePtr ExpressionLet::evaluate(const Context *context) const Context c(context); evaluate_sequential_assignment(this->call_arguments, &c); - return this->children[0]->evaluate(&c); + return this->first->evaluate(&c); } void ExpressionLet::print(std::ostream &stream) const @@ -529,38 +511,23 @@ ExpressionLcExpression::ExpressionLcExpression(Expression *expr) : Expression(ex ValuePtr ExpressionLcExpression::evaluate(const Context *context) const { - return this->children[0]->evaluate(context); + return this->first->evaluate(context); } void ExpressionLcExpression::print(std::ostream &stream) const { - Expression const* c = this->first; - - stream << "["; - - do { - if (c->call_funcname == "for") { - stream << "for(" << c->call_arguments << ") "; - c = c->children[0]; - } else if (c->call_funcname == "if") { - stream << "if(" << c->children[0] << ") "; - c = c->children[1]; - } else if (c->call_funcname == "let") { - stream << "let(" << c->call_arguments << ") "; - c = c->children[0]; - } else { - assert(false && "Illegal list comprehension element"); - } - } while (c->isListComprehension()); - - stream << *c << "]"; + stream << "[" << *this->first << "]"; } -ExpressionLc::ExpressionLc(Expression *expr) : Expression(expr) +ExpressionLc::ExpressionLc(const std::string &name, + const AssignmentList &arglist, Expression *expr) + : Expression(expr), name(name), call_arguments(arglist) { } -ExpressionLc::ExpressionLc(Expression *expr1, Expression *expr2) : Expression(expr1, expr2) +ExpressionLc::ExpressionLc(const std::string &name, + Expression *expr1, Expression *expr2) + : Expression(expr1, expr2), name(name) { } @@ -573,16 +540,16 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const { Value::VectorType vec; - if (this->call_funcname == "if") { - if (this->children[0]->evaluate(context)) { - if (this->children[1]->isListComprehension()) { - return this->children[1]->evaluate(context); + if (this->name == "if") { + if (this->first->evaluate(context)) { + if (this->second->isListComprehension()) { + return this->second->evaluate(context); } else { - vec.push_back((*this->children[1]->evaluate(context))); + vec.push_back((*this->second->evaluate(context))); } } return ValuePtr(vec); - } else if (this->call_funcname == "for") { + } else if (this->name == "for") { EvalContext for_context(context, this->call_arguments); Context assign_context(context); @@ -601,30 +568,30 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const } else { for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { c.set_variable(it_name, ValuePtr(*it)); - vec.push_back((*this->children[0]->evaluate(&c))); + vec.push_back((*this->first->evaluate(&c))); } } } else if (it_values->type() == Value::VECTOR) { for (size_t i = 0; i < it_values->toVector().size(); i++) { c.set_variable(it_name, it_values->toVector()[i]); - vec.push_back((*this->children[0]->evaluate(&c))); + vec.push_back((*this->first->evaluate(&c))); } } else if (it_values->type() != Value::UNDEFINED) { c.set_variable(it_name, it_values); - vec.push_back((*this->children[0]->evaluate(&c))); + vec.push_back((*this->first->evaluate(&c))); } - if (this->children[0]->isListComprehension()) { + if (this->first->isListComprehension()) { return ValuePtr(flatten(vec)); } else { return ValuePtr(vec); } - } else if (this->call_funcname == "let") { + } else if (this->name == "let") { Context c(context); evaluate_sequential_assignment(this->call_arguments, &c); - return this->children[0]->evaluate(&c); + return this->first->evaluate(&c); } else { abort(); } @@ -632,7 +599,15 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const void ExpressionLc::print(std::ostream &stream) const { - // FIXME: Implement? + stream << this->name; + if (this->name == "if") { + stream << "(" << *this->first << ") " << *this->second; + } + else if (this->name == "for" || this->name == "let") { + stream << "(" << this->call_arguments << ") " << *this->first; + } else { + assert(false && "Illegal list comprehension element"); + } } std::ostream &operator<<(std::ostream &stream, const Expression &expr) diff --git a/src/expression.h b/src/expression.h index 2b95ffa0..2cd1bded 100644 --- a/src/expression.h +++ b/src/expression.h @@ -13,16 +13,7 @@ public: Expression *second; Expression *third; - ValuePtr const_value; - std::string var_name; - - std::string call_funcname; - AssignmentList call_arguments; - Expression(); - Expression(const ValuePtr &val); - Expression(const std::string &val); - Expression(const std::string &val, Expression *expr); Expression(Expression *expr); Expression(Expression *left, Expression *right); Expression(Expression *expr1, Expression *expr2, Expression *expr3); @@ -161,6 +152,7 @@ public: ExpressionArrayLookup(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: }; class ExpressionInvert : public Expression @@ -177,6 +169,8 @@ public: ExpressionConst(const ValuePtr &val); ValuePtr evaluate(const class Context *) const; virtual void print(std::ostream &stream) const; +private: + ValuePtr const_value; }; class ExpressionRange : public Expression @@ -199,33 +193,42 @@ public: class ExpressionLookup : public Expression { public: - ExpressionLookup(const std::string &val); + ExpressionLookup(const std::string &var_name); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + std::string var_name; }; class ExpressionMember : public Expression { public: - ExpressionMember(const std::string &val, Expression *expr); + ExpressionMember(Expression *expr, const std::string &member); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + std::string member; }; -class ExpressionFunction : public Expression +class ExpressionFunctionCall : public Expression { public: - ExpressionFunction(); + ExpressionFunctionCall(const std::string &funcname, const AssignmentList &arglist); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +public: + std::string funcname; + AssignmentList call_arguments; }; class ExpressionLet : public Expression { public: - ExpressionLet(Expression *expr); + ExpressionLet(const AssignmentList &arglist, Expression *expr); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + AssignmentList call_arguments; }; class ExpressionLcExpression : public Expression @@ -240,8 +243,13 @@ class ExpressionLc : public Expression { virtual bool isListComprehension() const; public: - ExpressionLc(Expression *expr); - ExpressionLc(Expression *expr1, Expression *expr2); + ExpressionLc(const std::string &name, + const AssignmentList &arglist, Expression *expr); + ExpressionLc(const std::string &name, + Expression *expr1, Expression *expr2); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + std::string name; + AssignmentList call_arguments; }; diff --git a/src/parser.y b/src/parser.y index 04dbdb8f..dfa1ab2e 100644 --- a/src/parser.y +++ b/src/parser.y @@ -319,7 +319,7 @@ expr: } | expr '.' TOK_ID { - $$ = new ExpressionMember($3, $1); + $$ = new ExpressionMember($1, $3); free($3); } | TOK_STRING @@ -333,8 +333,7 @@ expr: } | TOK_LET '(' arguments_call ')' expr %prec LET { - $$ = new ExpressionLet($5); - $$->call_arguments = *$3; + $$ = new ExpressionLet(*$3, $5); delete $3; } | '[' expr ':' expr ']' @@ -435,9 +434,7 @@ expr: } | TOK_ID '(' arguments_call ')' { - $$ = new ExpressionFunction(); - $$->call_funcname = $1; - $$->call_arguments = *$3; + $$ = new ExpressionFunctionCall($1, *$3); free($1); delete $3; } @@ -448,9 +445,7 @@ list_comprehension_elements: be parsed as an expression) */ TOK_LET '(' arguments_call ')' list_comprehension_elements { - $$ = new ExpressionLc($5); - $$->call_funcname = "let"; - $$->call_arguments = *$3; + $$ = new ExpressionLc("let", *$3, $5); delete $3; } | TOK_FOR '(' arguments_call ')' list_comprehension_elements_or_expr @@ -459,17 +454,16 @@ list_comprehension_elements: /* transform for(i=...,j=...) -> for(i=...) for(j=...) */ for (int i = $3->size()-1; i >= 0; i--) { - Expression *e = new ExpressionLc($$); - e->call_funcname = "for"; - e->call_arguments.push_back((*$3)[i]); + AssignmentList arglist; + arglist.push_back((*$3)[i]); + Expression *e = new ExpressionLc("for", arglist, $$); $$ = e; } delete $3; } | TOK_IF '(' expr ')' list_comprehension_elements_or_expr { - $$ = new ExpressionLc($3, $5); - $$->call_funcname = "if"; + $$ = new ExpressionLc("if", $3, $5); } ; From 0b58b7d2b348e7dd7eafa56b596e543bace68945 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 26 Nov 2014 15:02:44 -0500 Subject: [PATCH 060/263] Compile fix: Don't include Carbon as it pollutes the global namespace with e.g. 'Polygon' --- src/AppleEvents.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AppleEvents.cc b/src/AppleEvents.cc index 92585de6..f1e7d0da 100644 --- a/src/AppleEvents.cc +++ b/src/AppleEvents.cc @@ -1,4 +1,6 @@ -#include +#include +#include +#include #include #include "MainWindow.h" From 819f5d085f009152f4aa75b451895b8d240c9059 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 26 Nov 2014 15:22:15 -0500 Subject: [PATCH 061/263] Moved Polygon typedef out of PolySet class --- src/GeometryEvaluator.cc | 4 ++-- src/cgal.h | 1 + src/cgalutils.cc | 8 ++++---- src/export.cc | 2 +- src/linalg.h | 3 +++ src/polyset-utils.cc | 10 +++++----- src/polyset.cc | 2 +- src/polyset.h | 3 +-- 8 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 5e82897f..8db1d5fb 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -573,7 +573,7 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node) static void translate_PolySet(PolySet &ps, const Vector3d &translation) { - BOOST_FOREACH(PolySet::Polygon &p, ps.polygons) { + BOOST_FOREACH(Polygon &p, ps.polygons) { BOOST_FOREACH(Vector3d &v, p) { v += translation; } @@ -651,7 +651,7 @@ static Geometry *extrudePolygon(const LinearExtrudeNode &node, const Polygon2d & PolySet *ps_bottom = poly.tessellate(); // bottom // Flip vertex ordering for bottom polygon - BOOST_FOREACH(PolySet::Polygon &p, ps_bottom->polygons) { + BOOST_FOREACH(Polygon &p, ps_bottom->polygons) { std::reverse(p.begin(), p.end()); } translate_PolySet(*ps_bottom, Vector3d(0,0,h1)); diff --git a/src/cgal.h b/src/cgal.h index 3d096d6c..75054f91 100644 --- a/src/cgal.h +++ b/src/cgal.h @@ -62,6 +62,7 @@ typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; typedef CGAL::Point_3 CGAL_Point_3; typedef CGAL::Iso_cuboid_3 CGAL_Iso_cuboid_3; +typedef std::vector CGAL_Polygon_3; // CGAL_Nef_polyhedron2 uses CGAL_Kernel2, but Iso_rectangle_2 needs to match // CGAL_Nef_polyhedron2::Explorer::Point which is different than diff --git a/src/cgalutils.cc b/src/cgalutils.cc index dd156720..a609bd63 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -67,7 +67,7 @@ namespace /* anonymous */ { Grid3d grid(GRID_FINE); std::vector indices(3); - BOOST_FOREACH(const PolySet::Polygon &p, ps.polygons) { + BOOST_FOREACH(const Polygon &p, ps.polygons) { BOOST_REVERSE_FOREACH(Vector3d v, p) { if (!grid.has(v[0], v[1], v[2])) { // align v to the grid; the CGALPoint will receive the aligned vertex @@ -85,7 +85,7 @@ namespace /* anonymous */ { BOOST_FOREACH(const CGALPoint &p, vertices) { B.add_vertex(p); } - BOOST_FOREACH(const PolySet::Polygon &p, ps.polygons) { + BOOST_FOREACH(const Polygon &p, ps.polygons) { #ifdef GEN_SURFACE_DEBUG if (pidx++ > 0) printf(","); #endif @@ -148,7 +148,7 @@ namespace /* anonymous */ { #ifdef GEN_SURFACE_DEBUG printf("polyhedron(faces=["); #endif - BOOST_FOREACH(const PolySet::Polygon &p, ps.polygons) { + BOOST_FOREACH(const Polygon &p, ps.polygons) { #ifdef GEN_SURFACE_DEBUG if (pidx++ > 0) printf(","); #endif @@ -373,7 +373,7 @@ namespace CGALUtils { } else { const PolySet *ps = dynamic_cast(chgeom.get()); if (ps) { - BOOST_FOREACH(const PolySet::Polygon &p, ps->polygons) { + BOOST_FOREACH(const Polygon &p, ps->polygons) { BOOST_FOREACH(const Vector3d &v, p) { points.insert(K::Point_3(v[0], v[1], v[2])); } diff --git a/src/export.cc b/src/export.cc index 1da18a74..7f0331d1 100644 --- a/src/export.cc +++ b/src/export.cc @@ -133,7 +133,7 @@ void export_stl(const PolySet &ps, std::ostream &output) setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output output << "solid OpenSCAD_Model\n"; - BOOST_FOREACH(const PolySet::Polygon &p, triangulated.polygons) { + BOOST_FOREACH(const Polygon &p, triangulated.polygons) { assert(p.size() == 3); // STL only allows triangles std::stringstream stream; stream << p[0][0] << " " << p[0][1] << " " << p[0][2]; diff --git a/src/linalg.h b/src/linalg.h index 69fe316f..9e7d9f94 100644 --- a/src/linalg.h +++ b/src/linalg.h @@ -17,6 +17,9 @@ using Eigen::Matrix4d; #define Transform3d Eigen::Affine3d #define Transform2d Eigen::Affine2d +typedef std::vector Polygon; +typedef std::vector Polygons; + bool matrix_contains_infinity( const Transform3d &m ); bool matrix_contains_nan( const Transform3d &m ); diff --git a/src/polyset-utils.cc b/src/polyset-utils.cc index e830d0ae..b55dfc4d 100644 --- a/src/polyset-utils.cc +++ b/src/polyset-utils.cc @@ -32,7 +32,7 @@ namespace PolysetUtils { Polygon2d *project(const PolySet &ps) { Polygon2d *poly = new Polygon2d; - BOOST_FOREACH(const PolySet::Polygon &p, ps.polygons) { + BOOST_FOREACH(const Polygon &p, ps.polygons) { Outline2d outline; BOOST_FOREACH(const Vector3d &v, p) { outline.vertices.push_back(Vector2d(v[0], v[1])); @@ -65,12 +65,12 @@ namespace PolysetUtils { void tessellate_faces(const PolySet &inps, PolySet &outps) { int degeneratePolygons = 0; for (size_t i = 0; i < inps.polygons.size(); i++) { - const PolySet::Polygon pgon = inps.polygons[i]; + const Polygon pgon = inps.polygons[i]; if (pgon.size() < 3) { degeneratePolygons++; continue; } - std::vector triangles; + std::vector triangles; if (pgon.size() == 3) { triangles.push_back(pgon); } @@ -98,7 +98,7 @@ namespace PolysetUtils { // Iterate over the resulting faces CDT::Finite_faces_iterator fit; for (fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end(); fit++) { - PolySet::Polygon pgon; + Polygon pgon; for (int i=0;i<3;i++) { K::Point_3 v = cdt.triangle(fit)[i]; pgon.push_back(Vector3d(v.x(), v.y(), v.z())); @@ -109,7 +109,7 @@ namespace PolysetUtils { // ..and pass to the output polyhedron for (size_t j=0;j *borders_p = &polygons; + const Polygons *borders_p = &polygons; for (size_t i = 0; i < borders_p->size(); i++) { const Polygon *poly = &borders_p->at(i); for (size_t j = 1; j <= poly->size(); j++) { diff --git a/src/polyset.h b/src/polyset.h index 91d17453..5701137d 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -14,8 +14,7 @@ BOOST_TRIBOOL_THIRD_STATE(unknown) class PolySet : public Geometry { public: - typedef std::vector Polygon; - std::vector polygons; + Polygons polygons; PolySet(unsigned int dim, boost::tribool convex = unknown); PolySet(const Polygon2d &origin); From a8204870326af439e8b607b16d0dade40c661649 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Wed, 26 Nov 2014 22:53:10 +0100 Subject: [PATCH 062/263] Simple implementation of tail-recursion elimination. --- src/context.cc | 7 ++++++ src/context.h | 1 + src/func.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/function.h | 5 +++- src/parser.y | 4 +--- 5 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/context.cc b/src/context.cc index 74dfc3cd..567cdbca 100644 --- a/src/context.cc +++ b/src/context.cc @@ -121,6 +121,13 @@ void Context::set_constant(const std::string &name, const Value &value) set_constant(name, ValuePtr(value)); } +void Context::apply_variables(const Context &other) +{ + for (ValueMap::const_iterator it = other.variables.begin();it != other.variables.end();it++) { + set_variable((*it).first, (*it).second); + } +} + ValuePtr Context::lookup_variable(const std::string &name, bool silent) const { if (!this->ctx_stack) { diff --git a/src/context.h b/src/context.h index 696eaa85..f3b1bcc0 100644 --- a/src/context.h +++ b/src/context.h @@ -26,6 +26,7 @@ public: void set_constant(const std::string &name, const ValuePtr &value); void set_constant(const std::string &name, const Value &value); + void apply_variables(const Context &other); ValuePtr lookup_variable(const std::string &name, bool silent = false) const; bool has_local_variable(const std::string &name) const; diff --git a/src/func.cc b/src/func.cc index ed03fac8..96a7b887 100644 --- a/src/func.cc +++ b/src/func.cc @@ -84,6 +84,11 @@ std::string AbstractFunction::dump(const std::string &indent, const std::string return dump.str(); } +Function::Function(const char *name, AssignmentList &definition_arguments, Expression *expr) + : name(name), definition_arguments(definition_arguments), expr(expr) +{ +} + Function::~Function() { delete expr; @@ -113,6 +118,66 @@ std::string Function::dump(const std::string &indent, const std::string &name) c return dump.str(); } +class FunctionTailRecursion : public Function +{ +private: + bool invert; + ExpressionFunctionCall *call; // memory owned by the main expression + Expression *endexpr; // memory owned by the main expression + +public: + FunctionTailRecursion(const char *name, AssignmentList &definition_arguments, Expression *expr, ExpressionFunctionCall *call, Expression *endexpr, bool invert); + virtual ~FunctionTailRecursion(); + + virtual ValuePtr evaluate(const Context *ctx, const EvalContext *evalctx) const; +}; + +FunctionTailRecursion::FunctionTailRecursion(const char *name, AssignmentList &definition_arguments, Expression *expr, ExpressionFunctionCall *call, Expression *endexpr, bool invert) + : Function(name, definition_arguments, expr), invert(invert), call(call), endexpr(endexpr) +{ +} + +FunctionTailRecursion::~FunctionTailRecursion() +{ +} + +ValuePtr FunctionTailRecursion::evaluate(const Context *ctx, const EvalContext *evalctx) const +{ + if (!expr) return ValuePtr::undefined; + + Context c(ctx); + c.setVariables(definition_arguments, evalctx); + + EvalContext ec(&c, call->call_arguments); + while (invert ^ expr->first->evaluate(&c)) { + Context tmp; + tmp.setVariables(definition_arguments, &ec); + c.apply_variables(tmp); + } + + ValuePtr result = endexpr->evaluate(&c); + + return result; +} + +Function * Function::create(const char *name, AssignmentList &definition_arguments, Expression *expr) +{ + if (dynamic_cast(expr)) { + ExpressionFunctionCall *f1 = dynamic_cast(expr->second); + ExpressionFunctionCall *f2 = dynamic_cast(expr->third); + if (f1 && !f2) { + if (name == f1->funcname) { + return new FunctionTailRecursion(name, definition_arguments, expr, f1, expr->third, false); + } + } else if (f2 && !f1) { + if (name == f2->funcname) { + return new FunctionTailRecursion(name, definition_arguments, expr, f2, expr->second, true); + } + } + } + return new Function(name, definition_arguments, expr); +} + BuiltinFunction::~BuiltinFunction() { } diff --git a/src/function.h b/src/function.h index 48496518..c9449c74 100644 --- a/src/function.h +++ b/src/function.h @@ -38,13 +38,16 @@ public: class Function : public AbstractFunction { public: + std::string name; AssignmentList definition_arguments; Expression *expr; - Function() { } + Function(const char *name, AssignmentList &definition_arguments, Expression *expr); virtual ~Function(); virtual ValuePtr evaluate(const Context *ctx, const EvalContext *evalctx) const; virtual std::string dump(const std::string &indent, const std::string &name) const; + + static Function * create(const char *name, AssignmentList &definition_arguments, Expression *expr); }; diff --git a/src/parser.y b/src/parser.y index dfa1ab2e..73c07504 100644 --- a/src/parser.y +++ b/src/parser.y @@ -166,9 +166,7 @@ statement: } | TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr { - Function *func = new Function(); - func->definition_arguments = *$4; - func->expr = $8; + Function *func = Function::create($2, *$4, $8); scope_stack.top()->functions[$2] = func; free($2); delete $4; From 4d6db2caa75fc6c2277e27235f8a87d63fed8e3f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 15:27:09 -0500 Subject: [PATCH 063/263] fixes crash when intersecting 3 or more 2d objects which results in an empty polygon --- src/GeometryEvaluator.cc | 8 ++++++-- src/clipper-utils.cc | 22 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 8db1d5fb..0f50141c 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -88,8 +88,12 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren(const Abstrac } } } - if (dim == 2) return ResultObject(applyToChildren2D(node, op)); - else if (dim == 3) return applyToChildren3D(node, op); + if (dim == 2) { + Polygon2d *p2d = applyToChildren2D(node, op); + assert(!p2d || !p2d->isEmpty()); + return ResultObject(p2d); + } + else if (dim == 3) return applyToChildren3D(node, op); return ResultObject(); } diff --git a/src/clipper-utils.cc b/src/clipper-utils.cc index f960b530..8754f578 100644 --- a/src/clipper-utils.cc +++ b/src/clipper-utils.cc @@ -81,12 +81,19 @@ namespace ClipperUtils { return result; } + /*! + Apply the clipper operator to the given paths. + + Returns a Polygon2d, or NULL if the result is empty. + + NB! Will not return an empty Polygon2d. + */ Polygon2d *apply(const std::vector &pathsvector, ClipperLib::ClipType clipType) { ClipperLib::Clipper clipper; - if (clipType == ClipperLib::ctIntersection && pathsvector.size() > 2) { + if (clipType == ClipperLib::ctIntersection && pathsvector.size() >= 2) { // intersection operations must be split into a sequence of binary operations ClipperLib::Paths source = pathsvector[0]; ClipperLib::PolyTree result; @@ -99,7 +106,7 @@ namespace ClipperUtils { clipper.Clear(); } } - return ClipperUtils::toPolygon2d(result); + return (result.Total() == 0) ? NULL : ClipperUtils::toPolygon2d(result); } bool first = true; @@ -116,6 +123,13 @@ namespace ClipperUtils { return ClipperUtils::toPolygon2d(sumresult); } + /*! + Apply the clipper operator to the given polygons. + + Returns a Polygon2d, or NULL if the result is empty. + + NB! Will not return an empty Polygon2d. + */ Polygon2d *apply(const std::vector &polygons, ClipperLib::ClipType clipType) { @@ -125,7 +139,9 @@ namespace ClipperUtils { if (!polygon->isSanitized()) ClipperLib::PolyTreeToPaths(sanitize(polypaths), polypaths); pathsvector.push_back(polypaths); } - return apply(pathsvector, clipType); + Polygon2d *res = apply(pathsvector, clipType); + assert(!res || !res->isEmpty()); + return res; } From 1b9d62c9070546674676bf201f792635a8e479ce Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 17:19:01 -0500 Subject: [PATCH 064/263] Added test for mixing empty 2D and 3D objects --- testdata/scad/3D/features/2d-3d.scad | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/testdata/scad/3D/features/2d-3d.scad b/testdata/scad/3D/features/2d-3d.scad index ca9f9663..b2dbd66b 100644 --- a/testdata/scad/3D/features/2d-3d.scad +++ b/testdata/scad/3D/features/2d-3d.scad @@ -1,3 +1,9 @@ // Test a mix of toplevel 2D and 3D objects cube(); translate([2,0,0]) square(); + +// Test mixing of empty 2D and 3D objects +union() { + cube(0); + circle(0); +} From 23f1c4ac3fa8bcf6b85788aa2a4e191b85081699 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 17:21:23 -0500 Subject: [PATCH 065/263] Updated test results --- tests/regression/dumptest/2d-3d-expected.csg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/regression/dumptest/2d-3d-expected.csg b/tests/regression/dumptest/2d-3d-expected.csg index a2f6422c..06daccb7 100644 --- a/tests/regression/dumptest/2d-3d-expected.csg +++ b/tests/regression/dumptest/2d-3d-expected.csg @@ -3,4 +3,8 @@ group() { multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { square(size = [1, 1], center = false); } + union() { + cube(size = [0, 0, 0], center = false); + circle($fn = 0, $fa = 12, $fs = 2, r = 0); + } } From 096ba7026d21fd4e48aa3863c8575bd6f545b0b2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 18:52:23 -0500 Subject: [PATCH 066/263] Added test for dxf file not found --- testdata/scad/templates/import_dxf-tests-template.scad | 1 + tests/regression/dumptest/import_dxf-tests-expected.csg | 1 + 2 files changed, 2 insertions(+) diff --git a/testdata/scad/templates/import_dxf-tests-template.scad b/testdata/scad/templates/import_dxf-tests-template.scad index 1a8b0df5..396ce1ef 100644 --- a/testdata/scad/templates/import_dxf-tests-template.scad +++ b/testdata/scad/templates/import_dxf-tests-template.scad @@ -1,4 +1,5 @@ import(); +import("notfound.dxf"); translate([-210,0,0]) import(file="../../../dxf/polygons.dxf"); translate([-210,0,0]) import(file="../../../dxf/polygons.dxf", origin=[0,110]); translate([-210,0,0]) import(file="../../../dxf/polygons.dxf", origin=[110,110], scale=0.5); diff --git a/tests/regression/dumptest/import_dxf-tests-expected.csg b/tests/regression/dumptest/import_dxf-tests-expected.csg index 2148ea74..1defde00 100644 --- a/tests/regression/dumptest/import_dxf-tests-expected.csg +++ b/tests/regression/dumptest/import_dxf-tests-expected.csg @@ -1,5 +1,6 @@ group() { import(file = "", layer = "", origin = [0, 0], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 2); + import(file = "notfound.dxf", layer = "", origin = [0, 0], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 2); multmatrix([[1, 0, 0, -210], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { import(file = "../../../dxf/polygons.dxf", layer = "", origin = [0, 0], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 2); } From 9c628225aa0bb07aabea3190793b38c18cf895ee Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 19:09:54 -0500 Subject: [PATCH 067/263] Added some nullspace tests --- testdata/scad/2D/features/nullspace-2d.scad | 6 ++++++ .../cgalpngtest/nullspace-2d-expected.png | Bin 0 -> 4408 bytes .../dumptest/nullspace-2d-expected.csg | 9 +++++++++ .../opencsgtest/nullspace-2d-expected.png | Bin 0 -> 4408 bytes .../throwntogethertest/nullspace-2d-expected.png | Bin 0 -> 4408 bytes 5 files changed, 15 insertions(+) create mode 100644 testdata/scad/2D/features/nullspace-2d.scad create mode 100644 tests/regression/cgalpngtest/nullspace-2d-expected.png create mode 100644 tests/regression/dumptest/nullspace-2d-expected.csg create mode 100644 tests/regression/opencsgtest/nullspace-2d-expected.png create mode 100644 tests/regression/throwntogethertest/nullspace-2d-expected.png diff --git a/testdata/scad/2D/features/nullspace-2d.scad b/testdata/scad/2D/features/nullspace-2d.scad new file mode 100644 index 00000000..278981c3 --- /dev/null +++ b/testdata/scad/2D/features/nullspace-2d.scad @@ -0,0 +1,6 @@ +translate() square(0); + +translate() { + square(0); + circle(0); +} diff --git a/tests/regression/cgalpngtest/nullspace-2d-expected.png b/tests/regression/cgalpngtest/nullspace-2d-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..08ee92b2216f45ca6b83efbc3b78c9fdabf45a71 GIT binary patch literal 4408 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(1_puuo-U3d6^w7MGV(Gg@Gv_b z*za4?v*2+)UsdcS+v4fU4h;;A^A5apoi>Akk%?tr1LFsF77l?9E{TSWk4eG`4hI;1 z0L3|6Sa}?_RBYrFP)K0-15&w&iA^DD&kdkj1BSW=phzGivw&_~4p6NGgFVR96%C9X zV)|x4wLA^-3JwhpAqN;-y2WP$)v_Jn7f^6e&`MxfbhO(SsGIo#JBNURfT#h(#Yacg z92$VmU>Akk%?tr1LFsF77l?9E{TSWk4eG`4hI;1 z0L3|6Sa}?_RBYrFP)K0-15&w&iA^DD&kdkj1BSW=phzGivw&_~4p6NGgFVR96%C9X zV)|x4wLA^-3JwhpAqN;-y2WP$)v_Jn7f^6e&`MxfbhO(SsGIo#JBNURfT#h(#Yacg z92$VmU>Akk%?tr1LFsF77l?9E{TSWk4eG`4hI;1 z0L3|6Sa}?_RBYrFP)K0-15&w&iA^DD&kdkj1BSW=phzGivw&_~4p6NGgFVR96%C9X zV)|x4wLA^-3JwhpAqN;-y2WP$)v_Jn7f^6e&`MxfbhO(SsGIo#JBNURfT#h(#Yacg z92$VmU> Date: Thu, 27 Nov 2014 19:19:02 -0500 Subject: [PATCH 068/263] Added surface not found tests --- testdata/scad/3D/features/surface-tests.scad | 2 ++ tests/regression/dumptest/surface-tests-expected.csg | 2 ++ 2 files changed, 4 insertions(+) diff --git a/testdata/scad/3D/features/surface-tests.scad b/testdata/scad/3D/features/surface-tests.scad index 5a67293d..5462f7b3 100644 --- a/testdata/scad/3D/features/surface-tests.scad +++ b/testdata/scad/3D/features/surface-tests.scad @@ -1,2 +1,4 @@ surface(); +surface("notfound.dat"); +surface("notfound.png"); surface("surface.dat", center=true); diff --git a/tests/regression/dumptest/surface-tests-expected.csg b/tests/regression/dumptest/surface-tests-expected.csg index a1ec6358..d731e9a9 100644 --- a/tests/regression/dumptest/surface-tests-expected.csg +++ b/tests/regression/dumptest/surface-tests-expected.csg @@ -1,4 +1,6 @@ group() { surface(file = "", center = false, invert = false); + surface(file = "notfound.dat", center = false, invert = false); + surface(file = "notfound.png", center = false, invert = false); surface(file = "surface.dat", center = true, invert = false); } From 1cca6c088a9d9c9a44821a97b260f60c9c0e8765 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 20:22:18 -0500 Subject: [PATCH 069/263] Added tests for empty text results --- testdata/scad/experimental/text-empty-tests.scad | 2 ++ tests/CMakeLists.txt | 4 +++- .../cgalpngtest/text-empty-tests-expected.png | Bin 0 -> 4408 bytes .../dumptest/text-empty-tests-expected.csg | 4 ++++ .../opencsgtest/text-empty-tests-expected.png | Bin 0 -> 4408 bytes .../text-empty-tests-expected.png | Bin 0 -> 4408 bytes 6 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 testdata/scad/experimental/text-empty-tests.scad create mode 100644 tests/regression/cgalpngtest/text-empty-tests-expected.png create mode 100644 tests/regression/dumptest/text-empty-tests-expected.csg create mode 100644 tests/regression/opencsgtest/text-empty-tests-expected.png create mode 100644 tests/regression/throwntogethertest/text-empty-tests-expected.png diff --git a/testdata/scad/experimental/text-empty-tests.scad b/testdata/scad/experimental/text-empty-tests.scad new file mode 100644 index 00000000..00a7134f --- /dev/null +++ b/testdata/scad/experimental/text-empty-tests.scad @@ -0,0 +1,2 @@ +text(); +text(""); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2d5f05f1..c105a013 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1119,8 +1119,10 @@ list(APPEND EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/3D/features ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad) disable_tests( - # This doesn't output anything + # These don't output anything + dxfpngtest_text-empty-tests dxfpngtest_nothing-decimal-comma-separated + dxfpngtest_nullspace-2d # Not useful throwntogethertest_internal-cavity diff --git a/tests/regression/cgalpngtest/text-empty-tests-expected.png b/tests/regression/cgalpngtest/text-empty-tests-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..08ee92b2216f45ca6b83efbc3b78c9fdabf45a71 GIT binary patch literal 4408 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(1_puuo-U3d6^w7MGV(Gg@Gv_b z*za4?v*2+)UsdcS+v4fU4h;;A^A5apoi>Akk%?tr1LFsF77l?9E{TSWk4eG`4hI;1 z0L3|6Sa}?_RBYrFP)K0-15&w&iA^DD&kdkj1BSW=phzGivw&_~4p6NGgFVR96%C9X zV)|x4wLA^-3JwhpAqN;-y2WP$)v_Jn7f^6e&`MxfbhO(SsGIo#JBNURfT#h(#Yacg z92$VmU>Akk%?tr1LFsF77l?9E{TSWk4eG`4hI;1 z0L3|6Sa}?_RBYrFP)K0-15&w&iA^DD&kdkj1BSW=phzGivw&_~4p6NGgFVR96%C9X zV)|x4wLA^-3JwhpAqN;-y2WP$)v_Jn7f^6e&`MxfbhO(SsGIo#JBNURfT#h(#Yacg z92$VmU>Akk%?tr1LFsF77l?9E{TSWk4eG`4hI;1 z0L3|6Sa}?_RBYrFP)K0-15&w&iA^DD&kdkj1BSW=phzGivw&_~4p6NGgFVR96%C9X zV)|x4wLA^-3JwhpAqN;-y2WP$)v_Jn7f^6e&`MxfbhO(SsGIo#JBNURfT#h(#Yacg z92$VmU> Date: Thu, 27 Nov 2014 20:37:40 -0500 Subject: [PATCH 070/263] createGeometry() should never return NULL --- src/primitives.cc | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/primitives.cc b/src/primitives.cc index a5045f86..873fedf5 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -544,8 +544,8 @@ Geometry *PrimitiveNode::createGeometry() const o.vertices[2] = v2; o.vertices[3] = Vector2d(v1[0], v2[1]); p->addOutline(o); - p->setSanitized(true); } + p->setSanitized(true); } break; case CIRCLE: { @@ -561,8 +561,8 @@ Geometry *PrimitiveNode::createGeometry() const o.vertices[i] = Vector2d(this->r1*cos(phi), this->r1*sin(phi)); } p->addOutline(o); - p->setSanitized(true); } + p->setSanitized(true); } break; case POLYGON: { @@ -574,12 +574,10 @@ Geometry *PrimitiveNode::createGeometry() const const Value::VectorType &vec = this->points.toVector(); for (unsigned int i=0;ioutlines().size() == 0) { - delete p; - g = NULL; - } - else { + if (p->outlines().size() > 0) { p->setConvexity(convexity); } } From 91139402ea7e4e7a3f7d218a3af3467b67b47526 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 20:38:09 -0500 Subject: [PATCH 071/263] toPolygon2d() should never return NULL --- src/dxfdata.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/dxfdata.cc b/src/dxfdata.cc index e9e83506..b749df9c 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -588,6 +588,9 @@ std::string DxfData::dump() const return out.str(); } +/* + May return an empty polygon, but will not return NULL + */ Polygon2d *DxfData::toPolygon2d() const { Polygon2d *poly = new Polygon2d(); @@ -602,9 +605,5 @@ Polygon2d *DxfData::toPolygon2d() const } poly->addOutline(outline); } - if (poly->outlines().size() == 0) { - delete poly; - poly = NULL; - } return poly; } From c2775d454125211579cd5e4d776def9ce225498e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 20:38:53 -0500 Subject: [PATCH 072/263] doc --- src/Polygon2d.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Polygon2d.cc b/src/Polygon2d.cc index 9218aae5..8152c7f9 100644 --- a/src/Polygon2d.cc +++ b/src/Polygon2d.cc @@ -11,7 +11,8 @@ We can store sanitized vs. unsanitized polygons. Sanitized polygons will have opposite winding order for holes and is guaranteed to not - have intersecting geometry. Sanitization is typically done by ClipperUtils. + have intersecting geometry. Sanitization is typically done by ClipperUtils, but + if you create geometry which you know is sanitized, the flag can be set manually. */ size_t Polygon2d::memsize() const From fac2340989564cb03ad6688317e7e49ef156b43c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 20:40:37 -0500 Subject: [PATCH 073/263] More correct handling of empty geometry. Should fix a few crash bugs --- src/GeometryEvaluator.cc | 20 +++++++++++++------- src/clipper-utils.cc | 13 ++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 0f50141c..71b52a81 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -90,7 +90,7 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren(const Abstrac } if (dim == 2) { Polygon2d *p2d = applyToChildren2D(node, op); - assert(!p2d || !p2d->isEmpty()); + assert(p2d); return ResultObject(p2d); } else if (dim == 3) return applyToChildren3D(node, op); @@ -129,10 +129,16 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const Abstr } + +/*! + Apply 2D hull. + + May return an empty geometry but will not return NULL. +*/ Polygon2d *GeometryEvaluator::applyHull2D(const AbstractNode &node) { std::vector children = collectChildren2D(node); - Polygon2d *geometry = NULL; + Polygon2d *geometry = new Polygon2d(); typedef CGAL::Point_2 > CGALPoint2; // Collect point cloud @@ -154,7 +160,6 @@ Polygon2d *GeometryEvaluator::applyHull2D(const AbstractNode &node) BOOST_FOREACH(const CGALPoint2 &p, result) { outline.vertices.push_back(Vector2d(p[0], p[1])); } - geometry = new Polygon2d(); geometry->addOutline(outline); } return geometry; @@ -275,12 +280,12 @@ Geometry::ChildList GeometryEvaluator::collectChildren3D(const AbstractNode &nod smartCacheInsert(*chnode, chgeom); if (chgeom) { - if (chgeom->isEmpty() || chgeom->getDimension() == 3) { - children.push_back(item); - } - else { + if (chgeom->getDimension() == 2) { PRINT("WARNING: Ignoring 2D child object for 3D operation"); } + else if (chgeom->isEmpty() || chgeom->getDimension() == 3) { + children.push_back(item); + } } } return children; @@ -447,6 +452,7 @@ Response GeometryEvaluator::visit(State &state, const LeafNode &node) shared_ptr geom; if (!isSmartCached(node)) { const Geometry *geometry = node.createGeometry(); + assert(geometry); if (const Polygon2d *polygon = dynamic_cast(geometry)) { if (!polygon->isSanitized()) { Polygon2d *p = ClipperUtils::sanitize(*polygon); diff --git a/src/clipper-utils.cc b/src/clipper-utils.cc index 8754f578..7b1c1463 100644 --- a/src/clipper-utils.cc +++ b/src/clipper-utils.cc @@ -84,9 +84,7 @@ namespace ClipperUtils { /*! Apply the clipper operator to the given paths. - Returns a Polygon2d, or NULL if the result is empty. - - NB! Will not return an empty Polygon2d. + May return an empty Polygon2d, but will not return NULL. */ Polygon2d *apply(const std::vector &pathsvector, ClipperLib::ClipType clipType) @@ -106,7 +104,7 @@ namespace ClipperUtils { clipper.Clear(); } } - return (result.Total() == 0) ? NULL : ClipperUtils::toPolygon2d(result); + return ClipperUtils::toPolygon2d(result); } bool first = true; @@ -116,7 +114,6 @@ namespace ClipperUtils { } ClipperLib::PolyTree sumresult; clipper.Execute(clipType, sumresult, ClipperLib::pftNonZero, ClipperLib::pftNonZero); - if (sumresult.Total() == 0) return NULL; // The returned result will have outlines ordered according to whether // they're positive or negative: Positive outlines counter-clockwise and // negative outlines clockwise. @@ -126,9 +123,7 @@ namespace ClipperUtils { /*! Apply the clipper operator to the given polygons. - Returns a Polygon2d, or NULL if the result is empty. - - NB! Will not return an empty Polygon2d. + May return an empty Polygon2d, but will not return NULL. */ Polygon2d *apply(const std::vector &polygons, ClipperLib::ClipType clipType) @@ -140,7 +135,7 @@ namespace ClipperUtils { pathsvector.push_back(polypaths); } Polygon2d *res = apply(pathsvector, clipType); - assert(!res || !res->isEmpty()); + assert(res); return res; } From 75b57cd9b5c5b9f6dc49eb5a60512c5b813b9afa Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 21:00:23 -0500 Subject: [PATCH 074/263] Added some malformed polyhedron tests and fixed an assertion bug --- src/primitives.cc | 3 +-- testdata/scad/3D/features/polyhedron-tests.scad | 3 +++ tests/regression/dumptest/polyhedron-tests-expected.csg | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/primitives.cc b/src/primitives.cc index 873fedf5..936825fc 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -516,8 +516,7 @@ Geometry *PrimitiveNode::createGeometry() const if (!this->points.toVector()[pt].getVec3(px, py, pz) || isinf(px) || isinf(py) || isinf(pz)) { PRINTB("ERROR: Unable to convert point at index %d to a vec3 of numbers", j); - delete p; - return NULL; + return p; } p->insert_vertex(px, py, pz); } diff --git a/testdata/scad/3D/features/polyhedron-tests.scad b/testdata/scad/3D/features/polyhedron-tests.scad index 02680c1b..443619d0 100644 --- a/testdata/scad/3D/features/polyhedron-tests.scad +++ b/testdata/scad/3D/features/polyhedron-tests.scad @@ -46,3 +46,6 @@ translate([0,2,0]) difference() { // dont crash (issue #703) polyhedron(points = undef, triangles = [[1, 2, 3]]); polyhedron(points = [[0,0,0],[1,1,1]], triangles = undef); +// More malformed polyhedrons +polyhedron(); +polyhedron(points=[0], faces = [[0]]); diff --git a/tests/regression/dumptest/polyhedron-tests-expected.csg b/tests/regression/dumptest/polyhedron-tests-expected.csg index 0dc507cc..82313982 100644 --- a/tests/regression/dumptest/polyhedron-tests-expected.csg +++ b/tests/regression/dumptest/polyhedron-tests-expected.csg @@ -32,4 +32,6 @@ group() { } polyhedron(points = undef, faces = [[1, 2, 3]], convexity = 1); polyhedron(points = [[0, 0, 0], [1, 1, 1]], faces = undef, convexity = 1); + polyhedron(points = undef, faces = undef, convexity = 1); + polyhedron(points = [0], faces = [[0]], convexity = 1); } From f36646730d72e6ae9de03d3505d4116f41ca45b2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 21:02:35 -0500 Subject: [PATCH 075/263] Added some malformed polygon tests --- testdata/scad/2D/features/polygon-tests.scad | 6 ++++++ tests/regression/dumptest/polygon-tests-expected.csg | 3 +++ 2 files changed, 9 insertions(+) diff --git a/testdata/scad/2D/features/polygon-tests.scad b/testdata/scad/2D/features/polygon-tests.scad index ff1d73f0..26bb979d 100644 --- a/testdata/scad/2D/features/polygon-tests.scad +++ b/testdata/scad/2D/features/polygon-tests.scad @@ -26,4 +26,10 @@ translate([0,0,0]) polygon(points = [[0,1], [0,0], [1,0], [1,1], [0.8,0.8], [0.8,0.2], [0.2,0.2], [0.2,0.8]], paths = [[7,6,5,4,3,2,1,0],[7,0,3,4] ]); + +// More malformed polygons +polyhedron(points = undef, paths = [[1, 2, 3]]); +polyhedron(points = [[0,0,0],[1,1,1]], paths = undef); +polyhedron(points=[0], paths = [[0]]); + // FIXME: convexity diff --git a/tests/regression/dumptest/polygon-tests-expected.csg b/tests/regression/dumptest/polygon-tests-expected.csg index 74b40691..e844927b 100644 --- a/tests/regression/dumptest/polygon-tests-expected.csg +++ b/tests/regression/dumptest/polygon-tests-expected.csg @@ -39,4 +39,7 @@ group() { multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { polygon(points = [[0, 1], [0, 0], [1, 0], [1, 1], [0.8, 0.8], [0.8, 0.2], [0.2, 0.2], [0.2, 0.8]], paths = [[7, 6, 5, 4, 3, 2, 1, 0], [7, 0, 3, 4]], convexity = 1); } + polyhedron(points = undef, faces = undef, convexity = 1); + polyhedron(points = [[0, 0, 0], [1, 1, 1]], faces = undef, convexity = 1); + polyhedron(points = [0], faces = undef, convexity = 1); } From cf418188b96199bf723408079292792eb7458cca Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 21:15:29 -0500 Subject: [PATCH 076/263] Added malformed offset tests --- testdata/scad/2D/features/offset-tests.scad | 4 ++++ tests/regression/dumptest/offset-tests-expected.csg | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/testdata/scad/2D/features/offset-tests.scad b/testdata/scad/2D/features/offset-tests.scad index b121b6d0..06855c64 100644 --- a/testdata/scad/2D/features/offset-tests.scad +++ b/testdata/scad/2D/features/offset-tests.scad @@ -41,3 +41,7 @@ offset(delta = 5) shape1(1, -1); // Bug with fragment calculateion with delta < 1 due to abs() instead of std::abs() translate([-50,-50]) scale([25,25,1]) offset(delta = 0.9, join_type="round") square(.1); + +// Malformed offsets +offset(); +offset() square(0); diff --git a/tests/regression/dumptest/offset-tests-expected.csg b/tests/regression/dumptest/offset-tests-expected.csg index ff88f5cc..3f3888ee 100644 --- a/tests/regression/dumptest/offset-tests-expected.csg +++ b/tests/regression/dumptest/offset-tests-expected.csg @@ -137,4 +137,8 @@ group() { } } } + offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2); + offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { + square(size = [0, 0], center = false); + } } From 3992cc547b723518abf01ed6a9a38a7773032d59 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 30 Nov 2014 02:29:29 +0100 Subject: [PATCH 077/263] Update drawing logic (fixes #1035). - Draw negative part of the axis with stippled lines - Calculate contrast color for axis based on background color - Disable lighting for axis / crosshair --- src/GLView.cc | 58 ++++++++++++++++++++++++++++-------------------- src/GLView.h | 8 +++---- src/colormap.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ src/colormap.h | 2 ++ 4 files changed, 99 insertions(+), 28 deletions(-) diff --git a/src/GLView.cc b/src/GLView.cc index 7ca5a480..fdc668b8 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -150,18 +150,20 @@ void GLView::setupCamera() void GLView::paintGL() { - glEnable(GL_LIGHTING); + glDisable(GL_LIGHTING); - setupCamera(); + setupCamera(); Color4f bgcol = ColorMap::getColor(*this->colorscheme, BACKGROUND_COLOR); + Color4f bgcontrast = ColorMap::getContrastColor(bgcol); glClearColor(bgcol[0], bgcol[1], bgcol[2], 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - // Only for GIMBAL cam + // Only for GIMBAL cam if (showcrosshairs) GLView::showCrosshairs(); - if (showaxes) GLView::showAxes(); + if (showaxes) GLView::showAxes(bgcontrast); + glEnable(GL_LIGHTING); glDepthFunc(GL_LESS); glCullFace(GL_BACK); glDisable(GL_CULL_FACE); @@ -174,10 +176,11 @@ void GLView::paintGL() OpenCSG::setContext(this->opencsg_id); #endif this->renderer->draw(showfaces, showedges); - } + } // Only for GIMBAL - if (showaxes) GLView::showSmallaxes(); + glDisable(GL_LIGHTING); + if (showaxes) GLView::showSmallaxes(bgcontrast); } #ifdef ENABLE_OPENCSG @@ -348,6 +351,7 @@ void GLView::initializeGL() glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); + glEnable(GL_LINE_STIPPLE); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); // The following line is reported to fix issue #71 @@ -358,7 +362,7 @@ void GLView::initializeGL() #endif } -void GLView::showSmallaxes() +void GLView::showSmallaxes(const Color4f &col) { // Fixme - this doesnt work in Vector Camera mode @@ -423,14 +427,9 @@ void GLView::showSmallaxes() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - // FIXME: This was an attempt to keep contrast with background, but is suboptimal - // (e.g. nearly invisible against a gray background). - // int r,g,b; - // r=g=b=0; - // bgcol.getRgb(&r, &g, &b); - // glColor3f((255.0f-r)/255.0f, (255.0f-g)/255.0f, (255.0f-b)/255.0f); - float d = 3*dpi; - glColor3f(0.0f, 0.0f, 0.0f); + glColor3f(col[0], col[1], col[2]); + + float d = 3*dpi; glBegin(GL_LINES); // X Label glVertex3d(xlabel_x-d, xlabel_y-d, 0); glVertex3d(xlabel_x+d, xlabel_y+d, 0); @@ -447,29 +446,40 @@ void GLView::showSmallaxes() glEnd(); } -void GLView::showAxes() +void GLView::showAxes(const Color4f &col) { + double l = cam.projection == Camera::PERSPECTIVE ? cam.viewer_distance : cam.height; + // FIXME: doesn't work under Vector Camera // Large gray axis cross inline with the model - // FIXME: This is always gray - adjust color to keep contrast with background glLineWidth(this->getDPI()); - glColor3d(0.5, 0.5, 0.5); + glColor3f(col[0], col[1], col[2]); + glBegin(GL_LINES); - double l = cam.projection == Camera::PERSPECTIVE ? cam.viewer_distance : cam.height; - glVertex3d(-l, 0, 0); + glVertex3d(0, 0, 0); glVertex3d(+l, 0, 0); - glVertex3d(0, -l, 0); + glVertex3d(0, 0, 0); glVertex3d(0, +l, 0); - glVertex3d(0, 0, -l); + glVertex3d(0, 0, 0); glVertex3d(0, 0, +l); glEnd(); + + glPushAttrib(GL_LINE_BIT); + glLineStipple(3, 0xAAAA); + glBegin(GL_LINES); + glVertex3d(0, 0, 0); + glVertex3d(-l, 0, 0); + glVertex3d(0, 0, 0); + glVertex3d(0, -l, 0); + glVertex3d(0, 0, 0); + glVertex3d(0, 0, -l); + glEnd(); + glPopAttrib(); } void GLView::showCrosshairs() { // FIXME: this might not work with Vector camera - // FIXME: Crosshairs and axes are lighted, this doesn't make sense and causes them - // to change color based on view orientation. glLineWidth(3); Color4f col = ColorMap::getColor(*this->colorscheme, CROSSHAIR_COLOR); glColor3f(col[0], col[1], col[2]); diff --git a/src/GLView.h b/src/GLView.h index f3f98ae2..5e3e4c53 100644 --- a/src/GLView.h +++ b/src/GLView.h @@ -42,10 +42,6 @@ public: void setCamera(const Camera &cam); void setupCamera(); - void showCrosshairs(); - void showAxes(); - void showSmallaxes(); - void setColorScheme(const ColorScheme &cs); void setColorScheme(const std::string &cs); void updateColorScheme(); @@ -76,4 +72,8 @@ public: bool opencsg_support; int opencsg_id; #endif +private: + void showCrosshairs(); + void showAxes(const Color4f &col); + void showSmallaxes(const Color4f &col); }; diff --git a/src/colormap.cc b/src/colormap.cc index e4ccda14..026c21fe 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -5,6 +5,29 @@ static const char *DEFAULT_COLOR_SCHEME_NAME = "Cornfield"; +// See http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv +static void rgbtohsv(float r, float g, float b, float &h, float &s, float &v) +{ + float K = 0.f; + + if (g < b) + { + std::swap(g, b); + K = -1.f; + } + + if (r < g) + { + std::swap(r, g); + K = -2.f / 6.f - K; + } + + float chroma = r - std::min(g, b); + h = fabs(K + (g - b) / (6.f * chroma + 1e-20f)); + s = chroma / (r + 1e-20f); + v = r; +} + RenderColorScheme::RenderColorScheme() : _path("") { _name = DEFAULT_COLOR_SCHEME_NAME; @@ -196,6 +219,42 @@ Color4f ColorMap::getColor(const ColorScheme &cs, const RenderColor rc) return Color4f(0, 0, 0, 127); } +Color4f ColorMap::getColorHSV(const Color4f &col) +{ + float h, s, v; + rgbtohsv(col[0], col[1], col[2], h, s, v); + return Color4f(h, s, v, col[3]); +} + +/** + * Calculate contrast color. Based on the article + * http://gamedev.stackexchange.com/questions/38536/given-a-rgb-color-x-how-to-find-the-most-contrasting-color-y + * + * @param col the input color + * @return a color with high contrast to the input color + */ +Color4f ColorMap::getContrastColor(const Color4f &col) +{ + Color4f hsv = ColorMap::getColorHSV(col); + float Y = 0.2126 * col[0] + 0.7152 * col[1] + 0.0722 * col[2]; + float S = hsv[1]; + + if (S < 0.5) { + // low saturation, choose between black / white based on luminance Y + float val = Y > 0.5 ? 0.0f : 1.0f; + return Color4f(val, val, val, 1.0f); + } else { + float H = 360 * hsv[0]; + if ((H < 60) || (H > 300)) { + return Color4f(0.0f, 1.0f, 1.0f, 1.0f); // red -> cyan + } else if (H < 180) { + return Color4f(1.0f, 0.0f, 1.0f, 1.0f); // green -> magenta + } else { + return Color4f(1.0f, 1.0f, 0.0f, 1.0f); // blue -> yellow + } + } +} + void ColorMap::enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path basePath) { const fs::path color_schemes = basePath / "color-schemes" / "render"; diff --git a/src/colormap.h b/src/colormap.h index 883932fc..0f8bc545 100644 --- a/src/colormap.h +++ b/src/colormap.h @@ -79,6 +79,8 @@ public: std::list colorSchemeNames(bool guiOnly = false) const; static Color4f getColor(const ColorScheme &cs, const RenderColor rc); + static Color4f getContrastColor(const Color4f &col); + static Color4f getColorHSV(const Color4f &col); private: ColorMap(); From fcbd9fc0241b49d743f9b4407024d24f2efeac5a Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 30 Nov 2014 03:02:07 +0100 Subject: [PATCH 078/263] Fix crosshair at the center of the display (fixes #1025). --- src/GLView.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/GLView.cc b/src/GLView.cc index fdc668b8..ba553bd5 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -113,7 +113,6 @@ void GLView::setupCamera() glRotated(cam.object_rot.x(), 1.0, 0.0, 0.0); glRotated(cam.object_rot.y(), 0.0, 1.0, 0.0); glRotated(cam.object_rot.z(), 0.0, 0.0, 1.0); - glTranslated(cam.object_trans.x(), cam.object_trans.y(), cam.object_trans.z() ); break; case Camera::VECTOR: { switch (this->cam.projection) { @@ -152,16 +151,20 @@ void GLView::paintGL() { glDisable(GL_LIGHTING); - setupCamera(); - Color4f bgcol = ColorMap::getColor(*this->colorscheme, BACKGROUND_COLOR); Color4f bgcontrast = ColorMap::getContrastColor(bgcol); glClearColor(bgcol[0], bgcol[1], bgcol[2], 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - // Only for GIMBAL cam - if (showcrosshairs) GLView::showCrosshairs(); - if (showaxes) GLView::showAxes(bgcontrast); + setupCamera(); + if (this->cam.type) { + // Only for GIMBAL cam + // The crosshair should be fixed at the center of the viewport... + if (showcrosshairs) GLView::showCrosshairs(); + glTranslated(cam.object_trans.x(), cam.object_trans.y(), cam.object_trans.z()); + // ...the axis lines need to follow the object translation. + if (showaxes) GLView::showAxes(bgcontrast); + } glEnable(GL_LIGHTING); glDepthFunc(GL_LESS); @@ -486,7 +489,7 @@ void GLView::showCrosshairs() glBegin(GL_LINES); for (double xf = -1; xf <= +1; xf += 2) for (double yf = -1; yf <= +1; yf += 2) { - double vd = cam.viewer_distance/20; + double vd = cam.viewer_distance/5; glVertex3d(-xf*vd, -yf*vd, -vd); glVertex3d(+xf*vd, +yf*vd, +vd); } From 6263bfd269e3fd806bac5939971bdf23259b71fa Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 30 Nov 2014 03:22:14 +0100 Subject: [PATCH 079/263] Render crosshair a bit less intrusive. --- src/GLView.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GLView.cc b/src/GLView.cc index ba553bd5..d52b3c9b 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -483,13 +483,13 @@ void GLView::showAxes(const Color4f &col) void GLView::showCrosshairs() { // FIXME: this might not work with Vector camera - glLineWidth(3); + glLineWidth(this->getDPI()); Color4f col = ColorMap::getColor(*this->colorscheme, CROSSHAIR_COLOR); glColor3f(col[0], col[1], col[2]); glBegin(GL_LINES); for (double xf = -1; xf <= +1; xf += 2) for (double yf = -1; yf <= +1; yf += 2) { - double vd = cam.viewer_distance/5; + double vd = cam.viewer_distance/8; glVertex3d(-xf*vd, -yf*vd, -vd); glVertex3d(+xf*vd, +yf*vd, +vd); } From ef9f2f328966d2246d9488ef371038fb7d268aaf Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 29 Nov 2014 22:44:40 +0100 Subject: [PATCH 080/263] Retain FileContext to lookup $vp{rtd} variables after compilation (fixes #949). --- src/mainwin.cc | 50 +++++++++++++++++++++----------------------------- src/module.cc | 25 +++++++++++++++++++++---- src/module.h | 9 ++++++--- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/mainwin.cc b/src/mainwin.cc index 776a46ed..f335d7b9 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -938,6 +938,7 @@ void MainWindow::compileDone(bool didchange) const char *callslot; if (didchange) { instantiateRoot(); + updateCamera(); callslot = afterCompileSlot; } else { @@ -1525,34 +1526,27 @@ void MainWindow::updateCamera() double rz = cam.object_rot.z(); double d = cam.viewer_distance; - ModuleContext mc(&top_ctx, NULL); - mc.initializeModule(*root_module); + double x, y, z; + const Value vpr = root_module->lookup_variable("$vpr"); + if (vpr.getVec3(x, y, z)) { + rx = x; + ry = y; + rz = z; + camera_set = true; + } - BOOST_FOREACH(const Assignment &a, root_module->scope.assignments) { - double x, y, z; - if ("$vpr" == a.first) { - const Value vpr = a.second.get()->evaluate(&mc); - if (vpr.getVec3(x, y, z)) { - rx = x; - ry = y; - rz = z; - camera_set = true; - } - } else if ("$vpt" == a.first) { - const Value vpt = a.second.get()->evaluate(&mc); - if (vpt.getVec3(x, y, z)) { - tx = x; - ty = y; - tz = z; - camera_set = true; - } - } else if ("$vpd" == a.first) { - const Value vpd = a.second.get()->evaluate(&mc); - if (vpd.type() == Value::NUMBER) { - d = vpd.toDouble(); - camera_set = true; - } - } + const Value vpt = root_module->lookup_variable("$vpt"); + if (vpt.getVec3(x, y, z)) { + tx = x; + ty = y; + tz = z; + camera_set = true; + } + + const Value vpd = root_module->lookup_variable("$vpd"); + if (vpd.type() == Value::NUMBER) { + d = vpd.toDouble(); + camera_set = true; } if (camera_set) { @@ -1613,8 +1607,6 @@ void MainWindow::compileTopLevelDocument() this->root_module = parse(fulltext.c_str(), this->fileName.isEmpty() ? "" : QFileInfo(this->fileName).absolutePath().toLocal8Bit(), false); - - updateCamera(); } void MainWindow::checkAutoReload() diff --git a/src/module.cc b/src/module.cc index 44c2da6b..2feafab5 100644 --- a/src/module.cc +++ b/src/module.cc @@ -238,6 +238,11 @@ std::string Module::dump(const std::string &indent, const std::string &name) con return dump.str(); } +FileModule::~FileModule() +{ + delete context; +} + void FileModule::registerUse(const std::string path) { std::string extraw = boosty::extension_str(fs::path(path)); std::string ext = boost::algorithm::to_lower_copy(extraw); @@ -346,19 +351,31 @@ bool FileModule::handleDependencies() return somethingchanged; } -AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const +AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) { assert(evalctx == NULL); - FileContext c(*this, ctx); - c.initializeModule(*this); + + delete context; + context = new FileContext(*this, ctx); + context->initializeModule(*this); + // FIXME: Set document path to the path of the module #if 0 && DEBUG c.dump(this, inst); #endif AbstractNode *node = new AbstractNode(inst); - std::vector instantiatednodes = this->scope.instantiateChildren(&c); + std::vector instantiatednodes = this->scope.instantiateChildren(context); node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end()); return node; } + +Value FileModule::lookup_variable(const std::string &name) const +{ + if (!context) { + return Value::undefined; + } + + return context->lookup_variable(name, true); +} \ No newline at end of file diff --git a/src/module.h b/src/module.h index 8d1f1e13..15a00628 100644 --- a/src/module.h +++ b/src/module.h @@ -99,8 +99,8 @@ private: class FileModule : public Module { public: - FileModule() : is_handling_dependencies(false) {} - virtual ~FileModule() {} + FileModule() : context(NULL), is_handling_dependencies(false) {} + virtual ~FileModule(); void setModulePath(const std::string &path) { this->path = path; } const std::string &modulePath() const { return this->path; } @@ -108,14 +108,17 @@ public: void registerInclude(const std::string &localpath, const std::string &fullpath); bool includesChanged() const; bool handleDependencies(); - virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx = NULL) const; + virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx = NULL); bool hasIncludes() const { return !this->includes.empty(); } bool usesLibraries() const { return !this->usedlibs.empty(); } bool isHandlingDependencies() const { return this->is_handling_dependencies; } + Value lookup_variable(const std::string &name) const; typedef boost::unordered_set ModuleContainer; ModuleContainer usedlibs; private: + /** Reference to retain the context that was used in the last evaluation */ + class FileContext *context; struct IncludeFile { std::string filename; bool valid; From a05fe72c6bcc46450797ab6b87a3494c703d4d4d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 1 Dec 2014 00:54:01 -0500 Subject: [PATCH 081/263] Rewrote tessellation used for NefPolyhedron to PolySet conversion. Should fix #1033 --- openscad.pro | 1 + src/cgalutils-tess-old.cc | 553 ++++++++++++++++++++++++++++++++++++ src/cgalutils-tess.cc | 571 +++++++++++--------------------------- src/cgalutils.cc | 230 ++++++++++----- src/cgalutils.h | 18 +- src/polyset-utils.cc | 51 +--- tests/CMakeLists.txt | 1 + 7 files changed, 907 insertions(+), 518 deletions(-) create mode 100644 src/cgalutils-tess-old.cc diff --git a/openscad.pro b/openscad.pro index f926ac56..6ee6fa34 100644 --- a/openscad.pro +++ b/openscad.pro @@ -440,6 +440,7 @@ HEADERS += src/cgal.h \ SOURCES += src/cgalutils.cc \ src/cgalutils-tess.cc \ + src/cgalutils-tess-old.cc \ src/CGALCache.cc \ src/CGALRenderer.cc \ src/CGAL_Nef_polyhedron.cc \ diff --git a/src/cgalutils-tess-old.cc b/src/cgalutils-tess-old.cc new file mode 100644 index 00000000..d779772f --- /dev/null +++ b/src/cgalutils-tess-old.cc @@ -0,0 +1,553 @@ +/* + +This is our custom tessellator of Nef Polyhedron faces. The problem with +Nef faces is that sometimes the 'default' tessellator of Nef Polyhedron +doesnt work. This is particularly true with situations where the polygon +face is not, actually, 'simple', according to CGAL itself. This can +occur on a bad quality STL import but also for other reasons. The +resulting Nef face will appear to the average human eye as an ordinary, +simple polygon... but in reality it has multiple edges that are +slightly-out-of-alignment and sometimes they backtrack on themselves. + +When the triangulator is fed a polygon with self-intersecting edges, +it's default behavior is to throw an exception. The other terminology +for this is to say that the 'constraints' in the triangulation are +'intersecting'. The 'constraints' represent the edges of the polygon. +The 'triangulation' is the covering of all the polygon points with +triangles. + +How do we allow interseting constraints during triangulation? We use an +'Itag' for the triangulation, per the CGAL docs. This allows the +triangulator to run without throwing an exception when it encounters +self-intersecting polygon edges. The trick here is that when it finds +an intersection, it actually creates a new point. + +The triangulator creates new points in 2d, but they aren't matched to +any 3d points on our 3d polygon plane. (The plane of the Nef face). How +to fix this problem? We actually 'project back up' or 'lift' into the 3d +plane from the 2d point. This is handled in the 'deproject()' function. + +There is also the issue of the Simplicity of Nef Polyhedron face +polygons. They are often not simple. The intersecting-constraints +Triangulation can triangulate non-simple polygons, but of course it's +result is also non-simple. This means that CGAL functions like +orientation_2() and bounded_side() simply will not work on the resulting +polygons because they all require input polygons to pass the +'is_simple2()' test. We have to use alternatives in order to create our +triangles. + +There is also the question of which underlying number type to use. Some +of the CGAL functions simply dont guarantee good results with a type +like double. Although much the math here is somewhat simple, like +line-line intersection, and involves only simple algebra, the +approximations required when using floating-point types can cause the +answers to be wrong. For example questions like 'is a point inside a +triangle' do not have good answers under floating-point systems where a +line may have a slope that is not expressible exactly as a floating +point number. There are ways to deal with floating point inaccuracy but +it is much, much simpler to use Rational numbers, although potentially +much slower in many cases. + +*/ + +#include "cgalutils.h" +#include +#include + +typedef CGAL_Kernel3 Kernel; +//typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Triangulation_vertex_base_2 Vb; +//typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::Exact_intersections_tag ITAG; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +//typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; + +typedef CDT::Vertex_handle Vertex_handle; +typedef CDT::Point CDTPoint; + +typedef CGAL::Ray_2 CGAL_Ray_2; +typedef CGAL::Line_3 CGAL_Line_3; +typedef CGAL::Point_2 CGAL_Point_2; +typedef CGAL::Vector_2 CGAL_Vector_2; +typedef CGAL::Segment_2 CGAL_Segment_2; +typedef CGAL::Direction_2 CGAL_Direction_2; +typedef CGAL::Direction_3 CGAL_Direction_3; +typedef CGAL::Plane_3 CGAL_Plane_3; + +/* The idea of 'projection' is how we make 3d points appear as though +they were 2d points to the tessellation algorithm. We take the 3-d plane +on which the polygon lies, and then 'project' or 'cast its shadow' onto +one of three standard planes, the xyplane, the yzplane, or the xzplane, +depending on which projection will prevent the polygon looking like a +flat line. (imagine, the triangle 0,0,1 0,1,1 0,1,0 ... if viewed from +the 'top' it looks line a flat line. so we want to view it from the +side). Thus we create a sequence of x,y points to feed to the algorithm, +but those points might actually be x,z pairs or y,z pairs... it is an +illusion we present to the triangulation algorithm by way of 'projection'. +We get a resulting sequence of triangles with x,y coordinates, which we +then 'deproject' back to x,z or y,z, in 3d space as needed. For example +the square 0,0,0 0,0,1 0,1,1 0,1,0 becomes '0,0 0,1 1,1 1,0', is then +split into two triangles, 0,0 1,0 1,1 and 0,0 1,1 0,1. those two triangles +then are projected back to 3d as 0,0,0 0,1,0 0,1,1 and 0,0 0,1,1 0,0,1. + +There is an additional trick we do with projection related to Polygon +orientation and the orientation of our output triangles, and thus, which +way they are facing in space (aka their 'normals' or 'oriented side'). + +The basic issues is this: every 3d flat polygon can be thought of as +having two sides. In Computer Graphics the convention is that the +'outside' or 'oriented side' or 'normal' is determined by looking at the +triangle in terms of the 'ordering' or 'winding' of the points. If the +points come in a 'clockwise' order, you must be looking at the triangle +from 'inside'. If the points come in a 'counterclockwise' order, you +must be looking at the triangle from the outside. For example, the +triangle 0,0,0 1,0,0 0,1,0, when viewed from the 'top', has points in a +counterclockwise order, so the 'up' side is the 'normal' or 'outside'. +if you look at that same triangle from the 'bottom' side, the points +will appear to be 'clockwise', so the 'down' side is the 'inside', and is the +opposite of the 'normal' side. + +How do we keep track of all that when doing a triangulation? We could +check each triangle as it was generated, and fix it's orientation before +we feed it back to our output list. That is done by, for example, checking +the orientation of the input polygon and then forcing the triangle to +match that orientation during output. This is what CGAL's Nef Polyhedron +does, you can read it inside /usr/include/CGAL/Nef_polyhedron_3.h. + +Or.... we could actually add an additional 'projection' to the incoming +polygon points so that our triangulation algorithm is guaranteed to +create triangles with the proper orientation in the first place. How? +First, we assume that the triangulation algorithm will always produce +'counterclockwise' triangles in our plain old x-y plane. + +The method is based on the following curious fact: That is, if you take +the points of a polygon, and flip the x,y coordinate of each point, +making y:=x and x:=y, then you essentially get a 'mirror image' of the +original polygon... but the orientation will be flipped. Given a +clockwise polygon, the 'flip' will result in a 'counterclockwise' +polygon mirror-image and vice versa. + +Now, there is a second curious fact that helps us here. In 3d, we are +using the plane equation of ax+by+cz+d=0, where a,b,c determine its +direction. If you notice, there are actually mutiple sets of numbers +a:b:c that will describe the exact same plane. For example the 'ground' +plane, called the XYplane, where z is everywhere 0, has the equation +0x+0y+1z+0=0, simplifying to a solution for x,y,z of z=0 and x,y = any +numbers in your number system. However you can also express this as +0x+0y+-1z=0. The x,y,z solution is the same: z is everywhere 0, x and y +are any number, even though a,b,c are different. We can say that the +plane is 'oriented' differently, if we wish. + +But how can we link that concept to the points on the polygon? Well, if +you generate a plane using the standard plane-equation generation +formula, given three points M,N,P, then you will get a plane equation +with . However if you feed the points in the reverse order, +P,N,M, so that they are now oriented in the opposite order, you will get +a plane equation with the signs flipped. <-a:-b:-c:-d> This means you +can essentially consider that a plane has an 'orientation' based on it's +equation, by looking at the signs of a,b,c relative to some other +quantity. + +This means that you can 'flip' the projection of the input polygon +points so that the projection will match the orientation of the input +plane, thus guaranteeing that the output triangles will be oriented in +the same direction as the input polygon was. In other words, even though +we technically 'lose information' when we project from 3d->2d, we can +actually keep the concept of 'orientation' through the whole +triangulation process, and not have to recalculate the proper +orientation during output. + +For example take two side-squares of a cube and the plane equations +formed by feeding the points in counterclockwise, as if looking in from +outside the cube: + + 0,0,0 0,1,0 0,1,1 0,0,1 <-1:0:0:0> + 1,0,0 1,1,0 1,1,1 1,0,1 <1:0:0:1> + +They are both projected onto the YZ plane. They look the same: + 0,0 1,0 1,1 0,1 + 0,0 1,0 1,1 0,1 + +But the second square plane has opposite orientation, so we flip the x +and y for each point: + 0,0 1,0 1,1 0,1 + 0,0 0,1 1,1 1,0 + +Only now do we feed these two 2-d squares to the tessellation algorithm. +The result is 4 triangles. When de-projected back to 3d, they will have +the appropriate winding that will match that of the original 3d faces. +And the first two triangles will have opposite orientation from the last two. +*/ + +typedef enum { XYPLANE, YZPLANE, XZPLANE, NONE } plane_t; +struct projection_t { + plane_t plane; + bool flip; +}; + +CGAL_Point_2 get_projected_point( CGAL_Point_3 &p3, projection_t projection ) { + NT3 x,y; + if (projection.plane == XYPLANE) { x = p3.x(); y = p3.y(); } + else if (projection.plane == XZPLANE) { x = p3.x(); y = p3.z(); } + else if (projection.plane == YZPLANE) { x = p3.y(); y = p3.z(); } + else if (projection.plane == NONE) { x = 0; y = 0; } + if (projection.flip) return CGAL_Point_2( y,x ); + return CGAL_Point_2( x,y ); +} + +/* given 2d point, 3d plane, and 3d->2d projection, 'deproject' from + 2d back onto a point on the 3d plane. true on failure, false on success */ +bool deproject( CGAL_Point_2 &p2, projection_t &projection, CGAL_Plane_3 &plane, CGAL_Point_3 &p3 ) +{ + NT3 x,y; + CGAL_Line_3 l; + CGAL_Point_3 p; + CGAL_Point_2 pf( p2.x(), p2.y() ); + if (projection.flip) pf = CGAL_Point_2( p2.y(), p2.x() ); + if (projection.plane == XYPLANE) { + p = CGAL_Point_3( pf.x(), pf.y(), 0 ); + l = CGAL_Line_3( p, CGAL_Direction_3(0,0,1) ); + } else if (projection.plane == XZPLANE) { + p = CGAL_Point_3( pf.x(), 0, pf.y() ); + l = CGAL_Line_3( p, CGAL_Direction_3(0,1,0) ); + } else if (projection.plane == YZPLANE) { + p = CGAL_Point_3( 0, pf.x(), pf.y() ); + l = CGAL_Line_3( p, CGAL_Direction_3(1,0,0) ); + } + CGAL::Object obj = CGAL::intersection( l, plane ); + const CGAL_Point_3 *point_test = CGAL::object_cast(&obj); + if (point_test) { + p3 = *point_test; + return false; + } + PRINT("ERROR: deproject failure"); + return true; +} + +/* this simple criteria guarantees CGALs triangulation algorithm will +terminate (i.e. not lock up and freeze the program) */ +template class DummyCriteria { +public: + typedef double Quality; + class Is_bad { + public: + CGAL::Mesh_2::Face_badness operator()(const Quality) const { + return CGAL::Mesh_2::NOT_BAD; + } + CGAL::Mesh_2::Face_badness operator()(const typename T::Face_handle&, Quality&q) const { + q = 1; + return CGAL::Mesh_2::NOT_BAD; + } + }; + Is_bad is_bad_object() const { return Is_bad(); } +}; + +NT3 sign( const NT3 &n ) +{ + if (n>0) return NT3(1); + if (n<0) return NT3(-1); + return NT3(0); +} + +/* wedge, also related to 'determinant', 'signed parallelogram area', +'side', 'turn', 'winding', '2d portion of cross-product', etc etc. this +function can tell you whether v1 is 'counterclockwise' or 'clockwise' +from v2, based on the sign of the result. when the input Vectors are +formed from three points, A-B and B-C, it can tell you if the path along +the points A->B->C is turning left or right.*/ +NT3 wedge( CGAL_Vector_2 &v1, CGAL_Vector_2 &v2 ) { + return v1.x()*v2.y()-v2.x()*v1.y(); +} + +/* given a point and a possibly non-simple polygon, determine if the +point is inside the polygon or not, using the given winding rule. note +that even_odd is not implemented. */ +typedef enum { NONZERO_WINDING, EVEN_ODD } winding_rule_t; +bool inside(CGAL_Point_2 &p1,std::vector &pgon, winding_rule_t winding_rule) +{ + NT3 winding_sum = NT3(0); + CGAL_Point_2 p2; + CGAL_Ray_2 eastray(p1,CGAL_Direction_2(1,0)); + for (size_t i=0;i(&obj); + if (point_test) { + p2 = *point_test; + CGAL_Vector_2 v1( p1, p2 ); + CGAL_Vector_2 v2( p2, head ); + NT3 this_winding = wedge( v1, v2 ); + winding_sum += sign(this_winding); + } else { + continue; + } + } + if (winding_sum != NT3(0) && winding_rule == NONZERO_WINDING ) return true; + return false; +} + +projection_t find_good_projection( CGAL_Plane_3 &plane ) +{ + projection_t goodproj; + goodproj.plane = NONE; + goodproj.flip = false; + NT3 qxy = plane.a()*plane.a()+plane.b()*plane.b(); + NT3 qyz = plane.b()*plane.b()+plane.c()*plane.c(); + NT3 qxz = plane.a()*plane.a()+plane.c()*plane.c(); + NT3 min = std::min(qxy,std::min(qyz,qxz)); + if (min==qxy) { + goodproj.plane = XYPLANE; + if (sign(plane.c())>0) goodproj.flip = true; + } else if (min==qyz) { + goodproj.plane = YZPLANE; + if (sign(plane.a())>0) goodproj.flip = true; + } else if (min==qxz) { + goodproj.plane = XZPLANE; + if (sign(plane.b())<0) goodproj.flip = true; + } else PRINT("ERROR: failed to find projection"); + return goodproj; +} + +namespace CGALUtils { +/* given a single near-planar 3d polygon with holes, tessellate into a + sequence of polygons without holes. as of writing, this means conversion + into a sequence of 3d triangles. the given plane should be the same plane + holding the polygon and it's holes. */ + bool tessellate3DFaceWithHolesNew(std::vector &polygons, + Polygons &triangles, + CGAL_Plane_3 &plane) + { + if (polygons.size()==1 && polygons[0].size()==3) { + PRINTD("input polygon has 3 points. shortcut tessellation."); + Polygon t; + t.push_back(Vector3d(CGAL::to_double(polygons[0][0].x()), CGAL::to_double(polygons[0][0].y()), CGAL::to_double(polygons[0][0].z()))); + t.push_back(Vector3d(CGAL::to_double(polygons[0][1].x()), CGAL::to_double(polygons[0][1].y()), CGAL::to_double(polygons[0][1].z()))); + t.push_back(Vector3d(CGAL::to_double(polygons[0][2].x()), CGAL::to_double(polygons[0][2].y()), CGAL::to_double(polygons[0][2].z()))); + triangles.push_back( t ); + return false; + } + bool err = false; + CDT cdt; + std::map vertmap; + + PRINTD("finding good projection"); + projection_t goodproj = find_good_projection( plane ); + + PRINTDB("plane %s",plane ); + PRINTDB("proj: %i %i",goodproj.plane % goodproj.flip); + PRINTD("Inserting points and edges into Constrained Delaunay Triangulation"); + std::vector< std::vector > polygons2d; + for (size_t i=0;i vhandles; + std::vector polygon2d; + for (size_t j=0;j list_of_seeds; + for (size_t i=1;i &pgon = polygons2d[i]; + for (size_t j=0;j::iterator li = list_of_seeds.begin(); + for (;li!=list_of_seeds.end();li++) { + //PRINTB("seed %s",*li); + double x = CGAL::to_double( li->x() ); + double y = CGAL::to_double( li->y() ); + PRINTDB("seed %f,%f",x%y); + } + PRINTD("seeding done"); + + PRINTD( "meshing" ); + CGAL::refine_Delaunay_mesh_2_without_edge_refinement( cdt, + list_of_seeds.begin(), list_of_seeds.end(), + DummyCriteria() ); + + PRINTD("meshing done"); + // this fails because it calls is_simple and is_simple fails on many + // Nef Polyhedron faces + //CGAL::Orientation original_orientation = + // CGAL::orientation_2( orienpgon.begin(), orienpgon.end() ); + + CDT::Finite_faces_iterator fit; + for( fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end(); fit++ ) + { + if(fit->is_in_domain()) { + CDTPoint p1 = cdt.triangle( fit )[0]; + CDTPoint p2 = cdt.triangle( fit )[1]; + CDTPoint p3 = cdt.triangle( fit )[2]; + CGAL_Point_3 cp1,cp2,cp3; + if (vertmap.count(p1)) cp1 = vertmap[p1]; + else err = deproject( p1, goodproj, plane, cp1 ); + if (vertmap.count(p2)) cp2 = vertmap[p2]; + else err = deproject( p2, goodproj, plane, cp2 ); + if (vertmap.count(p3)) cp3 = vertmap[p3]; + else err = deproject( p3, goodproj, plane, cp3 ); + if (err) PRINT("WARNING: 2d->3d deprojection failure"); + Polygon tri; + tri.push_back(Vector3d(CGAL::to_double(cp1.x()), CGAL::to_double(cp1.y()), CGAL::to_double(cp1.z()))); + tri.push_back(Vector3d(CGAL::to_double(cp2.x()), CGAL::to_double(cp2.y()), CGAL::to_double(cp2.z()))); + tri.push_back(Vector3d(CGAL::to_double(cp3.x()), CGAL::to_double(cp3.y()), CGAL::to_double(cp3.z()))); + triangles.push_back( tri ); + } + } + + PRINTDB("built %i triangles",triangles.size()); + return err; + } + + +/* given a single near-planar 3d polygon with holes, tessellate into a + sequence of polygons without holes. as of writing, this means conversion + into a sequence of 3d triangles. the given plane should be the same plane + holding the polygon and it's holes. */ + bool tessellate3DFaceWithHoles(std::vector &polygons, + std::vector &triangles, + CGAL_Plane_3 &plane) + { + if (polygons.size()==1 && polygons[0].size()==3) { + PRINTD("input polygon has 3 points. shortcut tessellation."); + CGAL_Polygon_3 t; + t.push_back(polygons[0][2]); + t.push_back(polygons[0][1]); + t.push_back(polygons[0][0]); + triangles.push_back( t ); + return false; + } + bool err = false; + CDT cdt; + std::map vertmap; + + PRINTD("finding good projection"); + projection_t goodproj = find_good_projection( plane ); + + PRINTDB("plane %s",plane ); + PRINTDB("proj: %i %i",goodproj.plane % goodproj.flip); + PRINTD("Inserting points and edges into Constrained Delaunay Triangulation"); + std::vector< std::vector > polygons2d; + for (size_t i=0;i vhandles; + std::vector polygon2d; + for (size_t j=0;j list_of_seeds; + for (size_t i=1;i &pgon = polygons2d[i]; + for (size_t j=0;j::iterator li = list_of_seeds.begin(); + for (;li!=list_of_seeds.end();li++) { + //PRINTB("seed %s",*li); + double x = CGAL::to_double( li->x() ); + double y = CGAL::to_double( li->y() ); + PRINTDB("seed %f,%f",x%y); + } + PRINTD("seeding done"); + + PRINTD( "meshing" ); + CGAL::refine_Delaunay_mesh_2_without_edge_refinement( cdt, + list_of_seeds.begin(), list_of_seeds.end(), + DummyCriteria() ); + + PRINTD("meshing done"); + // this fails because it calls is_simple and is_simple fails on many + // Nef Polyhedron faces + //CGAL::Orientation original_orientation = + // CGAL::orientation_2( orienpgon.begin(), orienpgon.end() ); + + CDT::Finite_faces_iterator fit; + for( fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end(); fit++ ) + { + if(fit->is_in_domain()) { + CDTPoint p1 = cdt.triangle( fit )[0]; + CDTPoint p2 = cdt.triangle( fit )[1]; + CDTPoint p3 = cdt.triangle( fit )[2]; + CGAL_Point_3 cp1,cp2,cp3; + CGAL_Polygon_3 pgon; + if (vertmap.count(p1)) cp1 = vertmap[p1]; + else err = deproject( p1, goodproj, plane, cp1 ); + if (vertmap.count(p2)) cp2 = vertmap[p2]; + else err = deproject( p2, goodproj, plane, cp2 ); + if (vertmap.count(p3)) cp3 = vertmap[p3]; + else err = deproject( p3, goodproj, plane, cp3 ); + if (err) PRINT("WARNING: 2d->3d deprojection failure"); + pgon.push_back( cp1 ); + pgon.push_back( cp2 ); + pgon.push_back( cp3 ); + triangles.push_back( pgon ); + } + } + + PRINTDB("built %i triangles",triangles.size()); + return err; + } + +}; diff --git a/src/cgalutils-tess.cc b/src/cgalutils-tess.cc index c8188908..e230e9db 100644 --- a/src/cgalutils-tess.cc +++ b/src/cgalutils-tess.cc @@ -1,433 +1,198 @@ -/* - -This is our custom tessellator of Nef Polyhedron faces. The problem with -Nef faces is that sometimes the 'default' tessellator of Nef Polyhedron -doesnt work. This is particularly true with situations where the polygon -face is not, actually, 'simple', according to CGAL itself. This can -occur on a bad quality STL import but also for other reasons. The -resulting Nef face will appear to the average human eye as an ordinary, -simple polygon... but in reality it has multiple edges that are -slightly-out-of-alignment and sometimes they backtrack on themselves. - -When the triangulator is fed a polygon with self-intersecting edges, -it's default behavior is to throw an exception. The other terminology -for this is to say that the 'constraints' in the triangulation are -'intersecting'. The 'constraints' represent the edges of the polygon. -The 'triangulation' is the covering of all the polygon points with -triangles. - -How do we allow interseting constraints during triangulation? We use an -'Itag' for the triangulation, per the CGAL docs. This allows the -triangulator to run without throwing an exception when it encounters -self-intersecting polygon edges. The trick here is that when it finds -an intersection, it actually creates a new point. - -The triangulator creates new points in 2d, but they aren't matched to -any 3d points on our 3d polygon plane. (The plane of the Nef face). How -to fix this problem? We actually 'project back up' or 'lift' into the 3d -plane from the 2d point. This is handled in the 'deproject()' function. - -There is also the issue of the Simplicity of Nef Polyhedron face -polygons. They are often not simple. The intersecting-constraints -Triangulation can triangulate non-simple polygons, but of course it's -result is also non-simple. This means that CGAL functions like -orientation_2() and bounded_side() simply will not work on the resulting -polygons because they all require input polygons to pass the -'is_simple2()' test. We have to use alternatives in order to create our -triangles. - -There is also the question of which underlying number type to use. Some -of the CGAL functions simply dont guarantee good results with a type -like double. Although much the math here is somewhat simple, like -line-line intersection, and involves only simple algebra, the -approximations required when using floating-point types can cause the -answers to be wrong. For example questions like 'is a point inside a -triangle' do not have good answers under floating-point systems where a -line may have a slope that is not expressible exactly as a floating -point number. There are ways to deal with floating point inaccuracy but -it is much, much simpler to use Rational numbers, although potentially -much slower in many cases. - -*/ - #include "cgalutils.h" -#include -#include +//#include "cgal.h" +//#include "tess.h" -typedef CGAL_Kernel3 Kernel; -//typedef CGAL::Triangulation_vertex_base_2 Vb; -typedef CGAL::Triangulation_vertex_base_2 Vb; -//typedef CGAL::Constrained_triangulation_face_base_2 Fb; -typedef CGAL::Delaunay_mesh_face_base_2 Fb; -typedef CGAL::Triangulation_data_structure_2 TDS; -typedef CGAL::Exact_intersections_tag ITAG; -typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; -//typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +#ifdef NDEBUG +#define PREV_NDEBUG NDEBUG +#undef NDEBUG +#endif +#include +#include +#include +#ifdef PREV_NDEBUG +#define NDEBUG PREV_NDEBUG +#endif -typedef CDT::Vertex_handle Vertex_handle; -typedef CDT::Point CDTPoint; +#include -typedef CGAL::Ray_2 CGAL_Ray_2; -typedef CGAL::Line_3 CGAL_Line_3; -typedef CGAL::Point_2 CGAL_Point_2; -typedef CGAL::Vector_2 CGAL_Vector_2; -typedef CGAL::Segment_2 CGAL_Segment_2; -typedef CGAL::Direction_2 CGAL_Direction_2; -typedef CGAL::Direction_3 CGAL_Direction_3; -typedef CGAL::Plane_3 CGAL_Plane_3; -/* The idea of 'projection' is how we make 3d points appear as though -they were 2d points to the tessellation algorithm. We take the 3-d plane -on which the polygon lies, and then 'project' or 'cast its shadow' onto -one of three standard planes, the xyplane, the yzplane, or the xzplane, -depending on which projection will prevent the polygon looking like a -flat line. (imagine, the triangle 0,0,1 0,1,1 0,1,0 ... if viewed from -the 'top' it looks line a flat line. so we want to view it from the -side). Thus we create a sequence of x,y points to feed to the algorithm, -but those points might actually be x,z pairs or y,z pairs... it is an -illusion we present to the triangulation algorithm by way of 'projection'. -We get a resulting sequence of triangles with x,y coordinates, which we -then 'deproject' back to x,z or y,z, in 3d space as needed. For example -the square 0,0,0 0,0,1 0,1,1 0,1,0 becomes '0,0 0,1 1,1 1,0', is then -split into two triangles, 0,0 1,0 1,1 and 0,0 1,1 0,1. those two triangles -then are projected back to 3d as 0,0,0 0,1,0 0,1,1 and 0,0 0,1,1 0,0,1. - -There is an additional trick we do with projection related to Polygon -orientation and the orientation of our output triangles, and thus, which -way they are facing in space (aka their 'normals' or 'oriented side'). - -The basic issues is this: every 3d flat polygon can be thought of as -having two sides. In Computer Graphics the convention is that the -'outside' or 'oriented side' or 'normal' is determined by looking at the -triangle in terms of the 'ordering' or 'winding' of the points. If the -points come in a 'clockwise' order, you must be looking at the triangle -from 'inside'. If the points come in a 'counterclockwise' order, you -must be looking at the triangle from the outside. For example, the -triangle 0,0,0 1,0,0 0,1,0, when viewed from the 'top', has points in a -counterclockwise order, so the 'up' side is the 'normal' or 'outside'. -if you look at that same triangle from the 'bottom' side, the points -will appear to be 'clockwise', so the 'down' side is the 'inside', and is the -opposite of the 'normal' side. - -How do we keep track of all that when doing a triangulation? We could -check each triangle as it was generated, and fix it's orientation before -we feed it back to our output list. That is done by, for example, checking -the orientation of the input polygon and then forcing the triangle to -match that orientation during output. This is what CGAL's Nef Polyhedron -does, you can read it inside /usr/include/CGAL/Nef_polyhedron_3.h. - -Or.... we could actually add an additional 'projection' to the incoming -polygon points so that our triangulation algorithm is guaranteed to -create triangles with the proper orientation in the first place. How? -First, we assume that the triangulation algorithm will always produce -'counterclockwise' triangles in our plain old x-y plane. - -The method is based on the following curious fact: That is, if you take -the points of a polygon, and flip the x,y coordinate of each point, -making y:=x and x:=y, then you essentially get a 'mirror image' of the -original polygon... but the orientation will be flipped. Given a -clockwise polygon, the 'flip' will result in a 'counterclockwise' -polygon mirror-image and vice versa. - -Now, there is a second curious fact that helps us here. In 3d, we are -using the plane equation of ax+by+cz+d=0, where a,b,c determine its -direction. If you notice, there are actually mutiple sets of numbers -a:b:c that will describe the exact same plane. For example the 'ground' -plane, called the XYplane, where z is everywhere 0, has the equation -0x+0y+1z+0=0, simplifying to a solution for x,y,z of z=0 and x,y = any -numbers in your number system. However you can also express this as -0x+0y+-1z=0. The x,y,z solution is the same: z is everywhere 0, x and y -are any number, even though a,b,c are different. We can say that the -plane is 'oriented' differently, if we wish. - -But how can we link that concept to the points on the polygon? Well, if -you generate a plane using the standard plane-equation generation -formula, given three points M,N,P, then you will get a plane equation -with . However if you feed the points in the reverse order, -P,N,M, so that they are now oriented in the opposite order, you will get -a plane equation with the signs flipped. <-a:-b:-c:-d> This means you -can essentially consider that a plane has an 'orientation' based on it's -equation, by looking at the signs of a,b,c relative to some other -quantity. - -This means that you can 'flip' the projection of the input polygon -points so that the projection will match the orientation of the input -plane, thus guaranteeing that the output triangles will be oriented in -the same direction as the input polygon was. In other words, even though -we technically 'lose information' when we project from 3d->2d, we can -actually keep the concept of 'orientation' through the whole -triangulation process, and not have to recalculate the proper -orientation during output. - -For example take two side-squares of a cube and the plane equations -formed by feeding the points in counterclockwise, as if looking in from -outside the cube: - - 0,0,0 0,1,0 0,1,1 0,0,1 <-1:0:0:0> - 1,0,0 1,1,0 1,1,1 1,0,1 <1:0:0:1> - -They are both projected onto the YZ plane. They look the same: - 0,0 1,0 1,1 0,1 - 0,0 1,0 1,1 0,1 - -But the second square plane has opposite orientation, so we flip the x -and y for each point: - 0,0 1,0 1,1 0,1 - 0,0 0,1 1,1 1,0 - -Only now do we feed these two 2-d squares to the tessellation algorithm. -The result is 4 triangles. When de-projected back to 3d, they will have -the appropriate winding that will match that of the original 3d faces. -And the first two triangles will have opposite orientation from the last two. -*/ - -typedef enum { XYPLANE, YZPLANE, XZPLANE, NONE } plane_t; -struct projection_t { - plane_t plane; - bool flip; +struct FaceInfo { + int nesting_level; + bool in_domain() { return nesting_level%2 == 1; } }; -CGAL_Point_2 get_projected_point( CGAL_Point_3 &p3, projection_t projection ) { - NT3 x,y; - if (projection.plane == XYPLANE) { x = p3.x(); y = p3.y(); } - else if (projection.plane == XZPLANE) { x = p3.x(); y = p3.z(); } - else if (projection.plane == YZPLANE) { x = p3.y(); y = p3.z(); } - else if (projection.plane == NONE) { x = 0; y = 0; } - if (projection.flip) return CGAL_Point_2( y,x ); - return CGAL_Point_2( x,y ); -} +typedef CGAL::Triangulation_2_filtered_projection_traits_3 Projection; +typedef CGAL::Triangulation_face_base_with_info_2 Fbb; +typedef CGAL::Triangulation_data_structure_2< + CGAL::Triangulation_vertex_base_2, + CGAL::Constrained_triangulation_face_base_2 > Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2< + Projection, Tds, CGAL::Exact_predicates_tag> CDT; -/* given 2d point, 3d plane, and 3d->2d projection, 'deproject' from - 2d back onto a point on the 3d plane. true on failure, false on success */ -bool deproject( CGAL_Point_2 &p2, projection_t &projection, CGAL_Plane_3 &plane, CGAL_Point_3 &p3 ) + +static void mark_domains(CDT &ct, + CDT::Face_handle start, + int index, + std::list& border) { - NT3 x,y; - CGAL_Line_3 l; - CGAL_Point_3 p; - CGAL_Point_2 pf( p2.x(), p2.y() ); - if (projection.flip) pf = CGAL_Point_2( p2.y(), p2.x() ); - if (projection.plane == XYPLANE) { - p = CGAL_Point_3( pf.x(), pf.y(), 0 ); - l = CGAL_Line_3( p, CGAL_Direction_3(0,0,1) ); - } else if (projection.plane == XZPLANE) { - p = CGAL_Point_3( pf.x(), 0, pf.y() ); - l = CGAL_Line_3( p, CGAL_Direction_3(0,1,0) ); - } else if (projection.plane == YZPLANE) { - p = CGAL_Point_3( 0, pf.x(), pf.y() ); - l = CGAL_Line_3( p, CGAL_Direction_3(1,0,0) ); - } - CGAL::Object obj = CGAL::intersection( l, plane ); - const CGAL_Point_3 *point_test = CGAL::object_cast(&obj); - if (point_test) { - p3 = *point_test; - return false; - } - PRINT("ERROR: deproject failure"); - return true; + if (start->info().nesting_level != -1) return; + std::list queue; + queue.push_back(start); + while (!queue.empty()) { + CDT::Face_handle fh = queue.front(); + queue.pop_front(); + if (fh->info().nesting_level == -1) { + fh->info().nesting_level = index; + for (int i = 0; i < 3; i++) { + CDT::Edge e(fh,i); + CDT::Face_handle n = fh->neighbor(i); + if (n->info().nesting_level == -1) { + if (ct.is_constrained(e)) border.push_back(e); + else queue.push_back(n); + } + } + } + } } -/* this simple criteria guarantees CGALs triangulation algorithm will -terminate (i.e. not lock up and freeze the program) */ -template class DummyCriteria { -public: - typedef double Quality; - class Is_bad { - public: - CGAL::Mesh_2::Face_badness operator()(const Quality) const { - return CGAL::Mesh_2::NOT_BAD; - } - CGAL::Mesh_2::Face_badness operator()(const typename T::Face_handle&, Quality&q) const { - q = 1; - return CGAL::Mesh_2::NOT_BAD; - } - }; - Is_bad is_bad_object() const { return Is_bad(); } -}; -NT3 sign( const NT3 &n ) +//explore set of facets connected with non constrained edges, +//and attribute to each such set a nesting level. +//We start from facets incident to the infinite vertex, with a nesting +//level of 0. Then we recursively consider the non-explored facets incident +//to constrained edges bounding the former set and increase the nesting level by 1. +//Facets in the domain are those with an odd nesting level. +static void mark_domains(CDT& cdt) { - if (n>0) return NT3(1); - if (n<0) return NT3(-1); - return NT3(0); -} - -/* wedge, also related to 'determinant', 'signed parallelogram area', -'side', 'turn', 'winding', '2d portion of cross-product', etc etc. this -function can tell you whether v1 is 'counterclockwise' or 'clockwise' -from v2, based on the sign of the result. when the input Vectors are -formed from three points, A-B and B-C, it can tell you if the path along -the points A->B->C is turning left or right.*/ -NT3 wedge( CGAL_Vector_2 &v1, CGAL_Vector_2 &v2 ) { - return v1.x()*v2.y()-v2.x()*v1.y(); -} - -/* given a point and a possibly non-simple polygon, determine if the -point is inside the polygon or not, using the given winding rule. note -that even_odd is not implemented. */ -typedef enum { NONZERO_WINDING, EVEN_ODD } winding_rule_t; -bool inside(CGAL_Point_2 &p1,std::vector &pgon, winding_rule_t winding_rule) -{ - NT3 winding_sum = NT3(0); - CGAL_Point_2 p2; - CGAL_Ray_2 eastray(p1,CGAL_Direction_2(1,0)); - for (size_t i=0;i(&obj); - if (point_test) { - p2 = *point_test; - CGAL_Vector_2 v1( p1, p2 ); - CGAL_Vector_2 v2( p2, head ); - NT3 this_winding = wedge( v1, v2 ); - winding_sum += sign(this_winding); - } else { - continue; - } - } - if (winding_sum != NT3(0) && winding_rule == NONZERO_WINDING ) return true; - return false; -} - -projection_t find_good_projection( CGAL_Plane_3 &plane ) -{ - projection_t goodproj; - goodproj.plane = NONE; - goodproj.flip = false; - NT3 qxy = plane.a()*plane.a()+plane.b()*plane.b(); - NT3 qyz = plane.b()*plane.b()+plane.c()*plane.c(); - NT3 qxz = plane.a()*plane.a()+plane.c()*plane.c(); - NT3 min = std::min(qxy,std::min(qyz,qxz)); - if (min==qxy) { - goodproj.plane = XYPLANE; - if (sign(plane.c())>0) goodproj.flip = true; - } else if (min==qyz) { - goodproj.plane = YZPLANE; - if (sign(plane.a())>0) goodproj.flip = true; - } else if (min==qxz) { - goodproj.plane = XZPLANE; - if (sign(plane.b())<0) goodproj.flip = true; - } else PRINT("ERROR: failed to find projection"); - return goodproj; + for(CDT::All_faces_iterator it = cdt.all_faces_begin(); it != cdt.all_faces_end(); ++it) { + it->info().nesting_level = -1; + } + std::list border; + mark_domains(cdt, cdt.infinite_face(), 0, border); + while (!border.empty()) { + CDT::Edge e = border.front(); + border.pop_front(); + CDT::Face_handle n = e.first->neighbor(e.second); + if (n->info().nesting_level == -1) { + mark_domains(cdt, n, e.first->info().nesting_level+1, border); + } + } } namespace CGALUtils { -/* given a single near-planar 3d polygon with holes, tessellate into a - sequence of polygons without holes. as of writing, this means conversion - into a sequence of 3d triangles. the given plane should be the same plane - holding the polygon and it's holes. */ - bool tessellate3DFaceWithHoles(std::vector &polygons, - std::vector &triangles, - CGAL_Plane_3 &plane) + /*! + polygons define a polygon, potentially with holes. Each contour + should be added as a separate PolygonK instance. + The tessellator will handle almost planar polygons. + + If the normal is given, we will assume this as the normal vector of the polygon. + Otherwise, we will try to calculate it using Newell's method. + + The resulting triangles is added to the given triangles vector. + */ + bool tessellatePolygonWithHoles(const PolyholeK &polygons, + Polygons &triangles, + const K::Vector_3 *normal) { - if (polygons.size()==1 && polygons[0].size()==3) { + // No polygon. FIXME: Will this ever happen or can we assert here? + if (polygons.empty()) return false; + + // No hole + if (polygons.size() == 1) return tessellatePolygon(polygons.front(), triangles, normal); + + K::Vector_3 normalvec; + if (normal) { + normalvec = *normal; + } + else { + // Calculate best guess at face normal using Newell's method + CGAL::normal_vector_newell_3(polygons.front().begin(), polygons.front().end(), normalvec); + } + + // Pass the normal vector to the (undocumented) + // CGAL::Triangulation_2_filtered_projection_traits_3. This + // trait deals with projection from 3D to 2D using the normal + // vector as a hint, and allows for near-planar polygons to be passed to + // the Constrained Delaunay Triangulator. + Projection actualProjection(normalvec); + CDT cdt(actualProjection); + BOOST_FOREACH(const PolygonK &poly, polygons) { + for (size_t i=0;iinfo().in_domain()) { + Polygon tri; + for (int i=0;i<3;i++) { + Vertex3K v = cdt.triangle(fit)[i]; + tri.push_back(Vector3d(v.x(), v.y(), v.z())); + } + triangles.push_back(tri); + } + } + + return false; + } + + bool tessellatePolygon(const PolygonK &polygon, + Polygons &triangles, + const K::Vector_3 *normal) + { + if (polygon.size() == 3) { PRINTD("input polygon has 3 points. shortcut tessellation."); - CGAL_Polygon_3 t; - t.push_back(polygons[0][2]); - t.push_back(polygons[0][1]); - t.push_back(polygons[0][0]); - triangles.push_back( t ); + Polygon t; + t.push_back(Vector3d(polygon[0].x(), polygon[0].y(), polygon[0].z())); + t.push_back(Vector3d(polygon[1].x(), polygon[1].y(), polygon[1].z())); + t.push_back(Vector3d(polygon[2].x(), polygon[2].y(), polygon[2].z())); + triangles.push_back(t); return false; } - bool err = false; - CDT cdt; - std::map vertmap; - PRINTD("finding good projection"); - projection_t goodproj = find_good_projection( plane ); - - PRINTDB("plane %s",plane ); - PRINTDB("proj: %i %i",goodproj.plane % goodproj.flip); - PRINTD("Inserting points and edges into Constrained Delaunay Triangulation"); - std::vector< std::vector > polygons2d; - for (size_t i=0;i vhandles; - std::vector polygon2d; - for (size_t j=0;j list_of_seeds; - for (size_t i=1;i &pgon = polygons2d[i]; - for (size_t j=0;j::iterator li = list_of_seeds.begin(); - for (;li!=list_of_seeds.end();li++) { - //PRINTB("seed %s",*li); - double x = CGAL::to_double( li->x() ); - double y = CGAL::to_double( li->y() ); - PRINTDB("seed %f,%f",x%y); + + // Pass the normal vector to the (undocumented) + // CGAL::Triangulation_2_filtered_projection_traits_3. This + // trait deals with projection from 3D to 2D using the normal + // vector as a hint, and allows for near-planar polygons to be passed to + // the Constrained Delaunay Triangulator. + Projection actualProjection(normalvec); + CDT cdt(actualProjection); + for (size_t i=0;i() ); - - PRINTD("meshing done"); - // this fails because it calls is_simple and is_simple fails on many - // Nef Polyhedron faces - //CGAL::Orientation original_orientation = - // CGAL::orientation_2( orienpgon.begin(), orienpgon.end() ); + + //Mark facets that are inside the domain bounded by the polygon + mark_domains(cdt); + // Iterate over the resulting faces CDT::Finite_faces_iterator fit; - for( fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end(); fit++ ) - { - if(fit->is_in_domain()) { - CDTPoint p1 = cdt.triangle( fit )[0]; - CDTPoint p2 = cdt.triangle( fit )[1]; - CDTPoint p3 = cdt.triangle( fit )[2]; - CGAL_Point_3 cp1,cp2,cp3; - CGAL_Polygon_3 pgon; - if (vertmap.count(p1)) cp1 = vertmap[p1]; - else err = deproject( p1, goodproj, plane, cp1 ); - if (vertmap.count(p2)) cp2 = vertmap[p2]; - else err = deproject( p2, goodproj, plane, cp2 ); - if (vertmap.count(p3)) cp3 = vertmap[p3]; - else err = deproject( p3, goodproj, plane, cp3 ); - if (err) PRINT("WARNING: 2d->3d deprojection failure"); - pgon.push_back( cp1 ); - pgon.push_back( cp2 ); - pgon.push_back( cp3 ); - triangles.push_back( pgon ); + for (fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end(); fit++) { + if (fit->info().in_domain()) { + Polygon tri; + for (int i=0;i<3;i++) { + K::Point_3 v = cdt.triangle(fit)[i]; + tri.push_back(Vector3d(v.x(), v.y(), v.z())); + } + triangles.push_back(tri); } } - PRINTDB("built %i triangles",triangles.size()); - return err; + return false; } -}; + +}; // namespace CGALUtils + diff --git a/src/cgalutils.cc b/src/cgalutils.cc index a609bd63..5338a14e 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -21,21 +21,21 @@ #include #include +namespace Eigen { + size_t hash_value(Vector3d const &v) { + size_t seed = 0; + for (int i=0;i<3;i++) boost::hash_combine(seed, v[i]); + return seed; + } +} + namespace /* anonymous */ { template Result vector_convert(V const& v) { return Result(CGAL::to_double(v[0]),CGAL::to_double(v[1]),CGAL::to_double(v[2])); } -#undef GEN_SURFACE_DEBUG - - namespace Eigen { - size_t hash_value(Vector3d const &v) { - size_t seed = 0; - for (int i=0;i<3;i++) boost::hash_combine(seed, v[i]); - return seed; - } - } +#define GEN_SURFACE_DEBUG class CGAL_Build_PolySet : public CGAL::Modifier_base { @@ -138,7 +138,6 @@ namespace /* anonymous */ { void operator()(CGAL_HDS& hds) { CGAL_Polybuilder B(hds, true); - typedef boost::tuple BuilderVertex; Reindexer vertices; std::vector indices(3); @@ -230,14 +229,14 @@ namespace /* anonymous */ { vi = in_poly.vertices_begin(), end = in_poly.vertices_end(); vi != end ; ++vi) { - typename Polyhedron_output::Point_3 p(::CGAL::to_double( vi->point().x()), - ::CGAL::to_double( vi->point().y()), - ::CGAL::to_double( vi->point().z())); + typename Polyhedron_output::Point_3 p(::CGAL::to_double(vi->point().x()), + ::CGAL::to_double(vi->point().y()), + ::CGAL::to_double(vi->point().z())); builder.add_vertex(p); } typedef CGAL::Inverse_index Index; - Index index( in_poly.vertices_begin(), in_poly.vertices_end()); + Index index(in_poly.vertices_begin(), in_poly.vertices_end()); for(Facet_const_iterator fi = in_poly.facets_begin(), end = in_poly.facets_end(); @@ -245,13 +244,13 @@ namespace /* anonymous */ { { HFCC hc = fi->facet_begin(); HFCC hc_end = hc; - // std::size_t n = circulator_size( hc); - // CGAL_assertion( n >= 3); + // std::size_t n = circulator_size(hc); + // CGAL_assertion(n >= 3); builder.begin_facet (); do { builder.add_vertex_to_facet(index[hc->vertex()]); ++hc; - } while( hc != hc_end); + } while(hc != hc_end); builder.end_facet(); } builder.end_surface(); @@ -300,19 +299,18 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) try { CGAL_Polyhedron P; bool err = CGALUtils::createPolyhedronFromPolySet(ps, P); - // if (!err) { - // PRINTB("Polyhedron is closed: %d", P.is_closed()); - // PRINTB("Polyhedron is valid: %d", P.is_valid(false, 0)); - // } + if (!err) { + PRINTDB("Polyhedron is closed: %d", P.is_closed()); + PRINTDB("Polyhedron is valid: %d", P.is_valid(false, 0)); + } if (!err) N = new CGAL_Nef_polyhedron3(P); } catch (const CGAL::Assertion_exception &e) { - if (std::string(e.what()).find("Plane_constructor")!=std::string::npos) { - if (std::string(e.what()).find("has_on")!=std::string::npos) { + if (std::string(e.what()).find("Plane_constructor")!=std::string::npos && + std::string(e.what()).find("has_on")!=std::string::npos) { PRINT("PolySet has nonplanar faces. Attempting alternate construction"); plane_error=true; - } } else { PRINTB("CGAL error in CGAL_Nef_polyhedron3(): %s", e.what()); } @@ -461,7 +459,7 @@ namespace CGALUtils { if ((ps && ps->is_convex()) || (!ps && is_weakly_convex(poly))) { - PRINTDB("Minkowski: child %d is convex and %s",i % (ps?"PolySet":"Nef") ); + PRINTDB("Minkowski: child %d is convex and %s",i % (ps?"PolySet":"Nef")); P[i].push_back(poly); } else { CGAL_Nef_polyhedron3 decomposed_nef; @@ -480,7 +478,7 @@ namespace CGALUtils { // the first volume is the outer volume, which ignored in the decomposition CGAL_Nef_polyhedron3::Volume_const_iterator ci = ++decomposed_nef.volumes_begin(); - for( ; ci != decomposed_nef.volumes_end(); ++ci) { + for(; ci != decomposed_nef.volumes_end(); ++ci) { if(ci->mark()) { CGAL_Polyhedron poly; decomposed_nef.convert_inner_shell_to_polyhedron(ci->shells_begin(), poly); @@ -844,13 +842,13 @@ namespace CGALUtils { // dont use z of 0. there are bugs in CGAL. double inf = 1e8; double eps = 0.001; - CGAL_Point_3 minpt( -inf, -inf, -eps ); - CGAL_Point_3 maxpt( inf, inf, eps ); - CGAL_Iso_cuboid_3 bigcuboid( minpt, maxpt ); - for ( int i=0;i<8;i++ ) pts.push_back( bigcuboid.vertex(i) ); + CGAL_Point_3 minpt(-inf, -inf, -eps); + CGAL_Point_3 maxpt( inf, inf, eps); + CGAL_Iso_cuboid_3 bigcuboid(minpt, maxpt); + for (int i=0;i<8;i++) pts.push_back(bigcuboid.vertex(i)); CGAL_Polyhedron bigbox; CGAL::convex_hull_3(pts.begin(), pts.end(), bigbox); - CGAL_Nef_polyhedron3 nef_bigbox( bigbox ); + CGAL_Nef_polyhedron3 nef_bigbox(bigbox); newN.p3.reset(new CGAL_Nef_polyhedron3(nef_bigbox.intersection(*N.p3))); } catch (const CGAL::Failure_exception &e) { @@ -864,18 +862,18 @@ namespace CGALUtils { return poly; } - PRINTDB("%s",OpenSCAD::svg_header( 480, 100000 )); + PRINTDB("%s",OpenSCAD::svg_header(480, 100000)); try { ZRemover zremover; CGAL_Nef_polyhedron3::Volume_const_iterator i; CGAL_Nef_polyhedron3::Shell_entry_const_iterator j; CGAL_Nef_polyhedron3::SFace_const_handle sface_handle; - for ( i = newN.p3->volumes_begin(); i != newN.p3->volumes_end(); ++i ) { + for (i = newN.p3->volumes_begin(); i != newN.p3->volumes_end(); ++i) { PRINTDB("",i->mark()); - for ( j = i->shells_begin(); j != i->shells_end(); ++j ) { + for (j = i->shells_begin(); j != i->shells_end(); ++j) { PRINTDB(""); } PRINTD(""); @@ -909,7 +907,7 @@ namespace CGALUtils { // can be optimized by rewriting bounding_box to accept vertices CGAL_forall_vertices(vi, N) points.push_back(vi->point()); - if (points.size()) result = CGAL::bounding_box( points.begin(), points.end() ); + if (points.size()) result = CGAL::bounding_box(points.begin(), points.end()); return result; } @@ -1052,25 +1050,26 @@ namespace CGALUtils { formats) do not allow for holes in their faces. The function documents the method used to deal with this */ +#if 0 bool createPolySetFromNefPolyhedron3(const CGAL_Nef_polyhedron3 &N, PolySet &ps) { bool err = false; CGAL_Nef_polyhedron3::Halffacet_const_iterator hfaceti; - CGAL_forall_halffacets( hfaceti, N ) { - CGAL::Plane_3 plane( hfaceti->plane() ); - std::vector polygons; + CGAL_forall_halffacets(hfaceti, N) { + CGAL::Plane_3 plane(hfaceti->plane()); + std::vector polyholes; // the 0-mark-volume is the 'empty' volume of space. skip it. if (hfaceti->incident_volume()->mark()) continue; CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator cyclei; - CGAL_forall_facet_cycles_of( cyclei, hfaceti ) { + CGAL_forall_facet_cycles_of(cyclei, hfaceti) { CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c1(cyclei); CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c2(c1); CGAL_Polygon_3 polygon; - CGAL_For_all( c1, c2 ) { + CGAL_For_all(c1, c2) { CGAL_Point_3 p = c1->source()->center_vertex()->point(); - polygon.push_back( p ); + polygon.push_back(p); } - polygons.push_back( polygon ); + polyholes.push_back(polygon); } /* at this stage, we have a sequence of polygons. the first @@ -1079,28 +1078,125 @@ namespace CGALUtils { options here to get rid of the holes. we choose to go ahead and let the tessellater deal with the holes, and then just output the resulting 3d triangles*/ + + CGAL::Vector_3 nvec = plane.orthogonal_vector(); + K::Vector_3 normal(CGAL::to_double(nvec.x()), CGAL::to_double(nvec.y()), CGAL::to_double(nvec.z())); std::vector triangles; - bool err = CGALUtils::tessellate3DFaceWithHoles(polygons, triangles, plane); + bool err = CGALUtils::tessellate3DFaceWithHoles(polyholes, triangles, plane); if (!err) { - for (size_t i=0;i=0;j--) { - double x1,y1,z1; - x1 = CGAL::to_double(triangles[i][j].x()); - y1 = CGAL::to_double(triangles[i][j].y()); - z1 = CGAL::to_double(triangles[i][j].z()); - ps.append_vertex(x1,y1,z1); - } + ps.append_vertex(CGAL::to_double(p[2].x()), CGAL::to_double(p[2].y()), CGAL::to_double(p[2].z())); + ps.append_vertex(CGAL::to_double(p[1].x()), CGAL::to_double(p[1].y()), CGAL::to_double(p[1].z())); + ps.append_vertex(CGAL::to_double(p[0].x()), CGAL::to_double(p[0].y()), CGAL::to_double(p[0].z())); } } } return err; } +#endif +#if 0 + bool createPolySetFromNefPolyhedron3(const CGAL_Nef_polyhedron3 &N, PolySet &ps) + { + bool err = false; + CGAL_Nef_polyhedron3::Halffacet_const_iterator hfaceti; + CGAL_forall_halffacets(hfaceti, N) { + CGAL::Plane_3 plane(hfaceti->plane()); + std::vector polyholes; + // the 0-mark-volume is the 'empty' volume of space. skip it. + if (hfaceti->incident_volume()->mark()) continue; + CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator cyclei; + CGAL_forall_facet_cycles_of(cyclei, hfaceti) { + CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c1(cyclei); + CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c2(c1); + CGAL_Polygon_3 polygon; + CGAL_For_all(c1, c2) { + CGAL_Point_3 p = c1->source()->center_vertex()->point(); + polygon.push_back(p); + } + polyholes.push_back(polygon); + } + /* at this stage, we have a sequence of polygons. the first + is the "outside edge' or 'body' or 'border', and the rest of the + polygons are 'holes' within the first. there are several + options here to get rid of the holes. we choose to go ahead + and let the tessellater deal with the holes, and then + just output the resulting 3d triangles*/ + + CGAL::Vector_3 nvec = plane.orthogonal_vector(); + K::Vector_3 normal(CGAL::to_double(nvec.x()), CGAL::to_double(nvec.y()), CGAL::to_double(nvec.z())); + std::vector triangles; + bool err = CGALUtils::tessellate3DFaceWithHolesNew(polyholes, triangles, plane); + if (!err) { + BOOST_FOREACH(const Polygon &p, triangles) { + if (p.size() != 3) { + PRINT("WARNING: triangle doesn't have 3 points. skipping"); + continue; + } + ps.append_poly(); + ps.append_vertex(p[0].x(), p[0].y(), p[0].z()); + ps.append_vertex(p[1].x(), p[1].y(), p[1].z()); + ps.append_vertex(p[2].x(), p[2].y(), p[2].z()); + } + } + } + return err; + } +#endif +#if 1 + bool createPolySetFromNefPolyhedron3(const CGAL_Nef_polyhedron3 &N, PolySet &ps) + { + bool err = false; + CGAL_Nef_polyhedron3::Halffacet_const_iterator hfaceti; + CGAL_forall_halffacets(hfaceti, N) { + CGAL::Plane_3 plane(hfaceti->plane()); + PolyholeK polyholes; + // the 0-mark-volume is the 'empty' volume of space. skip it. + if (hfaceti->incident_volume()->mark()) continue; + CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator cyclei; + CGAL_forall_facet_cycles_of(cyclei, hfaceti) { + CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c1(cyclei); + CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c2(c1); + PolygonK polygon; + CGAL_For_all(c1, c2) { + CGAL_Point_3 p = c1->source()->center_vertex()->point(); + polygon.push_back(Vertex3K(CGAL::to_double(p.x()), CGAL::to_double(p.y()), CGAL::to_double(p.z()))); + } + polyholes.push_back(polygon); + } + + /* at this stage, we have a sequence of polygons. the first + is the "outside edge' or 'body' or 'border', and the rest of the + polygons are 'holes' within the first. there are several + options here to get rid of the holes. we choose to go ahead + and let the tessellater deal with the holes, and then + just output the resulting 3d triangles*/ + + CGAL::Vector_3 nvec = plane.orthogonal_vector(); + K::Vector_3 normal(CGAL::to_double(nvec.x()), CGAL::to_double(nvec.y()), CGAL::to_double(nvec.z())); + std::vector triangles; + bool err = CGALUtils::tessellatePolygonWithHoles(polyholes, triangles, &normal); + if (!err) { + BOOST_FOREACH(const Polygon &p, triangles) { + if (p.size() != 3) { + PRINT("WARNING: triangle doesn't have 3 points. skipping"); + continue; + } + ps.append_poly(); + ps.append_vertex(p[0].x(), p[0].y(), p[0].z()); + ps.append_vertex(p[1].x(), p[1].y(), p[1].z()); + ps.append_vertex(p[2].x(), p[2].y(), p[2].z()); + } + } + } + return err; + } +#endif CGAL_Nef_polyhedron *createNefPolyhedronFromGeometry(const Geometry &geom) { const PolySet *ps = dynamic_cast(&geom); @@ -1117,10 +1213,10 @@ namespace CGALUtils { }; // namespace CGALUtils -void ZRemover::visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet ) +void ZRemover::visit(CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet) { PRINTDB(" ",hfacet->mark()); - if ( hfacet->plane().orthogonal_direction() != this->up ) { + if (hfacet->plane().orthogonal_direction() != this->up) { PRINTD(" "); PRINTD(" "); return; @@ -1130,36 +1226,36 @@ void ZRemover::visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet ) CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator fci; int contour_counter = 0; - CGAL_forall_facet_cycles_of( fci, hfacet ) { - if ( fci.is_shalfedge() ) { + CGAL_forall_facet_cycles_of(fci, hfacet) { + if (fci.is_shalfedge()) { PRINTD(" "); CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c1(fci), cend(c1); std::vector contour; - CGAL_For_all( c1, cend ) { + CGAL_For_all(c1, cend) { CGAL_Nef_polyhedron3::Point_3 point3d = c1->source()->target()->point(); CGAL_Nef_polyhedron2::Explorer::Point point2d(CGAL::to_double(point3d.x()), CGAL::to_double(point3d.y())); - contour.push_back( point2d ); + contour.push_back(point2d); } if (contour.size()==0) continue; if (OpenSCAD::debug!="") - PRINTDB(" ", CGAL::is_simple_2( contour.begin(), contour.end() ) ); + PRINTDB(" ", CGAL::is_simple_2(contour.begin(), contour.end())); - tmpnef2d.reset( new CGAL_Nef_polyhedron2( contour.begin(), contour.end(), boundary ) ); + tmpnef2d.reset(new CGAL_Nef_polyhedron2(contour.begin(), contour.end(), boundary)); - if ( contour_counter == 0 ) { - PRINTDB(" ", contour.size() ); + if (contour_counter == 0) { + PRINTDB(" ", contour.size()); *(output_nefpoly2d) += *(tmpnef2d); } else { - PRINTDB(" ", contour.size() ); + PRINTDB(" ", contour.size()); *(output_nefpoly2d) *= *(tmpnef2d); } /*log << "\n\n" - << OpenSCAD::dump_svg( *tmpnef2d ) << "\n" + << OpenSCAD::dump_svg(*tmpnef2d) << "\n" << "\n\n" - << OpenSCAD::dump_svg( *output_nefpoly2d ) << "\n";*/ + << OpenSCAD::dump_svg(*output_nefpoly2d) << "\n";*/ contour_counter++; } else { diff --git a/src/cgalutils.h b/src/cgalutils.h index f660f5aa..225e93f1 100644 --- a/src/cgalutils.h +++ b/src/cgalutils.h @@ -5,6 +5,12 @@ #include "CGAL_Nef_polyhedron.h" #include "enums.h" +#include +typedef CGAL::Epick K; +typedef CGAL::Point_3 Vertex3K; +typedef std::vector PolygonK; +typedef std::vector PolyholeK; + namespace CGALUtils { bool applyHull(const Geometry::ChildList &children, PolySet &P); void applyOperator(const Geometry::ChildList &children, CGAL_Nef_polyhedron &dest, OpenSCADOperator op); @@ -19,8 +25,16 @@ namespace CGALUtils { bool createPolySetFromNefPolyhedron3(const CGAL_Nef_polyhedron3 &N, PolySet &ps); bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p); - typedef std::vector CGAL_Polygon_3; - bool tessellate3DFaceWithHoles(std::vector &polygons, + bool tessellatePolygon(const PolygonK &polygon, + Polygons &triangles, + const K::Vector_3 *normal = NULL); + bool tessellatePolygonWithHoles(const PolyholeK &polygons, + Polygons &triangles, + const K::Vector_3 *normal = NULL); + bool tessellate3DFaceWithHolesNew(std::vector &polygons, + Polygons &triangles, + CGAL::Plane_3 &plane); + bool tessellate3DFaceWithHoles(std::vector &polygons, std::vector &triangles, CGAL::Plane_3 &plane); }; diff --git a/src/polyset-utils.cc b/src/polyset-utils.cc index b55dfc4d..5587be6e 100644 --- a/src/polyset-utils.cc +++ b/src/polyset-utils.cc @@ -2,25 +2,7 @@ #include "polyset.h" #include "Polygon2d.h" #include "printutils.h" -#include "cgal.h" - -#ifdef NDEBUG -#define PREV_NDEBUG NDEBUG -#undef NDEBUG -#endif -#include -#include -#include -#ifdef PREV_NDEBUG -#define NDEBUG PREV_NDEBUG -#endif - -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Triangulation_2_filtered_projection_traits_3 Projection; -typedef CGAL::Triangulation_data_structure_2 < - CGAL::Triangulation_vertex_base_2, - CGAL::Constrained_triangulation_face_base_2 > Tds; -typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +#include "cgalutils.h" #include @@ -60,7 +42,7 @@ namespace PolysetUtils { faces. As of writing, our only tessellation method is triangulation using CGAL's Constrained Delaunay algorithm. This code assumes the input polyset has simple polygon faces with no holes. - The tessellation will be robust wrt. degenerate and self-intersecting + The tessellation will be robust wrt. degenerate and self-intersecting */ void tessellate_faces(const PolySet &inps, PolySet &outps) { int degeneratePolygons = 0; @@ -76,35 +58,12 @@ namespace PolysetUtils { } else { // Build a data structure that CGAL accepts - std::vector cgalpoints; + PolygonK cgalpoints; BOOST_FOREACH(const Vector3d &v, pgon) { - cgalpoints.push_back(K::Point_3(v[0], v[1], v[2])); + cgalpoints.push_back(Vertex3K(v[0], v[1], v[2])); } - // Calculate best guess at face normal using Newell's method - K::Vector_3 normal; - CGAL::normal_vector_newell_3(cgalpoints.begin(), cgalpoints.end(), normal); - // Pass the normal vector to the (undocumented) - // CGAL::Triangulation_2_filtered_projection_traits_3. This - // trait deals with projection from 3D to 2D using the normal - // vector as a hint, and allows for near-planar polygons to be passed to - // the Constrained Delaunay Triangulator. - Projection actualProjection(normal); - CDT cdt(actualProjection); - for (size_t i=0;i Date: Mon, 1 Dec 2014 01:06:15 -0500 Subject: [PATCH 082/263] Tagged stlpngtest_bad-stl-wing as a bug --- tests/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2d012a48..d4703592 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1350,6 +1350,8 @@ set_test_config(Bugs offpngtest_polyhedron-tests offpngtest_bad-stl-pcbvicebar offpngtest_bad-stl-tardis offpngtest_bad-stl-wing) +# No issue - this was introduced when fixing #1033 +set_test_config(Bugs stlpngtest_bad-stl-wing) add_cmdline_test(monotonepngtest EXE ${OPENSCAD_BINPATH} ARGS --colorscheme=Monotone --enable=text --render -o SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(stlpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES}) From 80050e94db9e6d358b63ec126d70f5c67997d797 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 1 Dec 2014 02:51:56 -0500 Subject: [PATCH 083/263] merge fixes --- src/LibraryInfo.cc | 2 +- tests/csgtexttest.cc | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/LibraryInfo.cc b/src/LibraryInfo.cc index f736cd22..83f3875c 100644 --- a/src/LibraryInfo.cc +++ b/src/LibraryInfo.cc @@ -93,7 +93,7 @@ std::string LibraryInfo::info() << "\nGLib version: " << GLIB_MAJOR_VERSION << "." << GLIB_MINOR_VERSION << "." << GLIB_MICRO_VERSION << "\nApplication Path: " << PlatformUtils::applicationPath() << "\nDocuments Path: " << PlatformUtils::documentsPath() - << "\nResource Path: " << PlatformUtils::resourcesPath() + << "\nResource Path: " << PlatformUtils::resourceBasePath() << "\nUser Library Path: " << PlatformUtils::userLibraryPath() << "\nUser Config Path: " << PlatformUtils::userConfigPath() << "\nBackup Path: " << PlatformUtils::backupPath() diff --git a/tests/csgtexttest.cc b/tests/csgtexttest.cc index 1c65a413..c7a6855d 100644 --- a/tests/csgtexttest.cc +++ b/tests/csgtexttest.cc @@ -81,8 +81,7 @@ int main(int argc, char **argv) std::string applicationpath = boosty::stringy(fs::path(argv[0]).branch_path()); PlatformUtils::registerApplicationPath(applicationpath); - parser_init(applicationpath); - add_librarydir(boosty::stringy(fs::path(argv[0]).branch_path() / "../libraries")); + parser_init(); ModuleContext top_ctx; top_ctx.registerBuiltin(); From 96cde0a2659eb4c244494cacb573fc9e4900ebaa Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Mon, 1 Dec 2014 12:10:08 +0100 Subject: [PATCH 084/263] MCAD not available should not be a critical error, only a warning --- tests/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2d5f05f1..b891d48b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -71,7 +71,8 @@ endif() # MCAD if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../libraries/MCAD/__init__.py) - message(FATAL_ERROR "MCAD not found. You can install from the OpenSCAD root as follows: \n git submodule update --init") + #message(FATAL_ERROR "MCAD not found. You can install from the OpenSCAD root as follows: \n git submodule update --init") + message(STATUS "MCAD not found, no tests of MCAD possible. You can install from the OpenSCAD root as follows: \n git submodule update --init") endif() # NULLGL - Allow us to build without OpenGL(TM). run 'cmake .. -DNULLGL=1' From 415349e87349b2a0c6d1dab0d32589c083282658 Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Mon, 1 Dec 2014 12:20:16 +0100 Subject: [PATCH 085/263] Missing quotes in argument list target properties --- tests/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b891d48b..ce45ee1c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -738,13 +738,13 @@ target_link_libraries(tests-cgal tests-common ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_L # if (NOT NULLGL) add_library(tests-nocgal STATIC ${NOCGAL_SOURCES}) - set_target_properties(tests-nocgal PROPERTIES COMPILE_FLAGS ${ENABLE_OPENCSG_FLAG}) + set_target_properties(tests-nocgal PROPERTIES COMPILE_FLAGS "${ENABLE_OPENCSG_FLAG}") target_link_libraries(tests-nocgal tests-common) else() message(STATUS "NULLGL: cannot use GL/GLU tessellator. see dxftess.cc") message(STATUS "NULLGL: non-CGAL tests will use CGAL's tessellator") add_library(tests-nocgal STATIC ${NOCGAL_SOURCES}) - set_target_properties(tests-nocgal PROPERTIES COMPILE_FLAGS ${ENABLE_OPENCSG_FLAG}) + set_target_properties(tests-nocgal PROPERTIES COMPILE_FLAGS "${ENABLE_OPENCSG_FLAG}") target_link_libraries(tests-nocgal tests-common) endif() From 57974baa13328cef5e83fc66786d65e2d5cfe3c8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 1 Dec 2014 16:47:00 -0500 Subject: [PATCH 086/263] Silence verbose debug output --- src/cgalutils.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 5338a14e..5693ed60 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -35,7 +35,7 @@ namespace /* anonymous */ { return Result(CGAL::to_double(v[0]),CGAL::to_double(v[1]),CGAL::to_double(v[2])); } -#define GEN_SURFACE_DEBUG +#undef GEN_SURFACE_DEBUG class CGAL_Build_PolySet : public CGAL::Modifier_base { From 582d5dde8c4da16047d3e03f84f4711cb5bf5a2c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 1 Dec 2014 16:52:04 -0500 Subject: [PATCH 087/263] #1030 bugfix: contexts need a parent, or it may crash --- src/func.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/func.cc b/src/func.cc index 96a7b887..c7e26193 100644 --- a/src/func.cc +++ b/src/func.cc @@ -149,8 +149,8 @@ ValuePtr FunctionTailRecursion::evaluate(const Context *ctx, const EvalContext * c.setVariables(definition_arguments, evalctx); EvalContext ec(&c, call->call_arguments); + Context tmp(&c); while (invert ^ expr->first->evaluate(&c)) { - Context tmp; tmp.setVariables(definition_arguments, &ec); c.apply_variables(tmp); } From 0067aafbb01a40abf802eb649c0f349f82b84bed Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 1 Dec 2014 17:34:47 -0500 Subject: [PATCH 088/263] Forgot to commit Value -> ValuePtr fix to header --- src/module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module.h b/src/module.h index cf14d950..504eb2a8 100644 --- a/src/module.h +++ b/src/module.h @@ -111,7 +111,7 @@ public: bool hasIncludes() const { return !this->includes.empty(); } bool usesLibraries() const { return !this->usedlibs.empty(); } bool isHandlingDependencies() const { return this->is_handling_dependencies; } - Value lookup_variable(const std::string &name) const; + ValuePtr lookup_variable(const std::string &name) const; typedef boost::unordered_set ModuleContainer; ModuleContainer usedlibs; From 6898b49a08f1f294a9e6cb656a82ebdfa393dbb0 Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Tue, 2 Dec 2014 12:22:42 +0100 Subject: [PATCH 089/263] Revert "MCAD not available should not be a critical error, only a warning" This reverts commit 96cde0a2659eb4c244494cacb573fc9e4900ebaa. --- tests/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ce45ee1c..7901d1b6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -71,8 +71,7 @@ endif() # MCAD if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../libraries/MCAD/__init__.py) - #message(FATAL_ERROR "MCAD not found. You can install from the OpenSCAD root as follows: \n git submodule update --init") - message(STATUS "MCAD not found, no tests of MCAD possible. You can install from the OpenSCAD root as follows: \n git submodule update --init") + message(FATAL_ERROR "MCAD not found. You can install from the OpenSCAD root as follows: \n git submodule update --init") endif() # NULLGL - Allow us to build without OpenGL(TM). run 'cmake .. -DNULLGL=1' From 3e0ef9dd6870f913cdb08b8a15336554d9fa4da1 Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Mon, 1 Dec 2014 13:59:58 +0100 Subject: [PATCH 090/263] Needed changes to have NULLGL compiling. Resulting prog compiles to output stl --- src/NULLGL.cc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/NULLGL.cc b/src/NULLGL.cc index 496810c2..b0d360fc 100644 --- a/src/NULLGL.cc +++ b/src/NULLGL.cc @@ -4,17 +4,19 @@ GLView::GLView() {} void GLView::setRenderer(Renderer* r) {} void GLView::initializeGL() {} void GLView::resizeGL(int w, int h) {} -void GLView::setupGimbalCamPerspective() {} -void GLView::setupGimbalCamOrtho(double distance, bool offset) {} -void GLView::setupVectorCamPerspective() {} -void GLView::setupVectorCamOrtho(bool offset) {} -void GLView::setCamera( Camera &cam ) {} +//void GLView::setupGimbalCamPerspective() {} +//void GLView::setupGimbalCamOrtho(double distance, bool offset) {} +//void GLView::setupVectorCamPerspective() {} +//void GLView::setupVectorCamOrtho(bool offset) {} +void GLView::setCamera(const Camera &cam ) {} void GLView::paintGL() {} -void GLView::vectorCamPaintGL() {} -void GLView::gimbalCamPaintGL() {} +//void GLView::vectorCamPaintGL() {} +//void GLView::gimbalCamPaintGL() {} void GLView::showSmallaxes() {} void GLView::showAxes() {} void GLView::showCrosshairs() {} +void GLView::setColorScheme(const ColorScheme &cs){assert(false && "not implemented");} +void GLView::setColorScheme(const std::string &cs) {assert(false && "not implemented");} #include "ThrownTogetherRenderer.h" @@ -23,12 +25,16 @@ ThrownTogetherRenderer::ThrownTogetherRenderer(CSGChain *root_chain, void ThrownTogetherRenderer::draw(bool /*showfaces*/, bool showedges) const {} void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, bool background, bool showedges, bool fberror) const {} +BoundingBox ThrownTogetherRenderer::getBoundingBox() const {assert(false && "not implemented");} #include "CGALRenderer.h" CGALRenderer::CGALRenderer(shared_ptr geom) {} CGALRenderer::~CGALRenderer() {} void CGALRenderer::draw(bool showfaces, bool showedges) const {} +BoundingBox CGALRenderer::getBoundingBox() const {assert(false && "not implemented");} +void CGALRenderer::setColorScheme(const ColorScheme &cs){assert(false && "not implemented");} + #include "system-gl.h" From b894166dea17d501f89bf171a12c45b47f4ae956 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 2 Dec 2014 22:45:08 +0100 Subject: [PATCH 091/263] Add tests to check tail recursion eliminiation. --- testdata/scad/misc/tail-recursion-tests.scad | 31 +++++++++++++++++++ tests/CMakeLists.txt | 1 + .../tail-recursion-tests-expected.echo | 6 ++++ 3 files changed, 38 insertions(+) create mode 100644 testdata/scad/misc/tail-recursion-tests.scad create mode 100644 tests/regression/echotest/tail-recursion-tests-expected.echo diff --git a/testdata/scad/misc/tail-recursion-tests.scad b/testdata/scad/misc/tail-recursion-tests.scad new file mode 100644 index 00000000..5795530a --- /dev/null +++ b/testdata/scad/misc/tail-recursion-tests.scad @@ -0,0 +1,31 @@ +function substring(text, start, end = -1, idx = -1, res = "") = + idx < end && idx < len(text) + ? substring(text, start, end, idx < 0 ? start + 1 : idx + 1, str(res, text[idx < 0 ? start : idx])) + : res; + +// normal recursion, no tail-recursion elimination possible +function f3a(a, ret = 0) = a <= 0 ? 0 : a + f3a(a - 1); +echo("without tail-recursion eliminiation: ", f3a(100)); + +// this allows tail-recursion eliminiation +function f3b(a, ret = 0) = a <= 0 ? ret : f3b(a - 1, ret + a); +echo("with tail-recursion eliminiation: ", f3b(100)); + +// check tail-recursion eliminiation by using a high loop count +function f3c(a, ret = 0) = a <= 0 ? ret : f3c(a - 1, ret + a); +echo("with tail-recursion eliminiation: ", f3c(2000)); + +// use nested function call +function f1(x, y = []) = x <= 0 ? y : f1(x - 1, concat(y, [[x, x]])); +echo(f1(2000)[20]); + +// recursion in the "false" part of the ternary operator +function c(a, b) = chr(a % 26 + b); +function f2a(x, y = 0, t = "") = x <= 0 ? t : f2a(x - 1, y + 2, str(t, c(y, 65))); +s1 = f2a(50000); +echo(len(s1), substring(s1, 0, 40)); + +// recursion in the "true" part of the ternary operator +function f2b(x, y = 0, t = "") = x > 0 ? f2b(x - 1, y + 1, str(t, chr((y % 26) + 97))) : t; +s2 = f2b(50000); +echo(len(s2), substring(s2, 0, 40)); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a87b5c0b..20f0f791 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1045,6 +1045,7 @@ list(APPEND ECHO_FILES ${FUNCTION_FILES} ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/search-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/search-tests-unicode.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/recursion-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/tail-recursion-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/value-reassignment-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/value-reassignment-tests2.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/variable-scope-tests.scad diff --git a/tests/regression/echotest/tail-recursion-tests-expected.echo b/tests/regression/echotest/tail-recursion-tests-expected.echo new file mode 100644 index 00000000..753e2514 --- /dev/null +++ b/tests/regression/echotest/tail-recursion-tests-expected.echo @@ -0,0 +1,6 @@ +ECHO: "without tail-recursion eliminiation: ", 5050 +ECHO: "with tail-recursion eliminiation: ", 5050 +ECHO: "with tail-recursion eliminiation: ", 2001000 +ECHO: [1980, 1980] +ECHO: 50000, "ACEGIKMOQSUWYACEGIKMOQSUWYACEGIKMOQSUWYA" +ECHO: 50000, "abcdefghijklmnopqrstuvwxyzabcdefghijklmn" From 87f532493e18100c3ff85a6fe52dc03c37f2e787 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 3 Dec 2014 10:58:44 -0500 Subject: [PATCH 092/263] #1047 Some more cleanup for NULLGL --- src/NULLGL.cc | 12 +++--------- tests/CMakeLists.txt | 15 ++++----------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/NULLGL.cc b/src/NULLGL.cc index b0d360fc..65d6e5e7 100644 --- a/src/NULLGL.cc +++ b/src/NULLGL.cc @@ -4,16 +4,10 @@ GLView::GLView() {} void GLView::setRenderer(Renderer* r) {} void GLView::initializeGL() {} void GLView::resizeGL(int w, int h) {} -//void GLView::setupGimbalCamPerspective() {} -//void GLView::setupGimbalCamOrtho(double distance, bool offset) {} -//void GLView::setupVectorCamPerspective() {} -//void GLView::setupVectorCamOrtho(bool offset) {} -void GLView::setCamera(const Camera &cam ) {} +void GLView::setCamera(const Camera &cam ) {assert(false && "not implemented");} void GLView::paintGL() {} -//void GLView::vectorCamPaintGL() {} -//void GLView::gimbalCamPaintGL() {} -void GLView::showSmallaxes() {} -void GLView::showAxes() {} +void GLView::showSmallaxes(const Color4f &col) {} +void GLView::showAxes(const Color4f &col) {} void GLView::showCrosshairs() {} void GLView::setColorScheme(const ColorScheme &cs){assert(false && "not implemented");} void GLView::setColorScheme(const std::string &cs) {assert(false && "not implemented");} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d4703592..d754d882 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -78,7 +78,6 @@ endif() # Most tests will fail, but it can be used for testing/experiments if(NULLGL) - set(ENABLE_OPENCSG_FLAG "") # OpenCSG is entirely an OpenGL software set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNULLGL") set(SKIP_IMAGEMAGICK "1") # we dont generate png, so nothing to compare else() @@ -736,16 +735,10 @@ target_link_libraries(tests-cgal tests-common ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_L # # Create non-CGAL tests # +add_library(tests-nocgal STATIC ${NOCGAL_SOURCES}) +target_link_libraries(tests-nocgal tests-common) if (NOT NULLGL) - add_library(tests-nocgal STATIC ${NOCGAL_SOURCES}) set_target_properties(tests-nocgal PROPERTIES COMPILE_FLAGS ${ENABLE_OPENCSG_FLAG}) - target_link_libraries(tests-nocgal tests-common) -else() - message(STATUS "NULLGL: cannot use GL/GLU tessellator. see dxftess.cc") - message(STATUS "NULLGL: non-CGAL tests will use CGAL's tessellator") - add_library(tests-nocgal STATIC ${NOCGAL_SOURCES}) - set_target_properties(tests-nocgal PROPERTIES COMPILE_FLAGS ${ENABLE_OPENCSG_FLAG}) - target_link_libraries(tests-nocgal tests-common) endif() add_library(tests-offscreen STATIC ${OFFSCREEN_SOURCES}) @@ -767,8 +760,8 @@ target_link_libraries(csgtexttest tests-nocgal) # cgalcachetest # add_executable(cgalcachetest cgalcachetest.cc) -set_target_properties(cgalcachetest PROPERTIES COMPILE_FLAGS "${ENABLE_OPENCSG_FLAG} -DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") -target_link_libraries(cgalcachetest tests-cgal ${GLEW_LIBRARY}) +set_target_properties(cgalcachetest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") +target_link_libraries(cgalcachetest tests-cgal) # # openscad no-qt From 407da2ea8c1246f5dd29ac52df7226146830b060 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 4 Dec 2014 19:40:15 +0100 Subject: [PATCH 093/263] Move catch for function recursion detection. Catching this at ModuleInstantiation::evaluate() should ensure the whole function call is terminated with the first exception. Otherwise function calls with multiple recursion points (e.g. function f(x) = f(x) + f(x);) will still descent into the recursion multiple times. --- src/context.cc | 8 ++++++++ src/evalcontext.cc | 7 +------ src/module.cc | 9 +++++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/context.cc b/src/context.cc index 567cdbca..c7903967 100644 --- a/src/context.cc +++ b/src/context.cc @@ -162,6 +162,14 @@ bool Context::has_local_variable(const std::string &name) const return variables.find(name) != variables.end(); } +/** + * This is separated because PRINTB uses quite a lot of stack space + * and the methods using it evaluate_function() and instantiate_module() + * are called often when recursive functions or modules are evaluated. + * + * @param what what is ignored + * @param name name of the ignored object + */ static void print_ignore_warning(const char *what, const char *name) { PRINTB("WARNING: Ignoring unknown %s '%s'.", what % name); diff --git a/src/evalcontext.cc b/src/evalcontext.cc index 223b4ce6..79f078b7 100644 --- a/src/evalcontext.cc +++ b/src/evalcontext.cc @@ -27,12 +27,7 @@ ValuePtr EvalContext::getArgValue(size_t i, const Context *ctx) const const Assignment &arg = this->eval_arguments[i]; ValuePtr v; if (arg.second) { - try { - v = arg.second->evaluate(ctx ? ctx : this); - } - catch (RecursionException &e) { - PRINT(e.what()); - } + v = arg.second->evaluate(ctx ? ctx : this); } return v; } diff --git a/src/module.cc b/src/module.cc index 2a85c6b7..8cf6498e 100644 --- a/src/module.cc +++ b/src/module.cc @@ -153,8 +153,13 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const PRINT("New eval ctx:"); c.dump(NULL, this); #endif - AbstractNode *node = ctx->instantiate_module(*this, &c); // Passes c as evalctx - return node; + try { + AbstractNode *node = ctx->instantiate_module(*this, &c); // Passes c as evalctx + return node; + } catch (RecursionException &e) { + PRINT(e.what()); + return NULL; + } } std::vector ModuleInstantiation::instantiateChildren(const Context *evalctx) const From a466638433f0c5f3493effd0eab7abf4b82dbbc3 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 4 Dec 2014 20:44:53 +0100 Subject: [PATCH 094/263] Remove automatic translation update as that always generates modified *.po files. --- openscad.pro | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openscad.pro b/openscad.pro index 58e0921f..f1b6d144 100644 --- a/openscad.pro +++ b/openscad.pro @@ -486,10 +486,6 @@ isEmpty(PREFIX):PREFIX = /usr/local target.path = $$PREFIX/bin/ INSTALLS += target - -# Run translation update scripts as last step after linking the target -QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh - # Create install targets for the languages defined in LINGUAS LINGUAS = $$cat(locale/LINGUAS) LOCALE_PREFIX = $$PREFIX/share/openscad/locale From 9285222e29fec9c4b36ad49218af563e57dd6a2e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 4 Dec 2014 15:53:04 -0500 Subject: [PATCH 095/263] Updated test result after moving recursion exception catch --- tests/regression/echotest/recursion-tests-expected.echo | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/regression/echotest/recursion-tests-expected.echo b/tests/regression/echotest/recursion-tests-expected.echo index 4bf735f7..747e6d47 100644 --- a/tests/regression/echotest/recursion-tests-expected.echo +++ b/tests/regression/echotest/recursion-tests-expected.echo @@ -1,3 +1,2 @@ ERROR: Recursion detected calling function 'crash' -ECHO: undef ERROR: Recursion detected calling module 'crash' From 80f1a31143886341b4e4e84c6c9af17d51f54817 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 4 Dec 2014 23:20:25 +0100 Subject: [PATCH 096/263] Update translation file generator scripts. --- doc/translation.txt | 4 ++-- openscad.pro | 3 +++ scripts/release-common.sh | 4 ++++ scripts/translation-make.sh | 12 +++--------- scripts/translation-update.sh | 7 +++++++ 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/doc/translation.txt b/doc/translation.txt index 67bc4137..8abb3eaa 100644 --- a/doc/translation.txt +++ b/doc/translation.txt @@ -51,14 +51,14 @@ files. Then run the script to scan the source files, and regenerate .pot & .po files. - $ ./scripts/translation-make.sh + $ ./scripts/translation-update.sh This will create new .po files with any new untranslated strings you added to the source code. These .po files can be distributed to translators for translation. After the translated .po file is obtained, overwrite the old .po and run the same script to update the .mo files. - $ ./scripts/translation-make.sh + $ ./scripts/translation-update.sh To add a new language: ====================== diff --git a/openscad.pro b/openscad.pro index f1b6d144..5fdcab29 100644 --- a/openscad.pro +++ b/openscad.pro @@ -486,6 +486,9 @@ isEmpty(PREFIX):PREFIX = /usr/local target.path = $$PREFIX/bin/ INSTALLS += target +# Run translation update scripts as last step after linking the target +QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh + # Create install targets for the languages defined in LINGUAS LINGUAS = $$cat(locale/LINGUAS) LOCALE_PREFIX = $$PREFIX/share/openscad/locale diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 381504c0..f9faf8a6 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -280,6 +280,10 @@ if [[ $? != 0 ]]; then exit 1 fi +echo "Updating language files..." + +cd $OPENSCADDIR +./scripts/translation-update.sh echo "Building test suite..." diff --git a/scripts/translation-make.sh b/scripts/translation-make.sh index 95dcfb4e..89ebd91e 100755 --- a/scripts/translation-make.sh +++ b/scripts/translation-make.sh @@ -3,19 +3,13 @@ # Script for use from qmake to generate the translation # related files. # -# Step 1) call generate-potfiles.sh to collect input files -# Step 2) call translation-update.sh to generate *.mo files -# SCRIPTDIR="`dirname \"$0\"`" TOPDIR="`dirname \"$SCRIPTDIR\"`" -cd "$TOPDIR" +cd "$TOPDIR" || exit 1 -echo "Generating POTFILES..." -./scripts/generate-potfiles.sh > locale/POTFILES - -echo "Updating translation files..." -./scripts/translation-update.sh +echo "Compiling language files..." +./scripts/translation-update.sh updatemo echo "Done." diff --git a/scripts/translation-update.sh b/scripts/translation-update.sh index 1cb5ec38..11a30bc4 100755 --- a/scripts/translation-update.sh +++ b/scripts/translation-update.sh @@ -71,9 +71,16 @@ GETTEXT_PATH="" # GETTEXT_PATH="$OPENSCAD_LIBRARIES/bin/" #fi +SCRIPTDIR="`dirname \"$0\"`" +TOPDIR="`dirname \"$SCRIPTDIR\"`" + +cd "$TOPDIR" || exit 1 + if [ "x$1" = xupdatemo ]; then updatemo else + echo "Generating POTFILES..." + ./scripts/generate-potfiles.sh > locale/POTFILES updatepot && updatepo && updatemo fi From 092b9eeddc1c18c5bcc78f14b7e3ba8957cb5428 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 4 Dec 2014 23:29:18 +0100 Subject: [PATCH 097/263] Build with -DNOGDI by default to prevent name conflicts with windows.h. --- mingw-cross-env.pri | 2 +- src/OGL_helper.h | 1 + src/OffscreenContextWGL.cc | 1 + src/PlatformUtils-win.cc | 1 + src/colormap.cc | 4 +++- src/colormap.h | 1 - src/system-gl.h | 3 --- 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/mingw-cross-env.pri b/mingw-cross-env.pri index 5a6502a2..97ee3814 100644 --- a/mingw-cross-env.pri +++ b/mingw-cross-env.pri @@ -19,7 +19,7 @@ CONFIG(mingw-cross-env) { LIBS += mingw-cross-env/lib/libexpat.a LIBS += mingw-cross-env/lib/libintl.a LIBS += mingw-cross-env/lib/libiconv.a - QMAKE_CXXFLAGS += -fpermissive + QMAKE_CXXFLAGS += -fpermissive -DNOGDI WINSTACKSIZE = 8388608 # 8MB # github issue 116 QMAKE_CXXFLAGS += -Wl,--stack,$$WINSTACKSIZE LIBS += -Wl,--stack,$$WINSTACKSIZE diff --git a/src/OGL_helper.h b/src/OGL_helper.h index 488ee133..966657fc 100644 --- a/src/OGL_helper.h +++ b/src/OGL_helper.h @@ -44,6 +44,7 @@ const bool cull_backfaces = false; const bool color_backfaces = false; #ifdef _WIN32 +#include // For the CALLBACK macro #define CGAL_GLU_TESS_CALLBACK CALLBACK #else #define CGAL_GLU_TESS_CALLBACK diff --git a/src/OffscreenContextWGL.cc b/src/OffscreenContextWGL.cc index 6e657fe5..b9e0f0e8 100644 --- a/src/OffscreenContextWGL.cc +++ b/src/OffscreenContextWGL.cc @@ -11,6 +11,7 @@ For more info: http://blogs.msdn.com/b/oldnewthing/archive/2006/12/04/1205831.aspx by Tom */ +#undef NOGDI #include #include diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index c94a2a67..c83855d0 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -3,6 +3,7 @@ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif +#undef NOGDI #include #ifndef _WIN32_IE #define _WIN32_IE 0x0501 // SHGFP_TYPE_CURRENT diff --git a/src/colormap.cc b/src/colormap.cc index 84cd2a52..51868815 100644 --- a/src/colormap.cc +++ b/src/colormap.cc @@ -3,6 +3,8 @@ #include "printutils.h" #include "PlatformUtils.h" +#include + static const char *DEFAULT_COLOR_SCHEME_NAME = "Cornfield"; // See http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv @@ -298,4 +300,4 @@ ColorMap::colorscheme_set_t ColorMap::enumerateColorSchemes() enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); return result_set; -} \ No newline at end of file +} diff --git a/src/colormap.h b/src/colormap.h index 0f8bc545..bb869dd8 100644 --- a/src/colormap.h +++ b/src/colormap.h @@ -8,7 +8,6 @@ #include #include #include -#include namespace fs = boost::filesystem; diff --git a/src/system-gl.h b/src/system-gl.h index 1cabafe5..9d8e6ce0 100644 --- a/src/system-gl.h +++ b/src/system-gl.h @@ -8,9 +8,6 @@ #else #include #include - #ifdef _WIN32 - #include // For the CALLBACK macro - #endif #endif #else // NULLGL From 50e79a6817f3d125005dbaab0b95b78a973002a8 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 5 Dec 2014 20:54:01 +0100 Subject: [PATCH 098/263] Fix evaluation of ! expressions. --- src/value.cc | 5 + src/value.h | 1 + .../misc/expression-evaluation-tests.scad | 41 ++ tests/CMakeLists.txt | 1 + .../expression-evaluation-tests-expected.echo | 361 ++++++++++++++++++ 5 files changed, 409 insertions(+) create mode 100644 testdata/scad/misc/expression-evaluation-tests.scad create mode 100644 tests/regression/echotest/expression-evaluation-tests-expected.echo diff --git a/src/value.cc b/src/value.cc index 3180f2b0..d3eea01a 100644 --- a/src/value.cc +++ b/src/value.cc @@ -877,6 +877,11 @@ ValuePtr ValuePtr::operator-() const return ValuePtr(-**this); } +ValuePtr ValuePtr::operator!() const +{ + return ValuePtr(!**this); +} + ValuePtr ValuePtr::operator[](const ValuePtr &v) const { return ValuePtr((**this)[*v]); diff --git a/src/value.h b/src/value.h index bfd08376..e3822309 100644 --- a/src/value.h +++ b/src/value.h @@ -187,6 +187,7 @@ public: bool operator>=(const ValuePtr &v) const; bool operator>(const ValuePtr &v) const; ValuePtr operator-() const; + ValuePtr operator!() const; ValuePtr operator[](const ValuePtr &v) const; ValuePtr operator+(const ValuePtr &v) const; ValuePtr operator-(const ValuePtr &v) const; diff --git a/testdata/scad/misc/expression-evaluation-tests.scad b/testdata/scad/misc/expression-evaluation-tests.scad new file mode 100644 index 00000000..0dd5ff37 --- /dev/null +++ b/testdata/scad/misc/expression-evaluation-tests.scad @@ -0,0 +1,41 @@ +values = [ + undef, // special undefined value + 1/0, // infinity + -1/0, // -infinity + 0/0, // not a number + 0, -4.2, -2, 3, 42.42, 242, // number + true, false, // boolean + "", "text", // string + [], [ 0 ], [ 1 ], // vector + [ 0 : 0 ], [ 1 : 2 ] // range +]; + +array = [ "a", "b", "c", "d" ]; + +for (v = values) { + echo(v = v, op = "not v", result = !v); + echo(v = v, op = "-v", result = -v); + echo(v = v, op = "v *", result = v * 3); + echo(v = v, op = "* v", result = 2 * v); + echo(v = v, op = "v /", result = v / 3); + echo(v = v, op = "/ v", result = 2 / v); + echo(v = v, op = "v %", result = v % 3); + echo(v = v, op = "% v", result = 2 % v); + echo(v = v, op = "v +", result = v + 3); + echo(v = v, op = "+ v", result = 2 + v); + echo(v = v, op = "v -", result = v - 3); + echo(v = v, op = "- v", result = 2 - v); + echo(v = v, op = "v and true", result = v && true); + echo(v = v, op = "v and false", result = v && false); + echo(v = v, op = "v or true", result = v || true); + echo(v = v, op = "v or false", result = v || false); +// echo(v = v, op = "<", result = v < 3); +// echo(v = v, op = "<=", result = v <= 3); +// echo(v = v, op = "==", result = v == 3); +// echo(v = v, op = "!=", result = v != 3); +// echo(v = v, op = ">=", result = v >= 3); +// echo(v = v, op = ">", result = v > 3); + echo(v = v, op = "[v]", result = array[v]); + echo(v = v, op = "v[0]", result = v[0]); + echo(v = v, op = "v[4]", result = v[4]); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index be237330..e190b10c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1025,6 +1025,7 @@ list(APPEND EXAMPLE_FILES ${EXAMPLE_3D_FILES} ${EXAMPLE_2D_FILES}) list(APPEND ECHO_FILES ${FUNCTION_FILES} ${CMAKE_SOURCE_DIR}/../testdata/scad/3D/features/for-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/expression-evaluation-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/echo-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/escape-test.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/parser-tests.scad diff --git a/tests/regression/echotest/expression-evaluation-tests-expected.echo b/tests/regression/echotest/expression-evaluation-tests-expected.echo new file mode 100644 index 00000000..49f91f0d --- /dev/null +++ b/tests/regression/echotest/expression-evaluation-tests-expected.echo @@ -0,0 +1,361 @@ +ECHO: v = undef, op = "not v", result = true +ECHO: v = undef, op = "-v", result = undef +ECHO: v = undef, op = "v *", result = undef +ECHO: v = undef, op = "* v", result = undef +ECHO: v = undef, op = "v /", result = undef +ECHO: v = undef, op = "/ v", result = undef +ECHO: v = undef, op = "v %", result = undef +ECHO: v = undef, op = "% v", result = undef +ECHO: v = undef, op = "v +", result = undef +ECHO: v = undef, op = "+ v", result = undef +ECHO: v = undef, op = "v -", result = undef +ECHO: v = undef, op = "- v", result = undef +ECHO: v = undef, op = "v and true", result = false +ECHO: v = undef, op = "v and false", result = false +ECHO: v = undef, op = "v or true", result = true +ECHO: v = undef, op = "v or false", result = false +ECHO: v = undef, op = "[v]", result = undef +ECHO: v = undef, op = "v[0]", result = undef +ECHO: v = undef, op = "v[4]", result = undef +ECHO: v = inf, op = "not v", result = false +ECHO: v = inf, op = "-v", result = -inf +ECHO: v = inf, op = "v *", result = inf +ECHO: v = inf, op = "* v", result = inf +ECHO: v = inf, op = "v /", result = inf +ECHO: v = inf, op = "/ v", result = 0 +ECHO: v = inf, op = "v %", result = nan +ECHO: v = inf, op = "% v", result = 2 +ECHO: v = inf, op = "v +", result = inf +ECHO: v = inf, op = "+ v", result = inf +ECHO: v = inf, op = "v -", result = inf +ECHO: v = inf, op = "- v", result = -inf +ECHO: v = inf, op = "v and true", result = true +ECHO: v = inf, op = "v and false", result = false +ECHO: v = inf, op = "v or true", result = true +ECHO: v = inf, op = "v or false", result = true +ECHO: v = inf, op = "[v]", result = undef +ECHO: v = inf, op = "v[0]", result = undef +ECHO: v = inf, op = "v[4]", result = undef +ECHO: v = -inf, op = "not v", result = false +ECHO: v = -inf, op = "-v", result = inf +ECHO: v = -inf, op = "v *", result = -inf +ECHO: v = -inf, op = "* v", result = -inf +ECHO: v = -inf, op = "v /", result = -inf +ECHO: v = -inf, op = "/ v", result = 0 +ECHO: v = -inf, op = "v %", result = nan +ECHO: v = -inf, op = "% v", result = 2 +ECHO: v = -inf, op = "v +", result = -inf +ECHO: v = -inf, op = "+ v", result = -inf +ECHO: v = -inf, op = "v -", result = -inf +ECHO: v = -inf, op = "- v", result = inf +ECHO: v = -inf, op = "v and true", result = true +ECHO: v = -inf, op = "v and false", result = false +ECHO: v = -inf, op = "v or true", result = true +ECHO: v = -inf, op = "v or false", result = true +ECHO: v = -inf, op = "[v]", result = undef +ECHO: v = -inf, op = "v[0]", result = undef +ECHO: v = -inf, op = "v[4]", result = undef +ECHO: v = nan, op = "not v", result = false +ECHO: v = nan, op = "-v", result = nan +ECHO: v = nan, op = "v *", result = nan +ECHO: v = nan, op = "* v", result = nan +ECHO: v = nan, op = "v /", result = nan +ECHO: v = nan, op = "/ v", result = nan +ECHO: v = nan, op = "v %", result = nan +ECHO: v = nan, op = "% v", result = nan +ECHO: v = nan, op = "v +", result = nan +ECHO: v = nan, op = "+ v", result = nan +ECHO: v = nan, op = "v -", result = nan +ECHO: v = nan, op = "- v", result = nan +ECHO: v = nan, op = "v and true", result = true +ECHO: v = nan, op = "v and false", result = false +ECHO: v = nan, op = "v or true", result = true +ECHO: v = nan, op = "v or false", result = true +ECHO: v = nan, op = "[v]", result = undef +ECHO: v = nan, op = "v[0]", result = undef +ECHO: v = nan, op = "v[4]", result = undef +ECHO: v = 0, op = "not v", result = true +ECHO: v = 0, op = "-v", result = 0 +ECHO: v = 0, op = "v *", result = 0 +ECHO: v = 0, op = "* v", result = 0 +ECHO: v = 0, op = "v /", result = 0 +ECHO: v = 0, op = "/ v", result = inf +ECHO: v = 0, op = "v %", result = 0 +ECHO: v = 0, op = "% v", result = nan +ECHO: v = 0, op = "v +", result = 3 +ECHO: v = 0, op = "+ v", result = 2 +ECHO: v = 0, op = "v -", result = -3 +ECHO: v = 0, op = "- v", result = 2 +ECHO: v = 0, op = "v and true", result = false +ECHO: v = 0, op = "v and false", result = false +ECHO: v = 0, op = "v or true", result = true +ECHO: v = 0, op = "v or false", result = false +ECHO: v = 0, op = "[v]", result = "a" +ECHO: v = 0, op = "v[0]", result = undef +ECHO: v = 0, op = "v[4]", result = undef +ECHO: v = -4.2, op = "not v", result = false +ECHO: v = -4.2, op = "-v", result = 4.2 +ECHO: v = -4.2, op = "v *", result = -12.6 +ECHO: v = -4.2, op = "* v", result = -8.4 +ECHO: v = -4.2, op = "v /", result = -1.4 +ECHO: v = -4.2, op = "/ v", result = -0.47619047619 +ECHO: v = -4.2, op = "v %", result = -1.2 +ECHO: v = -4.2, op = "% v", result = 2 +ECHO: v = -4.2, op = "v +", result = -1.2 +ECHO: v = -4.2, op = "+ v", result = -2.2 +ECHO: v = -4.2, op = "v -", result = -7.2 +ECHO: v = -4.2, op = "- v", result = 6.2 +ECHO: v = -4.2, op = "v and true", result = true +ECHO: v = -4.2, op = "v and false", result = false +ECHO: v = -4.2, op = "v or true", result = true +ECHO: v = -4.2, op = "v or false", result = true +ECHO: v = -4.2, op = "[v]", result = undef +ECHO: v = -4.2, op = "v[0]", result = undef +ECHO: v = -4.2, op = "v[4]", result = undef +ECHO: v = -2, op = "not v", result = false +ECHO: v = -2, op = "-v", result = 2 +ECHO: v = -2, op = "v *", result = -6 +ECHO: v = -2, op = "* v", result = -4 +ECHO: v = -2, op = "v /", result = -0.66666666666 +ECHO: v = -2, op = "/ v", result = -1 +ECHO: v = -2, op = "v %", result = -2 +ECHO: v = -2, op = "% v", result = 0 +ECHO: v = -2, op = "v +", result = 1 +ECHO: v = -2, op = "+ v", result = 0 +ECHO: v = -2, op = "v -", result = -5 +ECHO: v = -2, op = "- v", result = 4 +ECHO: v = -2, op = "v and true", result = true +ECHO: v = -2, op = "v and false", result = false +ECHO: v = -2, op = "v or true", result = true +ECHO: v = -2, op = "v or false", result = true +ECHO: v = -2, op = "[v]", result = undef +ECHO: v = -2, op = "v[0]", result = undef +ECHO: v = -2, op = "v[4]", result = undef +ECHO: v = 3, op = "not v", result = false +ECHO: v = 3, op = "-v", result = -3 +ECHO: v = 3, op = "v *", result = 9 +ECHO: v = 3, op = "* v", result = 6 +ECHO: v = 3, op = "v /", result = 1 +ECHO: v = 3, op = "/ v", result = 0.66666666666 +ECHO: v = 3, op = "v %", result = 0 +ECHO: v = 3, op = "% v", result = 2 +ECHO: v = 3, op = "v +", result = 6 +ECHO: v = 3, op = "+ v", result = 5 +ECHO: v = 3, op = "v -", result = 0 +ECHO: v = 3, op = "- v", result = -1 +ECHO: v = 3, op = "v and true", result = true +ECHO: v = 3, op = "v and false", result = false +ECHO: v = 3, op = "v or true", result = true +ECHO: v = 3, op = "v or false", result = true +ECHO: v = 3, op = "[v]", result = "d" +ECHO: v = 3, op = "v[0]", result = undef +ECHO: v = 3, op = "v[4]", result = undef +ECHO: v = 42.42, op = "not v", result = false +ECHO: v = 42.42, op = "-v", result = -42.42 +ECHO: v = 42.42, op = "v *", result = 127.26 +ECHO: v = 42.42, op = "* v", result = 84.84 +ECHO: v = 42.42, op = "v /", result = 14.14 +ECHO: v = 42.42, op = "/ v", result = 0.0471475719 +ECHO: v = 42.42, op = "v %", result = 0.42 +ECHO: v = 42.42, op = "% v", result = 2 +ECHO: v = 42.42, op = "v +", result = 45.42 +ECHO: v = 42.42, op = "+ v", result = 44.42 +ECHO: v = 42.42, op = "v -", result = 39.42 +ECHO: v = 42.42, op = "- v", result = -40.42 +ECHO: v = 42.42, op = "v and true", result = true +ECHO: v = 42.42, op = "v and false", result = false +ECHO: v = 42.42, op = "v or true", result = true +ECHO: v = 42.42, op = "v or false", result = true +ECHO: v = 42.42, op = "[v]", result = undef +ECHO: v = 42.42, op = "v[0]", result = undef +ECHO: v = 42.42, op = "v[4]", result = undef +ECHO: v = 242, op = "not v", result = false +ECHO: v = 242, op = "-v", result = -242 +ECHO: v = 242, op = "v *", result = 726 +ECHO: v = 242, op = "* v", result = 484 +ECHO: v = 242, op = "v /", result = 80.66666666666 +ECHO: v = 242, op = "/ v", result = 0.00826446281 +ECHO: v = 242, op = "v %", result = 2 +ECHO: v = 242, op = "% v", result = 2 +ECHO: v = 242, op = "v +", result = 245 +ECHO: v = 242, op = "+ v", result = 244 +ECHO: v = 242, op = "v -", result = 239 +ECHO: v = 242, op = "- v", result = -240 +ECHO: v = 242, op = "v and true", result = true +ECHO: v = 242, op = "v and false", result = false +ECHO: v = 242, op = "v or true", result = true +ECHO: v = 242, op = "v or false", result = true +ECHO: v = 242, op = "[v]", result = undef +ECHO: v = 242, op = "v[0]", result = undef +ECHO: v = 242, op = "v[4]", result = undef +ECHO: v = true, op = "not v", result = false +ECHO: v = true, op = "-v", result = undef +ECHO: v = true, op = "v *", result = undef +ECHO: v = true, op = "* v", result = undef +ECHO: v = true, op = "v /", result = undef +ECHO: v = true, op = "/ v", result = undef +ECHO: v = true, op = "v %", result = undef +ECHO: v = true, op = "% v", result = undef +ECHO: v = true, op = "v +", result = undef +ECHO: v = true, op = "+ v", result = undef +ECHO: v = true, op = "v -", result = undef +ECHO: v = true, op = "- v", result = undef +ECHO: v = true, op = "v and true", result = true +ECHO: v = true, op = "v and false", result = false +ECHO: v = true, op = "v or true", result = true +ECHO: v = true, op = "v or false", result = true +ECHO: v = true, op = "[v]", result = undef +ECHO: v = true, op = "v[0]", result = undef +ECHO: v = true, op = "v[4]", result = undef +ECHO: v = false, op = "not v", result = true +ECHO: v = false, op = "-v", result = undef +ECHO: v = false, op = "v *", result = undef +ECHO: v = false, op = "* v", result = undef +ECHO: v = false, op = "v /", result = undef +ECHO: v = false, op = "/ v", result = undef +ECHO: v = false, op = "v %", result = undef +ECHO: v = false, op = "% v", result = undef +ECHO: v = false, op = "v +", result = undef +ECHO: v = false, op = "+ v", result = undef +ECHO: v = false, op = "v -", result = undef +ECHO: v = false, op = "- v", result = undef +ECHO: v = false, op = "v and true", result = false +ECHO: v = false, op = "v and false", result = false +ECHO: v = false, op = "v or true", result = true +ECHO: v = false, op = "v or false", result = false +ECHO: v = false, op = "[v]", result = undef +ECHO: v = false, op = "v[0]", result = undef +ECHO: v = false, op = "v[4]", result = undef +ECHO: v = "", op = "not v", result = true +ECHO: v = "", op = "-v", result = undef +ECHO: v = "", op = "v *", result = undef +ECHO: v = "", op = "* v", result = undef +ECHO: v = "", op = "v /", result = undef +ECHO: v = "", op = "/ v", result = undef +ECHO: v = "", op = "v %", result = undef +ECHO: v = "", op = "% v", result = undef +ECHO: v = "", op = "v +", result = undef +ECHO: v = "", op = "+ v", result = undef +ECHO: v = "", op = "v -", result = undef +ECHO: v = "", op = "- v", result = undef +ECHO: v = "", op = "v and true", result = false +ECHO: v = "", op = "v and false", result = false +ECHO: v = "", op = "v or true", result = true +ECHO: v = "", op = "v or false", result = false +ECHO: v = "", op = "[v]", result = undef +ECHO: v = "", op = "v[0]", result = undef +ECHO: v = "", op = "v[4]", result = undef +ECHO: v = "text", op = "not v", result = false +ECHO: v = "text", op = "-v", result = undef +ECHO: v = "text", op = "v *", result = undef +ECHO: v = "text", op = "* v", result = undef +ECHO: v = "text", op = "v /", result = undef +ECHO: v = "text", op = "/ v", result = undef +ECHO: v = "text", op = "v %", result = undef +ECHO: v = "text", op = "% v", result = undef +ECHO: v = "text", op = "v +", result = undef +ECHO: v = "text", op = "+ v", result = undef +ECHO: v = "text", op = "v -", result = undef +ECHO: v = "text", op = "- v", result = undef +ECHO: v = "text", op = "v and true", result = true +ECHO: v = "text", op = "v and false", result = false +ECHO: v = "text", op = "v or true", result = true +ECHO: v = "text", op = "v or false", result = true +ECHO: v = "text", op = "[v]", result = undef +ECHO: v = "text", op = "v[0]", result = "t" +ECHO: v = "text", op = "v[4]", result = undef +ECHO: v = [], op = "not v", result = true +ECHO: v = [], op = "-v", result = [] +ECHO: v = [], op = "v *", result = [] +ECHO: v = [], op = "* v", result = [] +ECHO: v = [], op = "v /", result = [] +ECHO: v = [], op = "/ v", result = [] +ECHO: v = [], op = "v %", result = undef +ECHO: v = [], op = "% v", result = undef +ECHO: v = [], op = "v +", result = undef +ECHO: v = [], op = "+ v", result = undef +ECHO: v = [], op = "v -", result = undef +ECHO: v = [], op = "- v", result = undef +ECHO: v = [], op = "v and true", result = false +ECHO: v = [], op = "v and false", result = false +ECHO: v = [], op = "v or true", result = true +ECHO: v = [], op = "v or false", result = false +ECHO: v = [], op = "[v]", result = undef +ECHO: v = [], op = "v[0]", result = undef +ECHO: v = [], op = "v[4]", result = undef +ECHO: v = [0], op = "not v", result = false +ECHO: v = [0], op = "-v", result = [0] +ECHO: v = [0], op = "v *", result = [0] +ECHO: v = [0], op = "* v", result = [0] +ECHO: v = [0], op = "v /", result = [0] +ECHO: v = [0], op = "/ v", result = [inf] +ECHO: v = [0], op = "v %", result = undef +ECHO: v = [0], op = "% v", result = undef +ECHO: v = [0], op = "v +", result = undef +ECHO: v = [0], op = "+ v", result = undef +ECHO: v = [0], op = "v -", result = undef +ECHO: v = [0], op = "- v", result = undef +ECHO: v = [0], op = "v and true", result = true +ECHO: v = [0], op = "v and false", result = false +ECHO: v = [0], op = "v or true", result = true +ECHO: v = [0], op = "v or false", result = true +ECHO: v = [0], op = "[v]", result = undef +ECHO: v = [0], op = "v[0]", result = 0 +ECHO: v = [0], op = "v[4]", result = undef +ECHO: v = [1], op = "not v", result = false +ECHO: v = [1], op = "-v", result = [-1] +ECHO: v = [1], op = "v *", result = [3] +ECHO: v = [1], op = "* v", result = [2] +ECHO: v = [1], op = "v /", result = [0.33333333333] +ECHO: v = [1], op = "/ v", result = [2] +ECHO: v = [1], op = "v %", result = undef +ECHO: v = [1], op = "% v", result = undef +ECHO: v = [1], op = "v +", result = undef +ECHO: v = [1], op = "+ v", result = undef +ECHO: v = [1], op = "v -", result = undef +ECHO: v = [1], op = "- v", result = undef +ECHO: v = [1], op = "v and true", result = true +ECHO: v = [1], op = "v and false", result = false +ECHO: v = [1], op = "v or true", result = true +ECHO: v = [1], op = "v or false", result = true +ECHO: v = [1], op = "[v]", result = undef +ECHO: v = [1], op = "v[0]", result = 1 +ECHO: v = [1], op = "v[4]", result = undef +ECHO: v = [0 : 1 : 0], op = "not v", result = false +ECHO: v = [0 : 1 : 0], op = "-v", result = undef +ECHO: v = [0 : 1 : 0], op = "v *", result = undef +ECHO: v = [0 : 1 : 0], op = "* v", result = undef +ECHO: v = [0 : 1 : 0], op = "v /", result = undef +ECHO: v = [0 : 1 : 0], op = "/ v", result = undef +ECHO: v = [0 : 1 : 0], op = "v %", result = undef +ECHO: v = [0 : 1 : 0], op = "% v", result = undef +ECHO: v = [0 : 1 : 0], op = "v +", result = undef +ECHO: v = [0 : 1 : 0], op = "+ v", result = undef +ECHO: v = [0 : 1 : 0], op = "v -", result = undef +ECHO: v = [0 : 1 : 0], op = "- v", result = undef +ECHO: v = [0 : 1 : 0], op = "v and true", result = true +ECHO: v = [0 : 1 : 0], op = "v and false", result = false +ECHO: v = [0 : 1 : 0], op = "v or true", result = true +ECHO: v = [0 : 1 : 0], op = "v or false", result = true +ECHO: v = [0 : 1 : 0], op = "[v]", result = undef +ECHO: v = [0 : 1 : 0], op = "v[0]", result = 0 +ECHO: v = [0 : 1 : 0], op = "v[4]", result = undef +ECHO: v = [1 : 1 : 2], op = "not v", result = false +ECHO: v = [1 : 1 : 2], op = "-v", result = undef +ECHO: v = [1 : 1 : 2], op = "v *", result = undef +ECHO: v = [1 : 1 : 2], op = "* v", result = undef +ECHO: v = [1 : 1 : 2], op = "v /", result = undef +ECHO: v = [1 : 1 : 2], op = "/ v", result = undef +ECHO: v = [1 : 1 : 2], op = "v %", result = undef +ECHO: v = [1 : 1 : 2], op = "% v", result = undef +ECHO: v = [1 : 1 : 2], op = "v +", result = undef +ECHO: v = [1 : 1 : 2], op = "+ v", result = undef +ECHO: v = [1 : 1 : 2], op = "v -", result = undef +ECHO: v = [1 : 1 : 2], op = "- v", result = undef +ECHO: v = [1 : 1 : 2], op = "v and true", result = true +ECHO: v = [1 : 1 : 2], op = "v and false", result = false +ECHO: v = [1 : 1 : 2], op = "v or true", result = true +ECHO: v = [1 : 1 : 2], op = "v or false", result = true +ECHO: v = [1 : 1 : 2], op = "[v]", result = undef +ECHO: v = [1 : 1 : 2], op = "v[0]", result = 1 +ECHO: v = [1 : 1 : 2], op = "v[4]", result = undef From 2f4171f50675c59f0fe486dc67be293998d0483c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 6 Dec 2014 19:23:19 +0100 Subject: [PATCH 099/263] Add optional target suffix for the binary / installation folder. This is mainly intended to be used for building snapshot binaries that are able to install in parallel to a release build. E.g. by using the parameter "SUFFIX=-nightly" for qmake, the target binary will be called openscad-nightly and the resource base folder /usr/share/openscad-nightly. --- openscad.pro | 28 +++++++++++++++++----------- src/PlatformUtils.cc | 10 ++++++++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/openscad.pro b/openscad.pro index 5fdcab29..a0ab8b42 100644 --- a/openscad.pro +++ b/openscad.pro @@ -12,6 +12,10 @@ # # PREFIX defines the base installation folder # +# SUFFIX defines an optional suffix for the binary and the +# resource folder. E.g. using SUFFIX=-nightly will name the +# resulting binary openscad-nightly. +# # Please see the 'Building' sections of the OpenSCAD user manual # for updated tips & workarounds. # @@ -78,8 +82,10 @@ macx { TARGET = OpenSCAD } else { - TARGET = openscad + TARGET = openscad$${SUFFIX} } +FULLNAME = openscad$${SUFFIX} +!isEmpty(SUFFIX): DEFINES += INSTALL_SUFFIX="\"\\\"$${SUFFIX}\\\"\"" macx { ICON = icons/OpenSCAD.icns @@ -491,7 +497,7 @@ QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh # Create install targets for the languages defined in LINGUAS LINGUAS = $$cat(locale/LINGUAS) -LOCALE_PREFIX = $$PREFIX/share/openscad/locale +LOCALE_PREFIX = "$$PREFIX/share/$${FULLNAME}/locale" for(language, LINGUAS) { catalog = locale/$$language/LC_MESSAGES/openscad.mo exists($$catalog) { @@ -505,40 +511,40 @@ for(language, LINGUAS) { } } -examples.path = $$PREFIX/share/openscad/examples/ +examples.path = "$$PREFIX/share/$${FULLNAME}/examples/" examples.files = examples/* INSTALLS += examples -libraries.path = $$PREFIX/share/openscad/libraries/ +libraries.path = "$$PREFIX/share/$${FULLNAME}/libraries/" libraries.files = libraries/* INSTALLS += libraries -fonts.path = $$PREFIX/share/openscad/fonts/ +fonts.path = "$$PREFIX/share/$${FULLNAME}/fonts/" fonts.files = fonts/* INSTALLS += fonts -colorschemes.path = $$PREFIX/share/openscad/color-schemes/ +colorschemes.path = "$$PREFIX/share/$${FULLNAME}/color-schemes/" colorschemes.files = color-schemes/* INSTALLS += colorschemes applications.path = $$PREFIX/share/applications -applications.files = icons/openscad.desktop +applications.extra = cp -f icons/openscad.desktop \"$$applications.path/$${FULLNAME}.desktop\" INSTALLS += applications mimexml.path = $$PREFIX/share/mime/packages -mimexml.files = icons/openscad.xml +mimexml.extra = cp -f icons/openscad.xml \"$$mimexml.path/$${FULLNAME}.xml\" INSTALLS += mimexml appdata.path = $$PREFIX/share/appdata -appdata.files = openscad.appdata.xml +appdata.extra = cp -f openscad.appdata.xml \"$$appdata.path/$${FULLNAME}.appdata.xml\" INSTALLS += appdata icons.path = $$PREFIX/share/pixmaps -icons.files = icons/openscad.png +icons.extra = cp -f icons/openscad.png \"$$icons.path/$${FULLNAME}.png\" INSTALLS += icons man.path = $$PREFIX/share/man/man1 -man.files = doc/openscad.1 +man.extra = cp -f doc/openscad.1 \"$$man.path/$${FULLNAME}.1\" INSTALLS += man CONFIG(winconsole) { diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index 2dc524ea..2ebc9950 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -2,6 +2,12 @@ #include "PlatformUtils.h" +#ifdef INSTALL_SUFFIX +#define RESOURCE_FOLDER(path) path INSTALL_SUFFIX +#else +#define RESOURCE_FOLDER(path) path +#endif + extern std::vector librarypath; extern std::vector fontpath; @@ -28,8 +34,8 @@ static std::string lookupResourcesPath() }; #else const char *searchpath[] = { - "../share/openscad", - "../../share/openscad", + RESOURCE_FOLDER("../share/openscad"), + RESOURCE_FOLDER("../../share/openscad"), ".", "..", "../..", From dcd0f232778024c0996f9f5ec95887f6214972b2 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 6 Dec 2014 21:31:37 +0100 Subject: [PATCH 100/263] Fix make install with INSTALL_ROOT set, e.g. used by Debian package build. --- openscad.pro | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openscad.pro b/openscad.pro index a0ab8b42..cedeb86d 100644 --- a/openscad.pro +++ b/openscad.pro @@ -528,23 +528,23 @@ colorschemes.files = color-schemes/* INSTALLS += colorschemes applications.path = $$PREFIX/share/applications -applications.extra = cp -f icons/openscad.desktop \"$$applications.path/$${FULLNAME}.desktop\" +applications.extra = cp -f icons/openscad.desktop \"\$(INSTALL_ROOT)$${applications.path}/$${FULLNAME}.desktop\" INSTALLS += applications mimexml.path = $$PREFIX/share/mime/packages -mimexml.extra = cp -f icons/openscad.xml \"$$mimexml.path/$${FULLNAME}.xml\" +mimexml.extra = cp -f icons/openscad.xml \"\$(INSTALL_ROOT)$${mimexml.path}/$${FULLNAME}.xml\" INSTALLS += mimexml appdata.path = $$PREFIX/share/appdata -appdata.extra = cp -f openscad.appdata.xml \"$$appdata.path/$${FULLNAME}.appdata.xml\" +appdata.extra = cp -f openscad.appdata.xml \"\$(INSTALL_ROOT)$${appdata.path}/$${FULLNAME}.appdata.xml\" INSTALLS += appdata icons.path = $$PREFIX/share/pixmaps -icons.extra = cp -f icons/openscad.png \"$$icons.path/$${FULLNAME}.png\" +icons.extra = cp -f icons/openscad.png \"\$(INSTALL_ROOT)$${icons.path}/$${FULLNAME}.png\" INSTALLS += icons man.path = $$PREFIX/share/man/man1 -man.extra = cp -f doc/openscad.1 \"$$man.path/$${FULLNAME}.1\" +man.extra = cp -f doc/openscad.1 \"\$(INSTALL_ROOT)$${man.path}/$${FULLNAME}.1\" INSTALLS += man CONFIG(winconsole) { From 04c194f6d65ec00de7c72a91addab75152b914ba Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 7 Dec 2014 03:38:02 +0100 Subject: [PATCH 101/263] Update .desktop file to include the install SUFFIX. --- openscad.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openscad.pro b/openscad.pro index cedeb86d..57a19ccf 100644 --- a/openscad.pro +++ b/openscad.pro @@ -528,7 +528,7 @@ colorschemes.files = color-schemes/* INSTALLS += colorschemes applications.path = $$PREFIX/share/applications -applications.extra = cp -f icons/openscad.desktop \"\$(INSTALL_ROOT)$${applications.path}/$${FULLNAME}.desktop\" +applications.extra = cat icons/openscad.desktop | sed -e \"'s/^Icon=openscad/Icon=$${FULLNAME}/; s/^Exec=openscad/Exec=$${FULLNAME}/'\" > \"\$(INSTALL_ROOT)$${applications.path}/$${FULLNAME}.desktop\" INSTALLS += applications mimexml.path = $$PREFIX/share/mime/packages From 771526b5ae2969bc6dce24543d8023b9695380cc Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 7 Dec 2014 03:39:01 +0100 Subject: [PATCH 102/263] Fix install target for translation files. --- openscad.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openscad.pro b/openscad.pro index 57a19ccf..ca298dda 100644 --- a/openscad.pro +++ b/openscad.pro @@ -500,7 +500,7 @@ LINGUAS = $$cat(locale/LINGUAS) LOCALE_PREFIX = "$$PREFIX/share/$${FULLNAME}/locale" for(language, LINGUAS) { catalog = locale/$$language/LC_MESSAGES/openscad.mo - exists($$catalog) { + exists(locale/$${language}.po) { translation_path = translation_$${language}.path translation_files = translation_$${language}.files translation_depends = translation_$${language}.depends From 399895bbfe8fb5d20e94d3a5c6967779eed521fa Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 7 Dec 2014 05:46:07 +0100 Subject: [PATCH 103/263] Fix translation file install target when running qmake on clean source. --- openscad.pro | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openscad.pro b/openscad.pro index ca298dda..cf374a44 100644 --- a/openscad.pro +++ b/openscad.pro @@ -499,13 +499,16 @@ QMAKE_POST_LINK += $$PWD/scripts/translation-make.sh LINGUAS = $$cat(locale/LINGUAS) LOCALE_PREFIX = "$$PREFIX/share/$${FULLNAME}/locale" for(language, LINGUAS) { - catalog = locale/$$language/LC_MESSAGES/openscad.mo + catalogdir = locale/$$language/LC_MESSAGES exists(locale/$${language}.po) { + # Use .extra and copy manually as the source path might not exist, + # e.g. on a clean checkout. In that case qmake would not create + # the needed targets in the generated Makefile. translation_path = translation_$${language}.path - translation_files = translation_$${language}.files + translation_extra = translation_$${language}.extra translation_depends = translation_$${language}.depends $$translation_path = $$LOCALE_PREFIX/$$language/LC_MESSAGES/ - $$translation_files = $$catalog + $$translation_extra = cp -f $${catalogdir}/openscad.mo \"\$(INSTALL_ROOT)$$LOCALE_PREFIX/$$language/LC_MESSAGES/openscad.mo\" $$translation_depends = locale/$${language}.po INSTALLS += translation_$$language } From 82b599e8baa097fe561af6775a5a56a621f372ce Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 7 Dec 2014 18:07:53 -0500 Subject: [PATCH 104/263] Bumped Qt to 5.3.2 --- scripts/macosx-build-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index e91123cc..952256e2 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -770,7 +770,7 @@ fi echo "Using basedir:" $BASEDIR mkdir -p $SRCDIR $DEPLOYDIR -build_qt5 5.3.1 +build_qt5 5.3.2 build_qscintilla 2.8.4 # NB! For eigen, also update the path in the function build_eigen 3.2.1 From a606fe39b6bfb37414c4ecfa33c39cbc204c0be7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 7 Dec 2014 19:38:48 -0500 Subject: [PATCH 105/263] Minor testcase tweak --- testdata/scad/2D/features/scale2D-tests.scad | 4 ++-- .../dumptest/scale2D-tests-expected.csg | 20 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/testdata/scad/2D/features/scale2D-tests.scad b/testdata/scad/2D/features/scale2D-tests.scad index 87b22784..385809c7 100644 --- a/testdata/scad/2D/features/scale2D-tests.scad +++ b/testdata/scad/2D/features/scale2D-tests.scad @@ -6,5 +6,5 @@ translate([5,0,0]) scale([2,4/3]) obj2D(); translate([10,0,0]) scale(2) obj2D(); // Scale by zero; 2D object -linear_extrude() scale([0,0]) obj2D(); -linear_extrude() scale([0,1]) obj2D(); +translate([-5,0,0]) linear_extrude() scale([0,0]) obj2D(); +translate([-5,0,0]) linear_extrude() scale([0,1]) obj2D(); diff --git a/tests/regression/dumptest/scale2D-tests-expected.csg b/tests/regression/dumptest/scale2D-tests-expected.csg index b20a9757..5d0b7866 100644 --- a/tests/regression/dumptest/scale2D-tests-expected.csg +++ b/tests/regression/dumptest/scale2D-tests-expected.csg @@ -18,17 +18,21 @@ group() { } } } - linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { - multmatrix([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - group() { - square(size = [2, 3], center = true); + multmatrix([[1, 0, 0, -5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + multmatrix([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + square(size = [2, 3], center = true); + } } } } - linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { - multmatrix([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - group() { - square(size = [2, 3], center = true); + multmatrix([[1, 0, 0, -5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + linear_extrude(height = 100, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + multmatrix([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + square(size = [2, 3], center = true); + } } } } From 5695d7f445b6b2feb2d9a8b8b04c0d4de6e1b998 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 7 Dec 2014 19:47:43 -0500 Subject: [PATCH 106/263] #1055 added testcase --- .../3D/features/scale-mirror2D-3D-tests.scad | 7 ++++ .../scale-mirror2D-3D-tests-expected.png | Bin 0 -> 7403 bytes .../scale-mirror2D-3D-tests-expected.csg | 36 ++++++++++++++++++ .../scale-mirror2D-3D-tests-expected.png | Bin 0 -> 7699 bytes .../scale-mirror2D-3D-tests-expected.png | Bin 0 -> 7716 bytes 5 files changed, 43 insertions(+) create mode 100644 testdata/scad/3D/features/scale-mirror2D-3D-tests.scad create mode 100644 tests/regression/cgalpngtest/scale-mirror2D-3D-tests-expected.png create mode 100644 tests/regression/dumptest/scale-mirror2D-3D-tests-expected.csg create mode 100644 tests/regression/opencsgtest/scale-mirror2D-3D-tests-expected.png create mode 100644 tests/regression/throwntogethertest/scale-mirror2D-3D-tests-expected.png diff --git a/testdata/scad/3D/features/scale-mirror2D-3D-tests.scad b/testdata/scad/3D/features/scale-mirror2D-3D-tests.scad new file mode 100644 index 00000000..bca2450f --- /dev/null +++ b/testdata/scad/3D/features/scale-mirror2D-3D-tests.scad @@ -0,0 +1,7 @@ +module obj2D() polygon([[-0.5,-0.5], [1,-0.5], [1,1], [-0.5, 0.5]]) +square([2,3], center=true); + +linear_extrude(1) scale([1, -1]) obj2D(); +translate([3,0,0]) linear_extrude(1) scale([-1, -0.5]) obj2D(); +translate([0,3,0]) linear_extrude(1) mirror() obj2D(); +translate([2,3,0]) linear_extrude(1) mirror([0,1]) obj2D(); diff --git a/tests/regression/cgalpngtest/scale-mirror2D-3D-tests-expected.png b/tests/regression/cgalpngtest/scale-mirror2D-3D-tests-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..5d85630a9a8777ed8340f33951b2e7aa393b9147 GIT binary patch literal 7403 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 literal 0 HcmV?d00001 diff --git a/tests/regression/dumptest/scale-mirror2D-3D-tests-expected.csg b/tests/regression/dumptest/scale-mirror2D-3D-tests-expected.csg new file mode 100644 index 00000000..2293a339 --- /dev/null +++ b/tests/regression/dumptest/scale-mirror2D-3D-tests-expected.csg @@ -0,0 +1,36 @@ +group() { + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + multmatrix([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1); + } + } + } + multmatrix([[1, 0, 0, 3], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + multmatrix([[-1, 0, 0, 0], [0, -0.5, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1); + } + } + } + } + multmatrix([[1, 0, 0, 0], [0, 1, 0, 3], [0, 0, 1, 0], [0, 0, 0, 1]]) { + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + multmatrix([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1); + } + } + } + } + multmatrix([[1, 0, 0, 2], [0, 1, 0, 3], [0, 0, 1, 0], [0, 0, 0, 1]]) { + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + multmatrix([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + polygon(points = [[-0.5, -0.5], [1, -0.5], [1, 1], [-0.5, 0.5]], paths = undef, convexity = 1); + } + } + } + } +} diff --git a/tests/regression/opencsgtest/scale-mirror2D-3D-tests-expected.png b/tests/regression/opencsgtest/scale-mirror2D-3D-tests-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..6521e4afc85dfde89cd86ea5dbfedb082a356ebc GIT binary patch literal 7699 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 KKU8{<81ru!pyFKs literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/scale-mirror2D-3D-tests-expected.png b/tests/regression/throwntogethertest/scale-mirror2D-3D-tests-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..471748a7afb4cc9fc338abeb326d3f2af9312675 GIT binary patch literal 7716 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 Date: Sun, 7 Dec 2014 19:54:31 -0500 Subject: [PATCH 107/263] #1055 Doc: Clarify sanitized polygons --- src/Polygon2d.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Polygon2d.cc b/src/Polygon2d.cc index 8152c7f9..aeb22b22 100644 --- a/src/Polygon2d.cc +++ b/src/Polygon2d.cc @@ -11,8 +11,10 @@ We can store sanitized vs. unsanitized polygons. Sanitized polygons will have opposite winding order for holes and is guaranteed to not - have intersecting geometry. Sanitization is typically done by ClipperUtils, but - if you create geometry which you know is sanitized, the flag can be set manually. + have intersecting geometry. The winding order will be counter-clockwise + for positive outlines and clockwise for holes. Sanitization is typically + done by ClipperUtils, but if you create geometry which you know is sanitized, + the flag can be set manually. */ size_t Polygon2d::memsize() const From ccea6fdde90d0c2e8cc6a15381266399ce3bdce8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 7 Dec 2014 20:09:45 -0500 Subject: [PATCH 108/263] Bugfix: 2D scale or mirror sometimes caused flipped normals which caused larger issues downstream. Fixes #1055 --- src/GeometryEvaluator.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 71b52a81..40250c68 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -547,7 +547,12 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node) node.matrix(1,0), node.matrix(1,1), node.matrix(1,3), node.matrix(3,0), node.matrix(3,1), node.matrix(3,3); newpoly->transform(mat2); - geom = newpoly; + // A 2D transformation may flip the winding order of a polygon. + // If that happens with a sanitized polygon, we need to reverse + // the winding order for it to be correct. + if (newpoly->isSanitized() && mat2.matrix().determinant() <= 0) { + geom.reset(ClipperUtils::sanitize(*newpoly)); + } } else if (geom->getDimension() == 3) { shared_ptr ps = dynamic_pointer_cast(geom); From 94aabb05b541328c50dcc65c22b46e69624fb7bf Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 8 Dec 2014 00:57:28 -0500 Subject: [PATCH 109/263] #1054 Fixed memory leak --- src/GeometryEvaluator.cc | 4 ++-- src/cgalutils.cc | 13 +++++++------ src/cgalutils.h | 5 +++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 40250c68..94130ce9 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -123,8 +123,7 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const Abstr if (op == OPENSCAD_MINKOWSKI) return ResultObject(CGALUtils::applyMinkowski(children)); - CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron; - CGALUtils::applyOperator(children, *N, op); + CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(children, op); return ResultObject(N); } @@ -354,6 +353,7 @@ void GeometryEvaluator::addToParent(const State &state, // Root node, insert into cache smartCacheInsert(node, geom); this->root = geom; + assert(this->visitedchildren.empty()); } } diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 5693ed60..50f87187 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -603,8 +603,7 @@ namespace CGALUtils { fake_children.push_back(std::make_pair((const AbstractNode*)NULL, shared_ptr(createNefPolyhedronFromGeometry(ps)))); } - CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron; - CGALUtils::applyOperator(fake_children, *N, OPENSCAD_UNION); + CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(fake_children, OPENSCAD_UNION); t.stop(); PRINTDB("Minkowski: Union done: %f s",t.time()); t.reset(); @@ -623,8 +622,7 @@ namespace CGALUtils { // If anything throws we simply fall back to Nef Minkowski PRINTD("Minkowski: Falling back to Nef Minkowski"); - CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron; - applyOperator(children, *N, OPENSCAD_MINKOWSKI); + CGAL_Nef_polyhedron *N = applyOperator(children, OPENSCAD_MINKOWSKI); return N; } } @@ -633,7 +631,7 @@ namespace CGALUtils { Applies op to all children and stores the result in dest. The child list should be guaranteed to contain non-NULL 3D or empty Geometry objects */ - void applyOperator(const Geometry::ChildList &children, CGAL_Nef_polyhedron &dest, OpenSCADOperator op) + CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op) { // Speeds up n-ary union operations significantly CGAL::Nef_nary_union_3 nary_union; @@ -720,13 +718,15 @@ namespace CGALUtils { } CGAL::set_error_behaviour(old_behaviour); } - if (N) dest = *N; + return N; } /*! Modifies target by applying op to target and src: target = target [op] src */ +//FIXME: Old, can be removed: +#if 0 void applyBinaryOperator(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op) { if (target.getDimension() != 2 && target.getDimension() != 3) { @@ -772,6 +772,7 @@ namespace CGALUtils { } CGAL::set_error_behaviour(old_behaviour); } +#endif static void add_outline_to_poly(CGAL_Nef_polyhedron2::Explorer &explorer, CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator circ, diff --git a/src/cgalutils.h b/src/cgalutils.h index 225e93f1..364ff80e 100644 --- a/src/cgalutils.h +++ b/src/cgalutils.h @@ -13,8 +13,9 @@ typedef std::vector PolyholeK; namespace CGALUtils { bool applyHull(const Geometry::ChildList &children, PolySet &P); - void applyOperator(const Geometry::ChildList &children, CGAL_Nef_polyhedron &dest, OpenSCADOperator op); - void applyBinaryOperator(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op); + CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op); + //FIXME: Old, can be removed: + //void applyBinaryOperator(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, OpenSCADOperator op); Polygon2d *project(const CGAL_Nef_polyhedron &N, bool cut); CGAL_Iso_cuboid_3 boundingBox(const CGAL_Nef_polyhedron3 &N); bool is_approximately_convex(const PolySet &ps); From 342af594adc9b7a7ad495aee1335fc0447ff7637 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 8 Dec 2014 18:54:39 +0100 Subject: [PATCH 110/263] Disable vertical refresh syncing. --- src/openscad.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/openscad.cc b/src/openscad.cc index 5080b814..54349f7f 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -625,14 +625,20 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha updater->init(); #endif + QGLFormat fmt; #if 0 /*** disabled by clifford wolf: adds rendering artefacts with OpenCSG ***/ // turn on anti-aliasing - QGLFormat f; - f.setSampleBuffers(true); - f.setSamples(4); - QGLFormat::setDefaultFormat(f); + fmt.setSampleBuffers(true); + fmt.setSamples(4); #endif - + // The default SwapInterval causes very bad interactive behavior as + // waiting for the buffer swap seems to block mouse events. So the + // effect is that we can process mouse events at the frequency of + // the screen retrace interval causing them to queue up. + // (see https://bugreports.qt-project.org/browse/QTBUG-39370 + fmt.setSwapInterval(0); + QGLFormat::setDefaultFormat(fmt); + set_render_color_scheme(arg_colorscheme, false); bool noInputFiles = false; From 0a049f7ab2e159d00fe572c87096ca21e8fb90ba Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 8 Dec 2014 17:53:19 -0500 Subject: [PATCH 111/263] removed fixed fixme --- testdata/scad/3D/features/transform-tests.scad | 2 -- 1 file changed, 2 deletions(-) diff --git a/testdata/scad/3D/features/transform-tests.scad b/testdata/scad/3D/features/transform-tests.scad index e2dd71e1..0c922c78 100644 --- a/testdata/scad/3D/features/transform-tests.scad +++ b/testdata/scad/3D/features/transform-tests.scad @@ -15,5 +15,3 @@ multmatrix([[1,0.4,0.1,-25], [0.4,0.8,0,-25], [0.2,0.2,0.5,0], [0,0,0,1]]) mycyl(); - -//FIXME: mirror() and scale() \ No newline at end of file From c03350e3cb5ad993e96699fe69373269561f04a4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 8 Dec 2014 17:53:40 -0500 Subject: [PATCH 112/263] Added more nullspace tests --- .../scad/3D/features/nullspace-difference.scad | 4 ++++ .../3D/features/nullspace-intersection.scad | 4 ++++ .../nullspace-minkowski-intersection.scad | 10 ++++++++++ .../scad/3D/features/nullspace-minkowski.scad | 7 +++++++ .../3D/features/nullspace-minkowski.scad.csg | 13 +++++++++++++ .../nullspace-difference-expected.png | Bin 0 -> 4408 bytes .../nullspace-intersection-expected.png | Bin 0 -> 4408 bytes .../nullspace-minkowski-expected.png | Bin 0 -> 4408 bytes ...ullspace-minkowski-intersection-expected.png | Bin 0 -> 4408 bytes .../dumptest/nullspace-difference-expected.csg | 6 ++++++ .../nullspace-intersection-expected.csg | 10 ++++++++++ .../dumptest/nullspace-minkowski-expected.csg | 13 +++++++++++++ ...ullspace-minkowski-intersection-expected.csg | 16 ++++++++++++++++ .../nullspace-difference-expected.png | Bin 0 -> 4408 bytes .../nullspace-intersection-expected.png | Bin 0 -> 4408 bytes .../nullspace-minkowski-expected.png | Bin 0 -> 4408 bytes ...ullspace-minkowski-intersection-expected.png | Bin 0 -> 4408 bytes .../nullspace-difference-expected.png | Bin 0 -> 4408 bytes .../nullspace-intersection-expected.png | Bin 0 -> 4408 bytes .../nullspace-minkowski-expected.png | Bin 0 -> 4408 bytes ...ullspace-minkowski-intersection-expected.png | Bin 0 -> 4408 bytes 21 files changed, 83 insertions(+) create mode 100644 testdata/scad/3D/features/nullspace-difference.scad create mode 100644 testdata/scad/3D/features/nullspace-intersection.scad create mode 100644 testdata/scad/3D/features/nullspace-minkowski-intersection.scad create mode 100644 testdata/scad/3D/features/nullspace-minkowski.scad create mode 100644 testdata/scad/3D/features/nullspace-minkowski.scad.csg create mode 100644 tests/regression/cgalpngtest/nullspace-difference-expected.png create mode 100644 tests/regression/cgalpngtest/nullspace-intersection-expected.png create mode 100644 tests/regression/cgalpngtest/nullspace-minkowski-expected.png create mode 100644 tests/regression/cgalpngtest/nullspace-minkowski-intersection-expected.png create mode 100644 tests/regression/dumptest/nullspace-difference-expected.csg create mode 100644 tests/regression/dumptest/nullspace-intersection-expected.csg create mode 100644 tests/regression/dumptest/nullspace-minkowski-expected.csg create mode 100644 tests/regression/dumptest/nullspace-minkowski-intersection-expected.csg create mode 100644 tests/regression/opencsgtest/nullspace-difference-expected.png create mode 100644 tests/regression/opencsgtest/nullspace-intersection-expected.png create mode 100644 tests/regression/opencsgtest/nullspace-minkowski-expected.png create mode 100644 tests/regression/opencsgtest/nullspace-minkowski-intersection-expected.png create mode 100644 tests/regression/throwntogethertest/nullspace-difference-expected.png create mode 100644 tests/regression/throwntogethertest/nullspace-intersection-expected.png create mode 100644 tests/regression/throwntogethertest/nullspace-minkowski-expected.png create mode 100644 tests/regression/throwntogethertest/nullspace-minkowski-intersection-expected.png diff --git a/testdata/scad/3D/features/nullspace-difference.scad b/testdata/scad/3D/features/nullspace-difference.scad new file mode 100644 index 00000000..7db36eae --- /dev/null +++ b/testdata/scad/3D/features/nullspace-difference.scad @@ -0,0 +1,4 @@ +difference() { + cube(1, center=true); + cube(2, center=true); +} diff --git a/testdata/scad/3D/features/nullspace-intersection.scad b/testdata/scad/3D/features/nullspace-intersection.scad new file mode 100644 index 00000000..b58b3e0e --- /dev/null +++ b/testdata/scad/3D/features/nullspace-intersection.scad @@ -0,0 +1,4 @@ +intersection() { + translate([-2,0,0]) cube(1); + translate([2,0,0]) cube(1); +} diff --git a/testdata/scad/3D/features/nullspace-minkowski-intersection.scad b/testdata/scad/3D/features/nullspace-minkowski-intersection.scad new file mode 100644 index 00000000..617eae82 --- /dev/null +++ b/testdata/scad/3D/features/nullspace-minkowski-intersection.scad @@ -0,0 +1,10 @@ +intersection() { + minkowski() { + intersection() { + translate([-2,0,0]) cube(1); + translate([2,0,0]) cube(1); + } + cube(); + } + cube(); +} diff --git a/testdata/scad/3D/features/nullspace-minkowski.scad b/testdata/scad/3D/features/nullspace-minkowski.scad new file mode 100644 index 00000000..c1cb6b50 --- /dev/null +++ b/testdata/scad/3D/features/nullspace-minkowski.scad @@ -0,0 +1,7 @@ +minkowski() { + intersection() { + translate([-2,0,0]) cube(1); + translate([2,0,0]) cube(1); + } + cube(); +} diff --git a/testdata/scad/3D/features/nullspace-minkowski.scad.csg b/testdata/scad/3D/features/nullspace-minkowski.scad.csg new file mode 100644 index 00000000..e387596e --- /dev/null +++ b/testdata/scad/3D/features/nullspace-minkowski.scad.csg @@ -0,0 +1,13 @@ +group() { + minkowski(convexity = 0) { + intersection() { + multmatrix([[1, 0, 0, -2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + cube(size = [1, 1, 1], center = false); + } + multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + cube(size = [1, 1, 1], center = false); + } + } + cube(size = [1, 1, 1], center = false); + } +} diff --git a/tests/regression/cgalpngtest/nullspace-difference-expected.png b/tests/regression/cgalpngtest/nullspace-difference-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..08ee92b2216f45ca6b83efbc3b78c9fdabf45a71 GIT binary patch literal 4408 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 Date: Mon, 8 Dec 2014 18:24:09 -0500 Subject: [PATCH 113/263] Disabled less useful test --- tests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e190b10c..0a3ff6ab 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1124,6 +1124,7 @@ disable_tests( # Not useful throwntogethertest_internal-cavity throwntogethertest_internal-cavity-polyhedron + throwntogethertest_nullspace-difference # these take too long, for little relative gain in testing stlpngtest_iteration From 2462799655b0b2f49655204303f10a65e11309bb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 8 Dec 2014 18:25:48 -0500 Subject: [PATCH 114/263] Handle a bunch of nullspace corner cases. Fixes #1029 --- src/CGAL_Nef_polyhedron.cc | 5 ++++ src/CGAL_Nef_polyhedron.h | 2 +- src/CsgInfo.h | 13 +-------- src/GeometryEvaluator.cc | 12 ++++++--- src/cgalutils.cc | 4 +-- src/export_png.cc | 5 +--- src/mainwin.cc | 27 +++++++++---------- .../3D/features/nullspace-minkowski.scad.csg | 13 --------- 8 files changed, 30 insertions(+), 51 deletions(-) delete mode 100644 testdata/scad/3D/features/nullspace-minkowski.scad.csg diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index dfe16536..d49521e0 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -48,6 +48,11 @@ size_t CGAL_Nef_polyhedron::memsize() const return memsize; } +bool CGAL_Nef_polyhedron::isEmpty() const +{ + return !this->p3 || this->p3->is_empty(); +} + /*! Creates a new PolySet and initializes it with the data from this polyhedron diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h index f3585469..2d7b37d6 100644 --- a/src/CGAL_Nef_polyhedron.h +++ b/src/CGAL_Nef_polyhedron.h @@ -19,7 +19,7 @@ public: virtual std::string dump() const; virtual unsigned int getDimension() const { return 3; } // Empty means it is a geometric node which has zero area/volume - virtual bool isEmpty() const { return !p3; } + virtual bool isEmpty() const; virtual Geometry *copy() const { return new CGAL_Nef_polyhedron(*this); } void reset() { p3.reset(); } diff --git a/src/CsgInfo.h b/src/CsgInfo.h index c50ab4d4..8a3512c8 100644 --- a/src/CsgInfo.h +++ b/src/CsgInfo.h @@ -12,13 +12,8 @@ class CsgInfo { public: - CsgInfo() + CsgInfo() : glview(NULL), root_chain(NULL), highlights_chain(NULL), background_chain(NULL), progress_function(NULL) { - root_chain = NULL; - highlights_chain = NULL; - background_chain = NULL; - glview = NULL; - progress_function = NULL; normalizelimit = RenderSettings::inst()->openCSGTermLimit; } OffscreenView *glview; @@ -43,12 +38,6 @@ public: CSGTermEvaluator evaluator(tree, &geomevaluator); boost::shared_ptr root_raw_term = evaluator.evaluateCSGTerm( *root_node, this->highlight_terms, this->background_terms ); - if (!root_raw_term && this->background_terms.empty()) { - PRINT("Error: CSG generation failed! (no objects found)"); - call_progress_function(); - return false; - } - PRINT("Compiling design (CSG Products normalization)..."); call_progress_function(); CSGTermNormalizer normalizer( normalizelimit ); diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 94130ce9..24118c1f 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -63,10 +63,12 @@ shared_ptr GeometryEvaluator::evaluateGeometry(const AbstractNod PolySet *ps = new PolySet(3); ps->setConvexity(N->getConvexity()); this->root.reset(ps); - bool err = CGALUtils::createPolySetFromNefPolyhedron3(*N->p3, *ps); - if (err) { - PRINT("ERROR: Nef->PolySet failed"); - } + if (!N->isEmpty()) { + bool err = CGALUtils::createPolySetFromNefPolyhedron3(*N->p3, *ps); + if (err) { + PRINT("ERROR: Nef->PolySet failed"); + } + } smartCacheInsert(node, this->root); } @@ -124,6 +126,8 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const Abstr if (op == OPENSCAD_MINKOWSKI) return ResultObject(CGALUtils::applyMinkowski(children)); CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(children, op); + // FIXME: Clarify when we can return NULL and what that means + if (!N) N = new CGAL_Nef_polyhedron; return ResultObject(N); } diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 50f87187..41c5f192 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -609,7 +609,7 @@ namespace CGALUtils { t.reset(); operands[0] = N; } else { - return NULL; + operands[0] = new CGAL_Nef_polyhedron(); } } @@ -628,7 +628,7 @@ namespace CGALUtils { } /*! - Applies op to all children and stores the result in dest. + Applies op to all children and returns the result. The child list should be guaranteed to contain non-NULL 3D or empty Geometry objects */ CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op) diff --git a/src/export_png.cc b/src/export_png.cc index 69770547..80dda0ca 100644 --- a/src/export_png.cc +++ b/src/export_png.cc @@ -53,10 +53,7 @@ void export_png_preview_common(Tree &tree, Camera &cam, std::ostream &output, Pr { PRINTD("export_png_preview_common"); CsgInfo csgInfo = CsgInfo(); - if (!csgInfo.compile_chains(tree)) { - fprintf(stderr,"Couldn't initialize CSG chains\n"); - return; - } + csgInfo.compile_chains(tree); try { csgInfo.glview = new OffscreenView(cam.pixel_width, cam.pixel_height); diff --git a/src/mainwin.cc b/src/mainwin.cc index 92d64a16..a4601f59 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1051,9 +1051,6 @@ void MainWindow::compileCSG(bool procevents) CSGTermEvaluator csgrenderer(this->tree, &geomevaluator); if (procevents) QApplication::processEvents(); this->root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms); - if (!root_raw_term && background_terms.empty()) { - PRINT("ERROR: CSG generation failed! (no objects found)"); - } GeometryCache::instance()->print(); #ifdef ENABLE_CGAL CGALCache::instance()->print(); @@ -1768,8 +1765,8 @@ void MainWindow::actionRenderDone(shared_ptr root_geom) int s = this->progresswidget->elapsedTime() / 1000; PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60)); - if (const CGAL_Nef_polyhedron *N = dynamic_cast(root_geom.get())) { - if (!N->isEmpty()) { + if (root_geom && !root_geom->isEmpty()) { + if (const CGAL_Nef_polyhedron *N = dynamic_cast(root_geom.get())) { if (N->getDimension() == 3) { PRINT(" Top level object is a 3D object:"); PRINTB(" Simple: %6s", (N->p3->is_simple() ? "yes" : "no")); @@ -1781,16 +1778,16 @@ void MainWindow::actionRenderDone(shared_ptr root_geom) PRINTB(" Volumes: %6d", N->p3->number_of_volumes()); } } - } - else if (const PolySet *ps = dynamic_cast(root_geom.get())) { - assert(ps->getDimension() == 3); - PRINT(" Top level object is a 3D object:"); - PRINTB(" Facets: %6d", ps->numPolygons()); - } else if (const Polygon2d *poly = dynamic_cast(root_geom.get())) { - PRINT(" Top level object is a 2D object:"); - PRINTB(" Contours: %6d", poly->outlines().size()); - } else { - assert(false && "Unknown geometry type"); + else if (const PolySet *ps = dynamic_cast(root_geom.get())) { + assert(ps->getDimension() == 3); + PRINT(" Top level object is a 3D object:"); + PRINTB(" Facets: %6d", ps->numPolygons()); + } else if (const Polygon2d *poly = dynamic_cast(root_geom.get())) { + PRINT(" Top level object is a 2D object:"); + PRINTB(" Contours: %6d", poly->outlines().size()); + } else { + assert(false && "Unknown geometry type"); + } } PRINT("Rendering finished."); diff --git a/testdata/scad/3D/features/nullspace-minkowski.scad.csg b/testdata/scad/3D/features/nullspace-minkowski.scad.csg deleted file mode 100644 index e387596e..00000000 --- a/testdata/scad/3D/features/nullspace-minkowski.scad.csg +++ /dev/null @@ -1,13 +0,0 @@ -group() { - minkowski(convexity = 0) { - intersection() { - multmatrix([[1, 0, 0, -2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - cube(size = [1, 1, 1], center = false); - } - multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - cube(size = [1, 1, 1], center = false); - } - } - cube(size = [1, 1, 1], center = false); - } -} From f4a6da7fb0e74766fbdc404c2ff388dce776910c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 19:13:56 +0100 Subject: [PATCH 115/263] Try to detect if compiling with a 32bit or 64bit compiler. --- src/LibraryInfo.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/LibraryInfo.cc b/src/LibraryInfo.cc index 83f3875c..71e36971 100644 --- a/src/LibraryInfo.cc +++ b/src/LibraryInfo.cc @@ -29,12 +29,20 @@ std::string LibraryInfo::info() { std::stringstream s; +#if defined(__x86_64__) || defined(_M_X64) + std::string bits(" 64bit"); +#elif defined(__i386) || defined(_M_IX86) + std::string bits(" 32bit"); +#else + std::string bits(""); +#endif + #if defined(__GNUG__) && !defined(__clang__) - std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) ); + std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) + bits); #elif defined(_MSC_VER) - std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) ); + std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) + bits); #elif defined(__clang__) - std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) ); + std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) + bits); #else std::string compiler_info( "unknown compiler" ); #endif From f7816e02cd720b95cac4b415706c5d8ade94d87f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 19:14:43 +0100 Subject: [PATCH 116/263] Add system info (OS / CPUs/ RAM / Distribution (when on Linux)). --- src/LibraryInfo.cc | 1 + src/PlatformUtils-mac.mm | 42 +++++++++++++++ src/PlatformUtils-posix.cc | 102 +++++++++++++++++++++++++++++++++++++ src/PlatformUtils-win.cc | 90 ++++++++++++++++++++++++++++++++ src/PlatformUtils.cc | 23 +++++++++ src/PlatformUtils.h | 20 ++++++++ 6 files changed, 278 insertions(+) diff --git a/src/LibraryInfo.cc b/src/LibraryInfo.cc index 71e36971..52facbb1 100644 --- a/src/LibraryInfo.cc +++ b/src/LibraryInfo.cc @@ -88,6 +88,7 @@ std::string LibraryInfo::info() const char *env_font_path = getenv("OPENSCAD_FONT_PATH"); s << "OpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION) + << "\nSystem information: " << PlatformUtils::sysinfo() << "\nCompiler, build date: " << compiler_info << ", " << __DATE__ << "\nBoost version: " << BOOST_LIB_VERSION << "\nEigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index cb93e522..20e72321 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -35,5 +35,47 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +std::string PlatformUtils::sysinfo() +{ + std::string result; + +#if 0 + struct utsname osinfo; + if (uname(&osinfo) == 0) { + result += osinfo.sysname; + result += " "; + result += osinfo.release; + result += " "; + result += osinfo.version; + result += " "; + result += osinfo.machine; + } else { +#endif + result += "Unknown MacOS"; +#if 0 + } + + long numcpu = sysconf(_SC_NPROCESSORS_ONLN); + if (numcpu > 0) { + result += " "; + result += boost::lexical_cast(numcpu); + result += " CPU"; + if (numcpu > 1) { + result += "s"; + } + } + + long pages = sysconf(_SC_PHYS_PAGES); + long pagesize = sysconf(_SC_PAGE_SIZE); + if ((pages > 0) && (pagesize > 0)) { + result += " "; + result += PlatformUtils::toMemorySizeString(pages * pagesize, 2); + result += " RAM"; + } +#endif + + return result; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index 3854a5e7..dbeaa411 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -1,4 +1,13 @@ +#include +#include +#include +#include #include +#include + +#include +#include +#include #include "PlatformUtils.h" #include "boosty.h" @@ -60,5 +69,98 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +/** + * Check /etc/os-release as defined by systemd. + * @see http://0pointer.de/blog/projects/os-release.html + * @see http://www.freedesktop.org/software/systemd/man/os-release.html + * @return the PRETTY_NAME from the os-release file or an empty string. + */ +static std::string checkOsRelease() +{ + std::ifstream os_release_stream("/etc/os-release"); + std::string os_release((std::istreambuf_iterator(os_release_stream)), std::istreambuf_iterator()); + + boost::smatch results; + boost::regex pretty_name("^PRETTY_NAME=\"([^\"]+)\""); + if (boost::regex_search(os_release, results, pretty_name)) { + return results[1]; + } + + return ""; +} + +static std::string checkEtcIssue() +{ + std::ifstream issue_stream("/etc/issue"); + std::string issue((std::istreambuf_iterator(issue_stream)), std::istreambuf_iterator()); + + boost::regex nl("\n.*$"); + issue = boost::regex_replace(issue, nl, ""); + boost::regex esc("\\\\."); + issue = boost::regex_replace(issue, esc, ""); + boost::algorithm::trim(issue); + + return issue; +} + +static std::string detectDistribution() +{ + std::string osrelease = checkOsRelease(); + if (!osrelease.empty()) { + return osrelease; + } + + std::string etcissue = checkEtcIssue(); + if (!etcissue.empty()) { + return etcissue; + } + + return ""; +} + +std::string PlatformUtils::sysinfo() +{ + std::string result; + + struct utsname osinfo; + if (uname(&osinfo) == 0) { + result += osinfo.sysname; + result += " "; + result += osinfo.release; + result += " "; + result += osinfo.version; + result += " "; + result += osinfo.machine; + } else { + result += "Unknown Linux"; + } + + long numcpu = sysconf(_SC_NPROCESSORS_ONLN); + if (numcpu > 0) { + result += " "; + result += boost::lexical_cast(numcpu); + result += " CPU"; + if (numcpu > 1) { + result += "s"; + } + } + + long pages = sysconf(_SC_PHYS_PAGES); + long pagesize = sysconf(_SC_PAGE_SIZE); + if ((pages > 0) && (pagesize > 0)) { + result += " "; + result += PlatformUtils::toMemorySizeString(pages * pagesize, 2); + result += " RAM"; + } + + std::string distribution = detectDistribution(); + if (!distribution.empty()) { + result += " "; + result += distribution; + } + + return result; +} + void PlatformUtils::ensureStdIO(void) {} diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index c83855d0..1f07b683 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -98,6 +98,96 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + +// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx +static BOOL IsWow64() +{ + BOOL bIsWow64 = FALSE; + + //IsWow64Process is not available on all supported versions of Windows. + //Use GetModuleHandle to get a handle to the DLL that contains the function + //and GetProcAddress to get a pointer to the function if available. + LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); + + if (NULL != fnIsWow64Process) { + if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) + { + return false; + } + } + return bIsWow64; +} + +std::string PlatformUtils::sysinfo() +{ + std::string result; + + OSVERSIONINFOEX osinfo; + osinfo.dwOSVersionInfoSize = sizeof(osinfo); + if (GetVersionEx((OSVERSIONINFO*)&osinfo) == 0) { + result += "Unknown Windows"; + } else { + unsigned int version = osinfo.dwMajorVersion * 1000 + osinfo.dwMinorVersion; + if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { + switch (version) { + case 5000: + result += "Windows 2000"; + break; + case 5001: + result += "Windows XP"; + break; + case 5002: + result += "Windows Server 2003"; + break; + case 6000: + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows Server 2008"); + break; + case 6001: + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows Server 2008 R2"); + break; + case 6002: + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows Server 2012"); + break; + case 6003: + // For applications that have been manifested for Windows 8.1. + result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows Server 2012 R2"); + break; + } + boost::format fmt(" (v%d.%d)"); + fmt % osinfo.dwMajorVersion % osinfo.dwMinorVersion; + result += fmt.str(); + } else { + boost::format fmt("Unknown Windows (dwPlatformId = %d, dwMajorVersion = %d, dwMinorVersion = %d"); + fmt % osinfo.dwPlatformId % osinfo.dwMajorVersion % osinfo.dwMinorVersion; + result += fmt.str(); + } + } + + SYSTEM_INFO systeminfo; + bool isWow64 = IsWow64(); + if (isWow64) { + GetNativeSystemInfo(&systeminfo); + } else { + GetSystemInfo(&systeminfo); + } + + int numcpu = systeminfo.dwNumberOfProcessors; + boost::format fmt(" %d CPU%s%s"); + fmt % numcpu % (numcpu > 1 ? "s" : "") % (isWow64 ? " WOW64" : ""); + result += fmt.str(); + + MEMORYSTATUSEX memoryinfo; + memoryinfo.dwLength = sizeof(memoryinfo); + if (GlobalMemoryStatusEx(&memoryinfo) != 0) { + result += " "; + result += PlatformUtils::toMemorySizeString(memoryinfo.ullTotalPhys, 2); + result += " RAM"; + } + + return result; +} + #include #include #include diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index 2ebc9950..a15a0a3c 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -1,4 +1,5 @@ #include +#include #include "PlatformUtils.h" @@ -190,3 +191,25 @@ int PlatformUtils::setenv(const char *name, const char *value, int overwrite) return ::setenv(name, value, overwrite); #endif } + +std::string PlatformUtils::toMemorySizeString(unsigned long bytes, int digits) +{ + static const char *units[] = { "B", "kB", "MB", "GB", "TB", NULL }; + + int idx = 0; + double val = bytes; + while (true) { + if (val < 1024.0) { + break; + } + if (units[idx + 1] == NULL) { + break; + } + idx++; + val /= 1024.0; + } + + boost::format fmt("%f %s"); + fmt % boost::io::group(std::setprecision(digits), val) % units[idx]; + return fmt.str(); +} diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index a5c2ec91..5210dc85 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -34,6 +34,20 @@ namespace PlatformUtils { std::string backupPath(); bool createBackupPath(); + /** + * Return a human readable text describing the operating system + * the application is currently running on. This is mainly intended + * to provide information for bug reports (e.g. to be included in + * the LibraryInfoDialog). + * + * If there is some error to retrieve the details, at least the + * OS type is reported based on what platform the application was + * built for. + * + * @return system information. + */ + std::string sysinfo(); + /** * Platform abstraction to set environment variables. Windows/MinGW * does not support setenv(), but needs _putenv(). @@ -65,4 +79,10 @@ namespace PlatformUtils { * Currently limited to MS Windows GUI application console only. */ void ensureStdIO(void); + + /** + * Convert the number of bytes to a human readable string with + * a given number of digits. + */ + std::string toMemorySizeString(unsigned long bytes, int digits); } From ba8446e8bfbf770926a13b2d312187077adcb368 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 22:06:06 +0100 Subject: [PATCH 117/263] Remove qtaccessiblewidgets as QTPLUGIN. MXE now ships Qt-5.4.0-rc which has accessibility built-in. All other platforms did not have it enabled so far. --- openscad.pro | 3 --- 1 file changed, 3 deletions(-) diff --git a/openscad.pro b/openscad.pro index cf374a44..d745c708 100644 --- a/openscad.pro +++ b/openscad.pro @@ -116,7 +116,6 @@ macx { win* { RC_FILE = openscad_win32.rc - QTPLUGIN += qtaccessiblewidgets } CONFIG += qt @@ -130,8 +129,6 @@ unix:!macx { QMAKE_LIBS_OPENGL *= -lX11 } -#QTPLUGIN += qtaccessiblewidgets - netbsd* { QMAKE_LFLAGS += -L/usr/X11R7/lib QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib From 6d9329966a77a73193acfea6d8d410dd5da8d071 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 9 Dec 2014 16:42:02 -0500 Subject: [PATCH 118/263] #1061 fixed test build behaving differently from GUI build due to ENABLE_CGAL flag not being passed to all relevant sources. Added testcase --- src/polyset-utils.cc | 15 +++++++++++++++ src/polyset-utils.h | 1 + src/polyset.cc | 15 +++------------ testdata/scad/bugs/issue1061.scad | 1 + tests/CMakeLists.txt | 16 +++++++++------- .../cgalpngtest/issue1061-expected.png | Bin 0 -> 10709 bytes .../monotonepngtest/issue1061-expected.png | Bin 0 -> 10709 bytes .../opencsgtest/issue1061-expected.png | Bin 0 -> 11401 bytes 8 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 testdata/scad/bugs/issue1061.scad create mode 100644 tests/regression/cgalpngtest/issue1061-expected.png create mode 100644 tests/regression/monotonepngtest/issue1061-expected.png create mode 100644 tests/regression/opencsgtest/issue1061-expected.png diff --git a/src/polyset-utils.cc b/src/polyset-utils.cc index 5587be6e..b3bba6d7 100644 --- a/src/polyset-utils.cc +++ b/src/polyset-utils.cc @@ -2,7 +2,9 @@ #include "polyset.h" #include "Polygon2d.h" #include "printutils.h" +#ifdef ENABLE_CGAL #include "cgalutils.h" +#endif #include @@ -45,6 +47,7 @@ namespace PolysetUtils { The tessellation will be robust wrt. degenerate and self-intersecting */ void tessellate_faces(const PolySet &inps, PolySet &outps) { +#ifdef ENABLE_CGAL int degeneratePolygons = 0; for (size_t i = 0; i < inps.polygons.size(); i++) { const Polygon pgon = inps.polygons[i]; @@ -76,5 +79,17 @@ namespace PolysetUtils { } } if (degeneratePolygons > 0) PRINT("WARNING: PolySet has degenerate polygons"); +#else + assert(false); +#endif } + + bool is_approximately_convex(const PolySet &ps) { +#ifdef ENABLE_CGAL + return CGALUtils::is_approximately_convex(ps); +#else + return false; +#endif + } + } diff --git a/src/polyset-utils.h b/src/polyset-utils.h index 2bdaca03..41364f07 100644 --- a/src/polyset-utils.h +++ b/src/polyset-utils.h @@ -7,5 +7,6 @@ namespace PolysetUtils { Polygon2d *project(const PolySet &ps); void tessellate_faces(const PolySet &inps, PolySet &outps); + bool is_approximately_convex(const PolySet &ps); }; diff --git a/src/polyset.cc b/src/polyset.cc index 0dfc2ba8..fc8e7e04 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -25,6 +25,7 @@ */ #include "polyset.h" +#include "polyset-utils.h" #include "linalg.h" #include "printutils.h" #include @@ -140,20 +141,10 @@ void PolySet::transform(const Transform3d &mat) } } -namespace CGALUtils { - extern bool is_approximately_convex(const PolySet &ps); -} - bool PolySet::is_convex() const { - if (convex) return true; + if (convex) return true; if (!convex) return false; - -#ifdef ENABLE_CGAL - convex = CGALUtils::is_approximately_convex(*this); - return convex; -#else - return false; -#endif + return PolysetUtils::is_approximately_convex(*this); } void PolySet::resize(Vector3d newsize, const Eigen::Matrix &autosize) diff --git a/testdata/scad/bugs/issue1061.scad b/testdata/scad/bugs/issue1061.scad new file mode 100644 index 00000000..70cc35cc --- /dev/null +++ b/testdata/scad/bugs/issue1061.scad @@ -0,0 +1 @@ +polyhedron(points = [[-5, -5, 0], [-5, 5, 0], [5, 5, 0], [5, -5, 0], [-1.87866, -4.21311, 3], [-4.21311, 5.51058, 3], [5.51058, 7.84504, 3], [7.84504, -1.87866, 3], [1.05099, -3.48892, 6], [-3.48892, 5.42115, 6], [5.42115, 9.96105, 6], [9.96105, 1.05099, 6], [3.39596, -3.09852, 9], [-3.09852, 4.50554, 9], [4.50554, 11, 9], [11, 3.39596, 9], [4.91038, -3.17979, 12], [-3.17979, 2.69807, 12], [2.69807, 10.7882, 12], [10.7882, 4.91038, 12], [5.53441, -3.70439, 15], [-3.70439, 0.122447, 15], [0.122447, 9.36124, 15], [9.36124, 5.53441, 15], [5.39234, -4.48455, 18], [-4.48455, -2.9202, 18], [-2.9202, 6.95668, 18], [6.95668, 5.39234, 18]], faces = [[0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [4, 5, 9, 8], [5, 6, 10, 9], [6, 7, 11, 10], [7, 4, 8, 11], [8, 9, 13, 12], [9, 10, 14, 13], [10, 11, 15, 14], [11, 8, 12, 15], [12, 13, 17, 16], [13, 14, 18, 17], [14, 15, 19, 18], [15, 12, 16, 19], [16, 17, 21, 20], [17, 18, 22, 21], [18, 19, 23, 22], [19, 16, 20, 23], [20, 21, 25, 24], [21, 22, 26, 25], [22, 23, 27, 26], [23, 20, 24, 27], [3, 2, 1, 0], [24, 25, 26, 27]]); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0a3ff6ab..d9b643e8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -632,7 +632,6 @@ set(CORE_SOURCES ../src/csgtermnormalizer.cc ../src/Geometry.cc ../src/Polygon2d.cc - ../src/polyset.cc ../src/csgops.cc ../src/transform.cc ../src/color.cc @@ -666,7 +665,10 @@ set(NOCGAL_SOURCES ../src/builtin.cc ../src/import.cc ../src/export.cc - ../src/LibraryInfo.cc) + ../src/LibraryInfo.cc + ../src/polyset.cc + ../src/polyset-utils.cc) + set(CGAL_SOURCES ${NOCGAL_SOURCES} @@ -678,7 +680,6 @@ set(CGAL_SOURCES ../src/CGALCache.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/Polygon2d-CGAL.cc - ../src/polyset-utils.cc ../src/svg.cc ../src/GeometryEvaluator.cc) @@ -749,20 +750,20 @@ set_target_properties(tests-offscreen PROPERTIES COMPILE_FLAGS "${ENABLE_OPENCSG # modulecachetest # add_executable(modulecachetest modulecachetest.cc) -target_link_libraries(modulecachetest tests-nocgal) +target_link_libraries(modulecachetest tests-nocgal ${GLEW_LIBRARY} ${OPENCSG_LIBRARY} ${APP_SERVICES_LIBRARY}) # # csgtexttest # add_executable(csgtexttest csgtexttest.cc CSGTextRenderer.cc CSGTextCache.cc) -target_link_libraries(csgtexttest tests-nocgal) +target_link_libraries(csgtexttest tests-nocgal ${GLEW_LIBRARY} ${OPENCSG_LIBRARY} ${APP_SERVICES_LIBRARY}) # # cgalcachetest # add_executable(cgalcachetest cgalcachetest.cc) set_target_properties(cgalcachetest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}") -target_link_libraries(cgalcachetest tests-cgal) +target_link_libraries(cgalcachetest tests-cgal ${GLEW_LIBRARY} ${OPENCSG_LIBRARY} ${APP_SERVICES_LIBRARY}) # # openscad no-qt @@ -1213,7 +1214,8 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1004.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(REMOVE_ITEM EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad) list(APPEND ALL_2D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad) diff --git a/tests/regression/cgalpngtest/issue1061-expected.png b/tests/regression/cgalpngtest/issue1061-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..78bd8525d0e2ef89c7874f2d97f9afbf5f0c0804 GIT binary patch literal 10709 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 J_jk~v{tqGIDNO(X literal 0 HcmV?d00001 From 845bd5706efa877e2cf5c0cb912ee3bfe934d7b3 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 9 Dec 2014 22:46:09 +0100 Subject: [PATCH 119/263] Guard against reading huge files. --- src/PlatformUtils-posix.cc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index dbeaa411..c3767fa7 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -69,6 +69,19 @@ unsigned long PlatformUtils::stackLimit() return STACK_LIMIT_DEFAULT; } +static std::string readText(const std::string &path) +{ + std::ifstream s(path.c_str()); + s.seekg(0, std::ios::end); + if (s.fail() || s.tellg() > 4096) { + return ""; + } + s.seekg(0, std::ios::beg); + + std::string text((std::istreambuf_iterator(s)), std::istreambuf_iterator()); + return text; +} + /** * Check /etc/os-release as defined by systemd. * @see http://0pointer.de/blog/projects/os-release.html @@ -77,8 +90,7 @@ unsigned long PlatformUtils::stackLimit() */ static std::string checkOsRelease() { - std::ifstream os_release_stream("/etc/os-release"); - std::string os_release((std::istreambuf_iterator(os_release_stream)), std::istreambuf_iterator()); + std::string os_release(readText("/etc/os-release")); boost::smatch results; boost::regex pretty_name("^PRETTY_NAME=\"([^\"]+)\""); @@ -91,8 +103,7 @@ static std::string checkOsRelease() static std::string checkEtcIssue() { - std::ifstream issue_stream("/etc/issue"); - std::string issue((std::istreambuf_iterator(issue_stream)), std::istreambuf_iterator()); + std::string issue(readText("/etc/issue")); boost::regex nl("\n.*$"); issue = boost::regex_replace(issue, nl, ""); From 7e728fac6a347c1fd21428540765802b1f785afe Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 9 Dec 2014 16:53:11 -0500 Subject: [PATCH 120/263] Improve polyset convexity check by tessellating polygons prior to testing. Fixes #1061 --- src/cgalutils.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 41c5f192..cc8d870f 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -273,7 +273,11 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) if (ps.isEmpty()) return new CGAL_Nef_polyhedron(); assert(ps.getDimension() == 3); - if (ps.is_convex()) { + // Since is_convex doesn't work well with non-planar faces, + // we tessellate the polyset before checking. + PolySet ps_tri(3); + PolysetUtils::tessellate_faces(ps, ps_tri); + if (ps_tri.is_convex()) { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; // Collect point cloud std::set points; @@ -316,10 +320,8 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) } } if (plane_error) try { - PolySet ps2(3); CGAL_Polyhedron P; - PolysetUtils::tessellate_faces(ps, ps2); - bool err = CGALUtils::createPolyhedronFromPolySet(ps2,P); + bool err = CGALUtils::createPolyhedronFromPolySet(ps_tri, P); if (!err) N = new CGAL_Nef_polyhedron3(P); } catch (const CGAL::Assertion_exception &e) { @@ -933,6 +935,13 @@ namespace CGALUtils { }; + /*! + Check if all faces of a polyset is within 0.1 degree of being convex. + + NB! This function can give false positives if the polyset contains + non-planar faces. To be on the safe side, consider passing a tessellated polyset. + See issue #1061. + */ bool is_approximately_convex(const PolySet &ps) { const double angle_threshold = cos(.1/180*M_PI); // .1° From 73b6700b693b95f60d98bbdd4e08562c124f5b8b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 9 Dec 2014 17:46:03 -0500 Subject: [PATCH 121/263] Empty polysets are convex. Fixes crash in is_approximately_convex() --- src/polyset.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/polyset.cc b/src/polyset.cc index fc8e7e04..ad6b6e59 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -142,7 +142,7 @@ void PolySet::transform(const Transform3d &mat) } bool PolySet::is_convex() const { - if (convex) return true; + if (convex || this->isEmpty()) return true; if (!convex) return false; return PolysetUtils::is_approximately_convex(*this); } From 39612397fa12c590594703c6d9c062458748c6d6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 10 Dec 2014 22:44:39 -0500 Subject: [PATCH 122/263] #1057 Sysinfo for Mac OS X --- src/PlatformUtils-mac.mm | 65 +++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index 20e72321..45157921 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -1,5 +1,8 @@ #include "PlatformUtils.h" #import +#include +#include +#include std::string PlatformUtils::pathSeparatorChar() { @@ -37,44 +40,30 @@ unsigned long PlatformUtils::stackLimit() std::string PlatformUtils::sysinfo() { - std::string result; - -#if 0 - struct utsname osinfo; - if (uname(&osinfo) == 0) { - result += osinfo.sysname; - result += " "; - result += osinfo.release; - result += " "; - result += osinfo.version; - result += " "; - result += osinfo.machine; - } else { -#endif - result += "Unknown MacOS"; -#if 0 - } - - long numcpu = sysconf(_SC_NPROCESSORS_ONLN); - if (numcpu > 0) { - result += " "; - result += boost::lexical_cast(numcpu); - result += " CPU"; - if (numcpu > 1) { - result += "s"; - } - } - - long pages = sysconf(_SC_PHYS_PAGES); - long pagesize = sysconf(_SC_PAGE_SIZE); - if ((pages > 0) && (pagesize > 0)) { - result += " "; - result += PlatformUtils::toMemorySizeString(pages * pagesize, 2); - result += " RAM"; - } -#endif - - return result; + std::string result; + + result += "Mac OS X "; + result += [[[NSProcessInfo processInfo] operatingSystemVersionString] UTF8String]; + + int mib[2]; + int64_t physical_memory; + int32_t numcpu; + size_t length64 = sizeof(int64_t); + size_t length32 = sizeof(int32_t);; + + sysctlbyname("hw.memsize", &physical_memory, &length64, NULL, 0); + sysctlbyname("hw.physicalcpu", &numcpu, &length32, NULL, 0); + + result += " "; + result += boost::lexical_cast(numcpu); + result += " CPU"; + if (numcpu > 1) result += "s"; + + result += " "; + result += PlatformUtils::toMemorySizeString(physical_memory, 2); + result += " RAM"; + + return result; } void PlatformUtils::ensureStdIO(void) {} From dd274b744a8fe77620edb5df4219296577ff4182 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 11 Dec 2014 19:42:35 +0100 Subject: [PATCH 123/263] Fix download urls for freetype and ragel; bump freetype to 2.5.4. --- scripts/macosx-build-dependencies.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index 952256e2..86bb3c7b 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -515,7 +515,7 @@ build_freetype() cd "$BASEDIR"/src rm -rf "freetype-$version" if [ ! -f "freetype-$version.tar.gz" ]; then - curl --insecure -LO "http://download.savannah.gnu.org/releases/freetype/freetype-$version.tar.gz" + curl --insecure -LO "http://downloads.sourceforge.net/project/freetype/freetype2/$version/freetype-$version.tar.gz" fi tar xzf "freetype-$version.tar.gz" cd "freetype-$version" @@ -655,7 +655,7 @@ build_ragel() cd "$BASEDIR"/src rm -rf "ragel-$version" if [ ! -f "ragel-$version.tar.gz" ]; then - curl --insecure -LO "http://www.colm.net/wp-content/uploads/2014/10/ragel-$version.tar.gz" + curl --insecure -LO "http://www.colm.net/files/ragel/ragel-$version.tar.gz" fi tar xzf "ragel-$version.tar.gz" cd "ragel-$version" @@ -784,7 +784,7 @@ build_gettext 0.18.3.2 build_libffi 3.1 build_glib2 2.40.0 build_opencsg 1.4.0 -build_freetype 2.5.3 --without-png +build_freetype 2.5.4 --without-png build_ragel 6.9 build_harfbuzz 0.9.35 "--with-coretext=auto --with-glib=no" export FREETYPE_CFLAGS="-I$DEPLOYDIR/include -I$DEPLOYDIR/include/freetype2" From 9863aa9ab275857146cb75017bed4e7505d88402 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 11 Dec 2014 16:09:55 -0500 Subject: [PATCH 124/263] #1051 Detect recursion after 1M tail recursion iterations --- src/func.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/func.cc b/src/func.cc index c7e26193..e6830099 100644 --- a/src/func.cc +++ b/src/func.cc @@ -36,6 +36,7 @@ #include "stl-utils.h" #include "printutils.h" #include "stackcheck.h" +#include "exceptions.h" #include #include @@ -150,9 +151,12 @@ ValuePtr FunctionTailRecursion::evaluate(const Context *ctx, const EvalContext * EvalContext ec(&c, call->call_arguments); Context tmp(&c); + unsigned int counter = 0; while (invert ^ expr->first->evaluate(&c)) { tmp.setVariables(definition_arguments, &ec); c.apply_variables(tmp); + + if (counter++ == 1000000) throw RecursionException("function", this->name); } ValuePtr result = endexpr->evaluate(&c); From 0a10aca8aaf49383a85cb35e7466608bc8f81d01 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 11 Dec 2014 16:37:27 -0500 Subject: [PATCH 125/263] #1051 Suppress warning and error output after 5 equal messages --- src/printutils.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/printutils.cc b/src/printutils.cc index 5004c745..4e400ccb 100644 --- a/src/printutils.cc +++ b/src/printutils.cc @@ -2,12 +2,16 @@ #include #include #include +#include +#include std::list print_messages_stack; OutputHandlerFunc *outputhandler = NULL; void *outputhandler_data = NULL; std::string OpenSCAD::debug(""); +boost::circular_buffer lastmessages(5); + void set_output_handler(OutputHandlerFunc *newhandler, void *userdata) { outputhandler = newhandler; @@ -46,6 +50,16 @@ void PRINT(const std::string &msg) void PRINT_NOCACHE(const std::string &msg) { if (msg.empty()) return; + + if (boost::starts_with(msg, "WARNING") || boost::starts_with(msg, "ERROR")) { + int i; + for (i=0;i Date: Thu, 11 Dec 2014 16:58:20 -0500 Subject: [PATCH 126/263] #600 Tag menu action roles to allow translated menu items to move to the correct Mac OS X menu --- src/MainWindow.ui | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 81f6c34b..74365644 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -543,6 +543,9 @@ Ctrl+Q + + QAction::QuitRole + @@ -955,6 +958,9 @@ About + + QAction::AboutRole + @@ -983,6 +989,9 @@ Preferences + + QAction::PreferencesRole + From 255fc1d58dbb0f45e64f2229449f21e15cb628e9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 11 Dec 2014 17:04:33 -0500 Subject: [PATCH 127/263] #1051 updated test results after suppressing repeated error messages --- tests/regression/echotest/dim-all-expected.echo | 3 --- tests/regression/echotest/for-tests-expected.echo | 11 ----------- 2 files changed, 14 deletions(-) diff --git a/tests/regression/echotest/dim-all-expected.echo b/tests/regression/echotest/dim-all-expected.echo index a16c5801..adba64d1 100644 --- a/tests/regression/echotest/dim-all-expected.echo +++ b/tests/regression/echotest/dim-all-expected.echo @@ -8,9 +8,6 @@ WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf". ECHO: ordinateX = -49.17542445724 WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf". ECHO: ordinateY = 30.86974532565 -WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf". ECHO: radius = 60 -WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf". ECHO: diameter = 120 -WARNING: Unsupported DXF Entity 'LEADER' (1) in "dim-all.dxf". ECHO: arc = 59.03624346792 diff --git a/tests/regression/echotest/for-tests-expected.echo b/tests/regression/echotest/for-tests-expected.echo index 39a8d584..d66cebf8 100644 --- a/tests/regression/echotest/for-tests-expected.echo +++ b/tests/regression/echotest/for-tests-expected.echo @@ -11,14 +11,3 @@ ECHO: "INF", 0 WARNING: Bad range parameter in for statement: too many elements (4294967295). ECHO: "-INF", 1 WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). -WARNING: Bad range parameter in for statement: too many elements (4294967295). From 9fe80a3a66afd0843442389254b911ef062e8daf Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 11 Dec 2014 17:23:45 -0500 Subject: [PATCH 128/263] Mac build fix --- src/PlatformUtils-mac.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index 45157921..768d9c09 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -1,8 +1,9 @@ #include "PlatformUtils.h" -#import -#include #include #include +#include + +#import std::string PlatformUtils::pathSeparatorChar() { From 1bbbfad5757c7174cf711a7be94a6ec5ed94ab05 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 11 Dec 2014 17:24:35 -0500 Subject: [PATCH 129/263] #964 Added test for checking correct export of nonmanifold objects --- testdata/scad/misc/nonmanifold-polyhedron.scad | 16 ++++++++++++++++ tests/CMakeLists.txt | 5 +++++ .../nonmanifold-polyhedron-expected.png | Bin 0 -> 7957 bytes 3 files changed, 21 insertions(+) create mode 100644 testdata/scad/misc/nonmanifold-polyhedron.scad create mode 100644 tests/regression/monotonepngtest/nonmanifold-polyhedron-expected.png diff --git a/testdata/scad/misc/nonmanifold-polyhedron.scad b/testdata/scad/misc/nonmanifold-polyhedron.scad new file mode 100644 index 00000000..a1b56654 --- /dev/null +++ b/testdata/scad/misc/nonmanifold-polyhedron.scad @@ -0,0 +1,16 @@ +polyhedron(points=[ +[0,0,0], +[10,0,0], +[10,10,0], +[0,10,0], +[0,-20,20], +[10,-20,20], +[10,-20,30], +[0,-20,30] +], +faces = [[0,1,2,3],[4,5,6,7], +[1,2,5,4], +[2,3,6,5], +[3,0,6,5], +[0,1,4,7] +]); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d9b643e8..0cfb1f16 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1116,6 +1116,9 @@ list(APPEND EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/3D/features ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-wing.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad) +list(APPEND EXPORTCSG_TEST_FILES + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/nonmanifold-polyhedron.scad) + disable_tests( # These don't output anything dxfpngtest_text-empty-tests @@ -1313,6 +1316,7 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake ${TMP}) # o stlpngtest: Export to STL, Re-import and render to PNG (--render=cgal) # o offpngtest: Export to OFF, Re-import and render to PNG (--render=cgal) # o dxfpngtest: Export to DXF, Re-import and render to PNG (--render=cgal) +# o stlcsgpngtest: Export to STL, Re-import and render to PNG (--preview) # add_cmdline_test(moduledumptest EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX ast FILES @@ -1356,6 +1360,7 @@ add_cmdline_test(monotonepngtest EXE ${OPENSCAD_BINPATH} ARGS --colorscheme=Mono add_cmdline_test(stlpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(offpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=OFF --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(dxfpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=DXF --render=cgal EXPECTEDDIR cgalpngtest SUFFIX png FILES ${FILES_2D}) +add_cmdline_test(stlcsgpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORTCSG_TEST_FILES}) # diff --git a/tests/regression/monotonepngtest/nonmanifold-polyhedron-expected.png b/tests/regression/monotonepngtest/nonmanifold-polyhedron-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..f3e6fe724a224865300cf4579a988d7dd5be6b38 GIT binary patch literal 7957 zcmeHM`CAiNvp#78giV8>I69aBvM8I5qoRn3A}Wf&xUeHQfq1>r_?FdwXs& z(4D6X05EXhykR>42>glw%JfIVJXbCN3%cDmtlJq+8Wv*LEbDh^i#y$B7*?Orw_8)B zv&8M3;yM4t=RG54@g&5=^@xIGOq%d6;YP@ZE79VIV>`1N$LoJn3_pC-DEoXnq{n%g zGvkC>*=j;qFj*k!IKmJF7SA@KGgVB{*4ur#R5gz6e`_&CleUk zSMP&jOwgf0rciAb)4_!~J;gdyIvso?A!Lg2Y$|Zmi|m9isbB)YM;CM{tb3;`4#Afc zkideE+%(C|mKT95;7c;gW%~Sk2*L^bWSN2Tg_>f%)e+2=G_h2$YQQ0UB>sillkt<3L|>dY1VGqT{~dD^RhdO z{}<^Q{#5wRS(ER%Zrwq= zVnORkYmjSuO9$2tP6`VQ_JtWE{p6pC0mn*^j-BzDt^%$IBBo|$QjATarb2$#ps*|( z!VJlejVGJcs44}+#_F@$e3{_8{MUITq(JA9Qk2y3bs_Ni_(WFJqOmN+<$_*OLmyxE+x)Xj=sL?~ZZvX7G z(WF2BEaUXbQ@|$Z#8zu2r{q8@+%KZHU7 z$0QC=h&ZTWM?jnanO_hr9)SM(!CS;G!0(Ou$Oir>q2rlD(_w9CEB8S%nR!wfTO%-Z zr4CE;LYNMebuy=eEBTdY`Hzr0SBMe^QFWvyna@2dquAMTRE|O2u3L@3*^cfFFnfN$ zH&e??5yT$3LfCJqeQXG7bq`lUEt76cFlGLU(6O_F0GB+Sjn5m|Xbz4_^==xadomU5 z$9sLZ`GFwI;Z;z2vlSg&oBb*VCP37bOj0QbLqfU70}PT<5FW9~AOy9hgBpub1m0c; zDHPVc*z$%`@I=jvHPQ7*sCD`q9S;bN*KfHksm37NR{R6%oV$r$%q2635jO&GjS z4K_QNLG&&lNNDZDfF0YQvW!^9lY^uvq=`!&qYUE54lZr-AoJIh{jvilb_~3XgI5`B z3_S-^i#qXxwitXVygPe3m#?yb)2lC5$T7&l@ejY3-=eTO7w@kjuZ3)-EkAxDcmUcI zfN<(=EY*UZS{YM;(VVx}b*goo@Q*qJWHNshBhF~9B}~F=A%m4j=-uA~bfMq`42es? zW6P@$T!y=u75fZGuV&?XL4dL$z4LFYD3@kMP0=i|?r6bUXT=a@#HymQil)3a z9hMip#u7FFvta{}^IlMSig~J!(7hxWxyS;OZZ8O<%?=z@ok{)&RQvZnV=$V~UGlV7HFQ0Rv}8|g`L@Hs!(pE_v+E&1(b`yMELNx&yx(HX?+y1UCl znBd#WXzipI2);Z$?Sdold6-+)=qR3Kpa#|fNgzGnFPFz-NwMRnOSoQOZ^5}A(}0=7 z;$v7^M~ydwYLS0ZRC*K^p1W~jQ6N(x+Vb<`HfKVx>L7c74}P8_z1+QL*YY6rfQK%5?NRMREp z0Sly;M&-Kvuac8c$%JkOaT_w>c5L7w0TTM;RKN_VGXS=91=l5%7$eA;jel}>KpjxE z4%Lsz`2wxcwFYxKp50iI2CdoIACORtgbphMf`3V>ufot7cAbfOLaV~M$U>({3xMWWtI#*b`YELzs@eN(TCOM%;GiaFGGknHe<40>6oBhlz5pN zRm2yl)s8uQfsz;sA)Na^IAmN0Pbpo0T+pqKMQQln#f0i_EM6fxXbygf@QC*J;CC|o z*NFm&6^=sGl?v*Q<_|qG8+jsk##0^-)zx5c-6W{vIS`*WqM76gkG1|M_2r4Ls>tji zoVH7o4~v13ll{mO6?;J=s3S|u@dz6sk(vi4$-RMyHF@pyske*PL`kx1FoPVqNNx<` z{Hr&IVh~-?qjpoT0Ahk7B>pY|@eBK6;r+x8K*vuytXVWtEyD~Rs~GF%0I#U2bIfGE zP%3-L)~Z}~GfaKpdyi~3fF*%m6e2#X5HT(}&(jQ0;vceq#Jo!a z^!b@tz=WRgYCY0ah0R1gZz`E0G$A*cASL|wa@qxz6gAMKs>o&U)hW9+f}bIgT#^Qa zSk|V(+2QJE3uj)k05dq1Ia&NS)0W@K?A;4BWF!-w@}`@5tS0js>nMwnV!0@2II|rI zhJlzXB+BFkwq(Ao8KcmyxkGJA%wOSNScAE2kwlIh=4}AKF0IVJ$C8R3d^LrbSqQNm z{xt>`VD<0w4w@ysmSW8psvL77MQCQ0R8--Ca0>HUZcxKy_}ZyT-zYATwdHj?nfdx* zdh3#;2?4h4HwDJsu>o3jDw*KMRLIE8m0L8nITjVDys)k;y>sE}k9M&{Ru0c}E9gEx z`S=mPM=F~n`nQIO(2wVN=wRVy615?G#GM>NxSZy3WRa~cO2voI;xa@`zx`2Q*zr-_ z?*BuY7SyV&_;U!a3XdKeytY`z5JKM{nCy=0?51|;)NOVLh8dl_)Zp5W|7 z>Ue0eThOvQZ+Msh-L_7|9_v&2*3i8-i=z~UaZ~MT6Fl~lDgQ-nS*bRpqDH!xV~9Xm zF|b;NzQDc&lAQ=Wt5@(zb5~$1YaNXmIMTpqpqKU7uQ>W7Q(r@S&R>`%dvtlh;F9qlV2fmdie^NZQTC_@g0;$dB9g zc3Xlub`LF2wx}~#K3^^rvE_#x{>d@XWo@l=`KFt+TS#1}ymI38axNNpSIQ`E^kNSy zK-Spgrx?Vvig-`M2l3X3;d43(+SI!T8`nWP&Yyy6o@3m37KO8bh1{holUXMaMR>Yv zzgMTu+5f7P%%{XQeY0(TrgBt%YJ!>zxFx8_V8O}^aIR$em?a{tA}mX4aI^LpluIZZ zvX0#ok=JGq^t2#`LbSFIlQNFyS)Hr_n*-*y9=GSHuocRqr=_AVJ4YAONV^^>zlUE5 zQ@3V!`?Cb7cI{RgxmshA_36zbaxaevn6`Mwp@Ao`4fsRtaxxEQu2!z9V%09JVH2}0 zj_)B!k>JY~RcA>wVKgR=1)urp@yLwOGmCHaSy8*xCd!db3dNh8V7@c!sIBjeS(FHM zvcPz>Loa|>5pjSx*L8Vbt267jv8<0)QR@^Ty_1EiieYPCAthcr>gA`*AQ+)Q7l%Q7 z1|E@<{%x@gSlRmB9opTjzS;aiebc5d-7Q{w$!p<`5K2(1+L{;{I3>W+>N|UnpK*21 z&+D<0qYg_fqE1TK<1n+Zro?3pTo!mL9}%V@?Qw*yZ@bLDWg6@duGRedNW{yhC^pym zzRD{evZ1|m{D)7kDYGVHXZqh#k$3+fWcTwOG4EtXi##2vB8VMoG%Fw?}1Mj4;u2fbQ_=g@+L}q>I z(2FIW;QQE8Q)cJ;I>$Ax680yERGrMt>!~9hNUP%Ik6>n4&Fxa3{MPF8AD*uci&r)? z=-3%4?P>K|*R$|exxho&tL)LSNX-6A7@7jU3S% zhG-kij;g0=l3Cnlce=YoR+{m2PYmG{Xd#2$U_xyW>P6qBXi|Ri3X_N)_I^Vn!;cT& zVu>{3bNdc#Lmu$Z)=Sz!_f<2Qihq2O9#ZwJvGD<@q-S(_$UR~D#vb^ z18#|?Z;SLvOI*_)-|jmn6(xSfw)fVT^uEJ+gwavPR|h)arM_Du?iUh%5?TVx-vd3p zUlJ|o;IPvcGu6?&lNSu(+VyD`b)}r2AbQ286x(D+2 zYhX#cC=CgZ4u~jX0g9IA+9^vRG4%j_bgzW)L%mXrsNk>ip-nTSxKM>(?L)m4ioBEW zi7}g{>qy@B8sp~t)Tyqjz$0)-GL8V_x+$;{vuD4qXM#)KG`z7$N^4P`4I9E;J6yj1 z4m;4LlY@0{JC%-WaqU>h>6R+dI0H7KP3E>Jty%5pG$z4qW$xkg;a>2}Sjdl&9wBi` zfLb<9JmMr1D~d~q+MMrCH$sRh%YW<(t|HR7MDes$&@UpbWb(TvzgH74uTB&a4FYr@ z%v;+s7hAY5_-DsO)~%R>>TD&xybcvILI-|2G6VMYo97Sy0^_)cHT*)D#>!bC?2zeZ?;;#d)Mc!Xo~)dh9q{6 zGVaMETLo%S_`t;>s4m8`YUL-jkg-RCRTLdA9KwY*2BmP^O2^U@c<5LSEoLfZx+sqm z4Np!vBB5j3n!DAh6*yO)M|@6b`91(K8*lrTvTS$0ysizlsP6>-=)tLK)x{2hdYr8k z$*X8Y86FoHLXC%G<%0T!iRxVncD@W-B*D+eWj^4-No9Y5v{lLomZUVtO{91)|8fnE zj1P;~O7Zb>yaomkeP|F-oD3&sF;coVu~s1BO_WPY@#!tdB&6kJs#{N?G?qA)GDW+S zU`oUiDGzI`nr-NCsq{K{B3KcUEsx~zh^N8*_2e2jKXj|a z{%07fzmnF*5b^-xM<1#XU=f-^#%Q7T4hbxL%FLs4M{f$S-6Hg5i`x0nELW|UGtn@lXqanQQu$pi~+J86j}CnStxkTIzd{;jv*zGLCy9vR*jY4p~r ze`gGFec#dt{+fxCN_n3DK+Rxv`<0}Zbto5YQ6KiVfWB^4TQ}|gMeAA&%ARC&#wYIF z0!KA_#qpn_?7;CmYPq^PLD;ATy;(Q%HYM0fOY11g#g0`~7Ttj8W%rcS@sp&YesQ6^ z=?V7s2!wPl86%$TIKb}#P9n&Bbzq}uKg@u=mh7ck4pKaT*qhK5QwJ6PHDR5###jHF zE^FBV*lE1VIuh;%vp2l$Ks_rQHhB!m+7+_95F;C6=&W^0(u5S9gy*n(HfZJB(t%I@ z$*#F!`m8^MA(D_ivVfP~@Wg6SHI3n=PmYByKTscBnhjkZ z)FrQBxawEyv!2mZVQP|d?bSB;IKw&gkk2 zA|mKWuS%@ck6!>Tv!}w;7iC-DyfLH0JI^eB&dpkWsytXQ$z2eb|YX;mQ3m^OK_CTzFe_J8sh}{uB87rpn~T9e%Ae3^rsgfnGGQ~gFs8c7rfeJbXL@+{%A`eKoTa<6`A9GZs* z#)}N+!hF{POQ30a;(Axk$)I&hOvBqV}Hl1 zqqY15Z~`4^SDsC4PS*MF0x<8mZ`mt;Hngh!qodE79Ef@Gp>_}DF|F?DKrPQ1HAaHr zR>9TPUzDA?j`sC*XEjWGV z;qH>KE^-ePbUy8vK`x&=DHo{^wB|UNGwBtuz6H}t;6E|UbbiVni}~r(|C?-w=6~p4 zx(e=bUcnTC7dYI|(aTt1bMS)HY1!MX=`Qw{e?|X|z`qgrHv<2cBQV7 Date: Thu, 11 Dec 2014 17:27:08 -0500 Subject: [PATCH 130/263] #964 Run correct tests --- tests/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0cfb1f16..885de360 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1220,7 +1220,13 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) -list(REMOVE_ITEM EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad) +list(REMOVE_ITEM EXPORT3D_TEST_FILES + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad) +list(APPEND EXPORTCSG_TEST_FILES + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad) list(APPEND ALL_2D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad) list(APPEND OPENCSGTEST_FILES ${BUGS_FILES}) From 1f032d0d7d67f31158a12da9507f65c30612807e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 11 Dec 2014 17:32:26 -0500 Subject: [PATCH 131/263] #803 Don't install OS X specific file on other platforms --- {fonts => fonts-osx/conf.d}/05-osx-fonts.conf | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {fonts => fonts-osx/conf.d}/05-osx-fonts.conf (100%) diff --git a/fonts/05-osx-fonts.conf b/fonts-osx/conf.d/05-osx-fonts.conf similarity index 100% rename from fonts/05-osx-fonts.conf rename to fonts-osx/conf.d/05-osx-fonts.conf From ad69698f97c1be731762bcc12fd8f3ba1c2bb2fc Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 11 Dec 2014 18:01:56 -0500 Subject: [PATCH 132/263] Changed stlcsgpngtest to render, not preview, to be able to reuse monotonepngtest results --- tests/CMakeLists.txt | 6 ++++-- .../nonmanifold-polyhedron-expected.png | Bin 7957 -> 7668 bytes 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 885de360..9c9f84c1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1244,6 +1244,8 @@ foreach(FILE ${BUGS_FILES}) set_test_config(Bugs ${TEST_FULLNAME}) get_test_fullname(stlpngtest ${FILE} TEST_FULLNAME) set_test_config(Bugs ${TEST_FULLNAME}) + get_test_fullname(stlcsgpngtest ${FILE} TEST_FULLNAME) + set_test_config(Bugs ${TEST_FULLNAME}) endforeach() # Examples @@ -1322,7 +1324,7 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake ${TMP}) # o stlpngtest: Export to STL, Re-import and render to PNG (--render=cgal) # o offpngtest: Export to OFF, Re-import and render to PNG (--render=cgal) # o dxfpngtest: Export to DXF, Re-import and render to PNG (--render=cgal) -# o stlcsgpngtest: Export to STL, Re-import and render to PNG (--preview) +# o stlcsgpngtest: Export to STL, Re-import and render to PNG (--render) # add_cmdline_test(moduledumptest EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX ast FILES @@ -1366,7 +1368,7 @@ add_cmdline_test(monotonepngtest EXE ${OPENSCAD_BINPATH} ARGS --colorscheme=Mono add_cmdline_test(stlpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(offpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=OFF --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(dxfpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=DXF --render=cgal EXPECTEDDIR cgalpngtest SUFFIX png FILES ${FILES_2D}) -add_cmdline_test(stlcsgpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORTCSG_TEST_FILES}) +add_cmdline_test(stlcsgpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORTCSG_TEST_FILES}) # diff --git a/tests/regression/monotonepngtest/nonmanifold-polyhedron-expected.png b/tests/regression/monotonepngtest/nonmanifold-polyhedron-expected.png index f3e6fe724a224865300cf4579a988d7dd5be6b38..27adff5c1ede8d05d1054fcf73aea0defc9bfc20 100644 GIT binary patch literal 7668 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 literal 7957 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 Date: Fri, 12 Dec 2014 14:06:28 -0500 Subject: [PATCH 133/263] Preserve whitespace inside strings when creating cache keys. Fixes #1066 --- src/Tree.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Tree.cc b/src/Tree.cc index d27e1984..d410f73a 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -3,6 +3,7 @@ #include #include +#include Tree::~Tree() { @@ -46,9 +47,13 @@ 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); + const std::string &str = getString(node); + const boost::regex re("(\".*\")|\\S+"); + std::stringstream sstream; + boost::sregex_token_iterator i(str.begin(), str.end(), re, 0); + std::copy(i, boost::sregex_token_iterator(), std::ostream_iterator(sstream)); + + return this->nodeidcache.insert(node, sstream.str()); } return this->nodeidcache[node]; } From 14870d69debf7c6e3f3acaa237c3d52d4baaa095 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 12 Dec 2014 14:35:42 -0500 Subject: [PATCH 134/263] #1066 Build fix --- src/Tree.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tree.cc b/src/Tree.cc index d410f73a..e2dc1182 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -3,6 +3,7 @@ #include #include +#include #include Tree::~Tree() From 6f68330ce019657746cc19c1633f7dbcac8a23f3 Mon Sep 17 00:00:00 2001 From: jgelderloos Date: Sat, 13 Dec 2014 16:03:25 -0500 Subject: [PATCH 135/263] Changed exit codes to 0 and added help description to help menu #1028 --- src/openscad.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/openscad.cc b/src/openscad.cc index 5080b814..54f8a9b3 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -113,6 +113,7 @@ static void help(const char *progname) PRINTB("Usage: %1% [ -o output_file [ -d deps_file ] ]\\\n" "%2%[ -m make_command ] [ -D var=val [..] ] \\\n" + "%2%[ --help ] print this help message and exit \\\n" "%2%[ --version ] [ --info ] \\\n" "%2%[ --camera=translatex,y,z,rotx,y,z,dist | \\\n" "%2% --camera=eyex,y,z,centerx,y,z ] \\\n" @@ -131,7 +132,7 @@ static void help(const char *progname) #endif "%2%filename\n", progname % (const char *)tabstr); - exit(1); + exit(0); } #define STRINGIFY(x) #x @@ -139,7 +140,7 @@ static void help(const char *progname) static void version() { PRINTB("OpenSCAD version %s\n", TOSTRING(OPENSCAD_VERSION)); - exit(1); + exit(0); } static void info() From 999e27d0daed888a3cbc5e0926a9c754ea9f4877 Mon Sep 17 00:00:00 2001 From: Keven Villeneuve Date: Sat, 13 Dec 2014 22:38:18 -0500 Subject: [PATCH 136/263] Added french translation :) --- locale/fr.po | 413 ++++++++++++++++++++++++++++----------------------- 1 file changed, 230 insertions(+), 183 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index d9722b2a..35018057 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: OpenSCAD 2013.02.07\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-13 00:22+0100\n" -"PO-Revision-Date: 2013-02-08 15:06-0600\n" -"Last-Translator: don bright \n" +"PO-Revision-Date: 2014-12-13 22:25-0500\n" +"Last-Translator: Keven Villeneuve \n" "Language-Team: French\n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -17,30 +17,31 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 1.7.1\n" #: objects/ui_AboutDialog.h:51 msgid "About OpenSCAD" -msgstr "" +msgstr "À propos de OpenSCAD" #: objects/ui_FontListDialog.h:102 msgid "OpenSCAD Font List" -msgstr "" +msgstr "Liste des polices OpenSCAD" #: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 msgid "&OK" -msgstr "" +msgstr "&OK" #: objects/ui_FontListDialog.h:105 msgid "Paste font selector to Editor Window" -msgstr "" +msgstr "Coller le sélecteur de polices dans l'éditeur de fenêtres" #: objects/ui_FontListDialog.h:107 msgid "Copy to Clipboard" -msgstr "" +msgstr "Coller dans le presse-papier" #: objects/ui_FontListDialog.h:108 msgid "Filter:" -msgstr "" +msgstr "Filtre:" #: objects/ui_FontListDialog.h:109 msgid "" @@ -54,10 +55,19 @@ msgid "" "family:'Courier New,courier';\"> text(t = "OpenSCAD", font = " ""Liberation Sans:style=Italic");" msgstr "" +"

Cette liste affiche les polices présentement chargées " +"avec OpenSCAD

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" #: objects/ui_launchingscreen.h:276 msgid "Welcome to OpenSCAD" -msgstr "" +msgstr "Bienvenue dans OpenSCAD" #: objects/ui_launchingscreen.h:277 #, fuzzy @@ -75,13 +85,12 @@ msgid "Help" msgstr "&Aide" #: objects/ui_launchingscreen.h:280 -#, fuzzy msgid "Recents" -msgstr "Ouvrir un fichier" +msgstr "Récents" #: objects/ui_launchingscreen.h:281 msgid "Open Recent" -msgstr "" +msgstr "Ouvrir un fichier récent" #: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 #: objects/ui_MainWindow.h:858 @@ -89,9 +98,8 @@ msgid "Examples" msgstr "&Exemples" #: objects/ui_launchingscreen.h:285 -#, fuzzy msgid "Open Example" -msgstr "&Exemples" +msgstr "&Ouvrir un example" #: objects/ui_launchingscreen.h:287 msgid "" @@ -106,18 +114,28 @@ msgid "" "\n" "\n" msgstr "" +"\n" +"

OpenSCAD

\n" +"

Le logiciel CAD 3D de conception paramétriques des programmeurs

\n" +"\n" +"\n" +"\n" #: objects/ui_launchingscreen.h:294 msgid "Don't show again" -msgstr "" +msgstr "Ne plus afficher" #: objects/ui_LibraryInfoDialog.h:75 msgid "Lib & Build Info" -msgstr "" +msgstr "Bibliothèque et Infos de la version" #: objects/ui_LibraryInfoDialog.h:76 msgid "OpenSCAD Detailed Library and Build Information" -msgstr "" +msgstr "Informations détaillées des bibliothèques et de la version d'OpenSCAD" #: objects/ui_MainWindow.h:733 msgid "&New" @@ -125,7 +143,7 @@ msgstr "&Nouveau" #: objects/ui_MainWindow.h:734 msgid "Ctrl+N" -msgstr "" +msgstr "Ctrl+N" #: objects/ui_MainWindow.h:735 msgid "&Open..." @@ -133,7 +151,7 @@ msgstr "&Ouvrir..." #: objects/ui_MainWindow.h:736 msgid "Ctrl+O" -msgstr "" +msgstr "Ctrl+O" #: objects/ui_MainWindow.h:737 msgid "&Save" @@ -141,7 +159,7 @@ msgstr "Enregi&strer" #: objects/ui_MainWindow.h:738 msgid "Ctrl+S" -msgstr "" +msgstr "Ctrl+S" #: objects/ui_MainWindow.h:739 msgid "Save &As..." @@ -149,7 +167,7 @@ msgstr "Enregistrer &sous..." #: objects/ui_MainWindow.h:740 msgid "Ctrl+Shift+S" -msgstr "" +msgstr "Ctrl+Shift+S" #: objects/ui_MainWindow.h:741 msgid "&Reload" @@ -157,7 +175,7 @@ msgstr "&Recharger" #: objects/ui_MainWindow.h:742 msgid "Ctrl+R" -msgstr "" +msgstr "Ctrl+R" #: objects/ui_MainWindow.h:743 msgid "&Quit" @@ -165,7 +183,7 @@ msgstr "&Quitter" #: objects/ui_MainWindow.h:744 msgid "Ctrl+Q" -msgstr "" +msgstr "Ctrl+Q" #: objects/ui_MainWindow.h:745 msgid "&Undo" @@ -173,15 +191,15 @@ msgstr "Ann&uler" #: objects/ui_MainWindow.h:746 msgid "Ctrl+Z" -msgstr "" +msgstr "Ctrl+Z" #: objects/ui_MainWindow.h:747 msgid "&Redo" -msgstr "&Refaire" +msgstr "&Répéter" #: objects/ui_MainWindow.h:748 msgid "Ctrl+Shift+Z" -msgstr "" +msgstr "Ctrl+Shift+Z" #: objects/ui_MainWindow.h:749 msgid "Cu&t" @@ -189,7 +207,7 @@ msgstr "Co&uper" #: objects/ui_MainWindow.h:750 msgid "Ctrl+X" -msgstr "" +msgstr "Ctrl+X" #: objects/ui_MainWindow.h:751 msgid "&Copy" @@ -197,7 +215,7 @@ msgstr "&Copier" #: objects/ui_MainWindow.h:752 msgid "Ctrl+C" -msgstr "" +msgstr "Ctrl+C" #: objects/ui_MainWindow.h:753 msgid "&Paste" @@ -205,7 +223,7 @@ msgstr "&Coller" #: objects/ui_MainWindow.h:754 msgid "Ctrl+V" -msgstr "" +msgstr "Ctrl+V" #: objects/ui_MainWindow.h:755 msgid "&Indent" @@ -213,7 +231,7 @@ msgstr "&Indenter" #: objects/ui_MainWindow.h:756 msgid "Ctrl+I" -msgstr "" +msgstr "Ctrl+I" #: objects/ui_MainWindow.h:757 msgid "U&nindent" @@ -221,35 +239,35 @@ msgstr "Dési&ndenter" #: objects/ui_MainWindow.h:758 msgid "Ctrl+Shift+I" -msgstr "" +msgstr "Ctrl+Shift+I" #: objects/ui_MainWindow.h:759 msgid "C&omment" -msgstr "" +msgstr "C&ommenter" #: objects/ui_MainWindow.h:760 msgid "Ctrl+D" -msgstr "" +msgstr "Ctrl+D" #: objects/ui_MainWindow.h:761 msgid "Unco&mment" -msgstr "" +msgstr "Déco&mmenter" #: objects/ui_MainWindow.h:762 msgid "Ctrl+Shift+D" -msgstr "" +msgstr "Ctrl+Shift+D" #: objects/ui_MainWindow.h:763 msgid "Paste viewport translation" -msgstr "" +msgstr "Coller la translation de la fenêtre de rendu" #: objects/ui_MainWindow.h:764 msgid "Ctrl+T" -msgstr "" +msgstr "Ctrl+T" #: objects/ui_MainWindow.h:765 msgid "Paste viewport rotation" -msgstr "" +msgstr "Coller la rotation de la fenêtre rendu" #: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 msgid "Zoom In" @@ -257,7 +275,7 @@ msgstr "Zoom Avant" #: objects/ui_MainWindow.h:767 msgid "Ctrl++" -msgstr "" +msgstr "Ctrl++" #: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 msgid "Zoom Out" @@ -265,83 +283,83 @@ msgstr "Zoom Arrière" #: objects/ui_MainWindow.h:769 msgid "Ctrl+-" -msgstr "" +msgstr "Ctrl+-" #: objects/ui_MainWindow.h:770 msgid "Hide editor" -msgstr "" +msgstr "Cacher l'éditeur" #: objects/ui_MainWindow.h:771 msgid "&Reload and Preview" -msgstr "" +msgstr "&Recharger et Aperçu" #: objects/ui_MainWindow.h:772 msgid "F4" -msgstr "" +msgstr "F4" #: objects/ui_MainWindow.h:773 msgid "&Preview" -msgstr "" +msgstr "&Aperçu" #: objects/ui_MainWindow.h:774 msgid "F5" -msgstr "" +msgstr "F5" #: objects/ui_MainWindow.h:775 msgid "&Render" -msgstr "" +msgstr "&Rendu" #: objects/ui_MainWindow.h:776 msgid "F6" -msgstr "" +msgstr "F6" #: objects/ui_MainWindow.h:777 msgid "Check Validity" -msgstr "" +msgstr "Vérifier la Validité" #: objects/ui_MainWindow.h:778 msgid "Display &AST..." -msgstr "" +msgstr "Afficher &AST..." #: objects/ui_MainWindow.h:779 msgid "Display CSG &Tree..." -msgstr "" +msgstr "Afficher CSG &Arbre" #: objects/ui_MainWindow.h:780 msgid "Display CSG &Products..." -msgstr "" +msgstr "Afficher CSG &Produits" #: objects/ui_MainWindow.h:781 msgid "Export as &STL..." -msgstr "" +msgstr "Exporter comme &STL..." #: objects/ui_MainWindow.h:782 msgid "Export as &OFF..." -msgstr "" +msgstr "Exporter comme &OFF..." #: objects/ui_MainWindow.h:783 msgid "Preview" -msgstr "" +msgstr "Aperçu" #: objects/ui_MainWindow.h:784 msgid "F9" -msgstr "" +msgstr "F9" #: objects/ui_MainWindow.h:785 msgid "Surfaces" -msgstr "" +msgstr "Surfaces" #: objects/ui_MainWindow.h:786 msgid "F10" -msgstr "" +msgstr "F10" #: objects/ui_MainWindow.h:787 msgid "Wireframe" -msgstr "" +msgstr "Wireframe" #: objects/ui_MainWindow.h:788 msgid "F11" -msgstr "" +msgstr "F11" #: objects/ui_MainWindow.h:789 msgid "Thrown Together" @@ -349,23 +367,23 @@ msgstr "" #: objects/ui_MainWindow.h:790 msgid "F12" -msgstr "" +msgstr "F12" #: objects/ui_MainWindow.h:791 msgid "Show Edges" -msgstr "" +msgstr "Afficher les Arêtes" #: objects/ui_MainWindow.h:792 msgid "Ctrl+1" -msgstr "" +msgstr "Ctrl+1" #: objects/ui_MainWindow.h:793 msgid "Show Axes" -msgstr "Afficher les axes" +msgstr "Afficher les Axes" #: objects/ui_MainWindow.h:794 msgid "Ctrl+2" -msgstr "" +msgstr "Ctrl+2" #: objects/ui_MainWindow.h:795 msgid "Show Crosshairs" @@ -373,11 +391,11 @@ msgstr "" #: objects/ui_MainWindow.h:796 msgid "Ctrl+3" -msgstr "" +msgstr "Ctrl+3" #: objects/ui_MainWindow.h:797 msgid "Animate" -msgstr "" +msgstr "Animer" #: objects/ui_MainWindow.h:798 msgid "Top" @@ -385,7 +403,7 @@ msgstr "Dessus" #: objects/ui_MainWindow.h:799 msgid "Ctrl+4" -msgstr "" +msgstr "Ctrl+4" #: objects/ui_MainWindow.h:800 msgid "Bottom" @@ -393,7 +411,7 @@ msgstr "Dessous" #: objects/ui_MainWindow.h:801 msgid "Ctrl+5" -msgstr "" +msgstr "Ctrl+5" #: objects/ui_MainWindow.h:802 msgid "Left" @@ -401,7 +419,7 @@ msgstr "Gauche" #: objects/ui_MainWindow.h:803 msgid "Ctrl+6" -msgstr "" +msgstr "Ctrl+6" #: objects/ui_MainWindow.h:804 msgid "Right" @@ -409,7 +427,7 @@ msgstr "Droite" #: objects/ui_MainWindow.h:805 msgid "Ctrl+7" -msgstr "" +msgstr "Ctrl+7" #: objects/ui_MainWindow.h:806 msgid "Front" @@ -417,7 +435,7 @@ msgstr "Face" #: objects/ui_MainWindow.h:807 msgid "Ctrl+8" -msgstr "" +msgstr "Ctrl+8" #: objects/ui_MainWindow.h:808 msgid "Back" @@ -425,31 +443,31 @@ msgstr "Arrière" #: objects/ui_MainWindow.h:809 msgid "Ctrl+9" -msgstr "" +msgstr "Ctrl+9" #: objects/ui_MainWindow.h:810 msgid "Diagonal" -msgstr "" +msgstr "Diagonale" #: objects/ui_MainWindow.h:811 msgid "Ctrl+0" -msgstr "" +msgstr "Ctrl+0" #: objects/ui_MainWindow.h:812 msgid "Center" -msgstr "" +msgstr "Centre" #: objects/ui_MainWindow.h:813 msgid "Perspective" -msgstr "" +msgstr "Perspective" #: objects/ui_MainWindow.h:814 msgid "Orthogonal" -msgstr "" +msgstr "Orthogonal" #: objects/ui_MainWindow.h:815 msgid "Hide console" -msgstr "" +msgstr "Cache la console" #: objects/ui_MainWindow.h:816 msgid "About" @@ -457,15 +475,15 @@ msgstr "À propos" #: objects/ui_MainWindow.h:817 msgid "Documentation" -msgstr "" +msgstr "Documentation" #: objects/ui_MainWindow.h:818 msgid "Clear Recent" -msgstr "" +msgstr "Effacer Récents" #: objects/ui_MainWindow.h:819 msgid "Export as DXF..." -msgstr "" +msgstr "Exporter comme DXF..." #: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 msgid "Close" @@ -473,7 +491,7 @@ msgstr "Fermer" #: objects/ui_MainWindow.h:821 msgid "Ctrl+W" -msgstr "" +msgstr "Ctrl+W" #: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 msgid "Preferences" @@ -481,141 +499,139 @@ msgstr "Préférences" #: objects/ui_MainWindow.h:823 msgid "Find..." -msgstr "" +msgstr "Rechercher..." #: objects/ui_MainWindow.h:824 msgid "Ctrl+F" -msgstr "" +msgstr "Ctrl+F" #: objects/ui_MainWindow.h:825 msgid "Find and Replace..." -msgstr "" +msgstr "Rechercher et remplacer..." #: objects/ui_MainWindow.h:826 msgid "Ctrl+Alt+F" -msgstr "" +msgstr "Ctrl+Alt+F" #: objects/ui_MainWindow.h:827 msgid "Find Next" -msgstr "" +msgstr "Rechercher Suivant" #: objects/ui_MainWindow.h:828 msgid "Ctrl+G" -msgstr "" +msgstr "Ctrl+G" #: objects/ui_MainWindow.h:829 msgid "Find Previous" -msgstr "" +msgstr "Rechercher Précédent" #: objects/ui_MainWindow.h:830 msgid "Ctrl+Shift+G" -msgstr "" +msgstr "Ctrl+Shift+G" #: objects/ui_MainWindow.h:831 msgid "Use Selection for Find" -msgstr "" +msgstr "Utiliser la sélection pour Rechercher" #: objects/ui_MainWindow.h:832 msgid "Ctrl+E" -msgstr "" +msgstr "Ctrl+E" #: objects/ui_MainWindow.h:833 msgid "Flush Caches" -msgstr "" +msgstr "Vider les caches" #: objects/ui_MainWindow.h:834 msgid "OpenSCAD Homepage" -msgstr "" +msgstr "Page d'accueil OpenSCAD" #: objects/ui_MainWindow.h:835 msgid "Automatic Reload and Preview" -msgstr "" +msgstr "Recharger et Aperçu Automatique" #: objects/ui_MainWindow.h:836 msgid "Export as Image..." -msgstr "" +msgstr "Exporter comme Image..." #: objects/ui_MainWindow.h:837 msgid "Export as CSG..." -msgstr "" +msgstr "Exporter comme CSG..." #: objects/ui_MainWindow.h:838 msgid "Library info" -msgstr "" +msgstr "Informations Bibliothèque" #: objects/ui_MainWindow.h:839 msgid "Check for Update.." -msgstr "" +msgstr "Vérifier les mises à jours" #: objects/ui_MainWindow.h:840 msgid "Show Library Folder..." -msgstr "" +msgstr "Afficher le dossier de la bibliothèque" #: objects/ui_MainWindow.h:841 msgid "Reset View" -msgstr "" +msgstr "Réinitialiser la vue" #: objects/ui_MainWindow.h:842 msgid "Font List" -msgstr "" +msgstr "Liste des polices" #: objects/ui_MainWindow.h:843 msgid "Export as SVG..." -msgstr "" +msgstr "Exporter comme SVG..." #: objects/ui_MainWindow.h:844 msgid "Export as AMF..." -msgstr "" +msgstr "Exporter comme AMF..." #: objects/ui_MainWindow.h:846 msgid "Ctrl+]" -msgstr "" +msgstr "Ctrl+]" #: objects/ui_MainWindow.h:848 msgid "Ctrl+[" -msgstr "" +msgstr "Ctrl+[" #: objects/ui_MainWindow.h:849 -#, fuzzy msgid "View All" -msgstr "&Vue" +msgstr "&Voir Tout" #: objects/ui_MainWindow.h:850 msgid "Convert Tabs to Spaces" -msgstr "" +msgstr "Convertir les tabulations pour des espaces" #: objects/ui_MainWindow.h:851 msgid "Hide toolbars" -msgstr "" +msgstr "Cacher les boîtes à outils" #: objects/ui_MainWindow.h:852 msgid "Time:" -msgstr "" +msgstr "Temps:" #: objects/ui_MainWindow.h:853 msgid "FPS:" -msgstr "" +msgstr "FPS:" #: objects/ui_MainWindow.h:854 msgid "Steps:" -msgstr "" +msgstr "Étapes:" #: objects/ui_MainWindow.h:855 msgid "Dump Pictures" -msgstr "" +msgstr "Vider les photos" #: objects/ui_MainWindow.h:856 msgid "&File" msgstr "&Fichier" #: objects/ui_MainWindow.h:857 -#, fuzzy msgid "Recent Files" -msgstr "Ouvrir un fichier" +msgstr "Fichiers Récents" #: objects/ui_MainWindow.h:859 msgid "Export" -msgstr "" +msgstr "Exporter" #: objects/ui_MainWindow.h:860 msgid "&Edit" @@ -623,7 +639,7 @@ msgstr "&Édition" #: objects/ui_MainWindow.h:861 msgid "&Design" -msgstr "" +msgstr "Conception" #: objects/ui_MainWindow.h:862 msgid "&View" @@ -635,40 +651,39 @@ msgstr "&Aide" #: objects/ui_MainWindow.h:866 msgid "Find" -msgstr "" +msgstr "Rechercher" #: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 msgid "Replace" -msgstr "" +msgstr "Remplacer" #: objects/ui_MainWindow.h:869 msgid "Search string" -msgstr "" +msgstr "Rechercher une chaîne de caractères" #: objects/ui_MainWindow.h:870 msgid "<" -msgstr "" +msgstr "<" #: objects/ui_MainWindow.h:871 msgid ">" -msgstr "" +msgstr ">" #: objects/ui_MainWindow.h:872 msgid "Done" -msgstr "" +msgstr "Terminer" #: objects/ui_MainWindow.h:873 msgid "Replacement string" -msgstr "" +msgstr "Remplacer une chaîne de caractères" #: objects/ui_MainWindow.h:875 msgid "All" -msgstr "" +msgstr "Tout" #: objects/ui_OpenCSGWarningDialog.h:86 -#, fuzzy msgid "OpenGL Warning" -msgstr "Information OpenGL" +msgstr "Avertissements OpenGL" #: objects/ui_OpenCSGWarningDialog.h:87 msgid "" @@ -683,107 +698,116 @@ msgid "" "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">" msgstr "" +"\n" +"\n" +"

" #: objects/ui_OpenCSGWarningDialog.h:92 msgid "Enable OpenCSG" -msgstr "" +msgstr "Activer OpenCSG" #: objects/ui_OpenCSGWarningDialog.h:93 msgid "Show this message again" -msgstr "" +msgstr "Affiche ce message à nouveau" #: objects/ui_Preferences.h:609 -#, fuzzy msgid "3D View" -msgstr "&Vue" +msgstr "&Vue 3D" #: objects/ui_Preferences.h:610 src/UIUtils.cc:85 msgid "Advanced" -msgstr "" +msgstr "Avancé" #: objects/ui_Preferences.h:611 src/mainwin.cc:2339 msgid "Editor" -msgstr "" +msgstr "Éditeur" #: objects/ui_Preferences.h:612 msgid "Update" -msgstr "" +msgstr "Mettre à jour" #: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 msgid "Features" -msgstr "" +msgstr "Fonctionnalités" #: objects/ui_Preferences.h:615 msgid "Enable/Disable experimental features" -msgstr "" +msgstr "Activer/Désactiver les fonctionnalités expérimentales" #: objects/ui_Preferences.h:617 msgid "Color scheme:" -msgstr "" +msgstr "Palette de couleurs:" #: objects/ui_Preferences.h:618 msgid "Editor Type" -msgstr "" +msgstr "Type d'éditeur" #: objects/ui_Preferences.h:621 msgid "Simple Editor" -msgstr "" +msgstr "Éditeur Simple" #: objects/ui_Preferences.h:622 msgid "QScintilla Editor" -msgstr "" +msgstr "Éditeur QScintilla" #: objects/ui_Preferences.h:624 msgid "(requires restart)" -msgstr "" +msgstr "(nécessite un redémarrage)" #: objects/ui_Preferences.h:625 msgid "Font" -msgstr "" +msgstr "Police" #: objects/ui_Preferences.h:626 msgid "Color syntax highlighting" -msgstr "" +msgstr "Colorer la coloration syntaxique" #: objects/ui_Preferences.h:627 msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" -msgstr "" +msgstr "Utiliser Ctrl/Cmd-Roulette-Souris pour agrandir le texte" #: objects/ui_Preferences.h:629 msgid "Automatically check for updates" -msgstr "" +msgstr "Vérifier les mises à jour automatiquement" #: objects/ui_Preferences.h:630 msgid "Include development snapshots" -msgstr "" +msgstr "Inclure les versions de développement" #: objects/ui_Preferences.h:631 msgid "Check Now" -msgstr "" +msgstr "Vérifier Maintenant" #: objects/ui_Preferences.h:632 msgid "Last checked: " -msgstr "" +msgstr "Dernière vérification:" #: objects/ui_Preferences.h:634 msgid "OpenCSG" -msgstr "" +msgstr "OpenCSG" #: objects/ui_Preferences.h:635 msgid "Show capability warning" -msgstr "" +msgstr "Afficher les avertissements de capacité" #: objects/ui_Preferences.h:636 msgid "Enable for OpenGL 1.x" -msgstr "" +msgstr "Activer pour OpenGL 1.x" #: objects/ui_Preferences.h:637 msgid "Turn off rendering at " -msgstr "" +msgstr "Désactiver le rendu à" #: objects/ui_Preferences.h:638 msgid "elements" -msgstr "" +msgstr "éléments" #: objects/ui_Preferences.h:639 msgid "Force Goldfeather" @@ -791,127 +815,134 @@ msgstr "" #: objects/ui_Preferences.h:640 msgid "CGAL Cache size" -msgstr "" +msgstr "Taille du Cache de CGAL" #: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 msgid "bytes" -msgstr "" +msgstr "octets" #: objects/ui_Preferences.h:642 msgid "PolySet Cache size" -msgstr "" +msgstr "Taille du Cache PolySet" #: objects/ui_Preferences.h:644 msgid "Allow to open multiple documents" -msgstr "" +msgstr "Autoriser l'ouverture de plusieurs documents" #: objects/ui_Preferences.h:645 msgid "Enable docking of Editor and Console in different places" -msgstr "" +msgstr "Activer l'ancrage de l'Éditeur et de la Console à différents endroits" #: objects/ui_Preferences.h:646 msgid "Enable undocking of Editor and Console to separate windows" msgstr "" +"Activer désancrage de l'Éditeur et de la Console dans des fenêtres séparés" #: objects/ui_Preferences.h:647 msgid "Show Welcome Screen" -msgstr "" +msgstr "Affiche l'écran d'accueil" #: objects/ui_Preferences.h:648 msgid "Enable user interface localization (requires restart of OpenSCAD)" msgstr "" +"Activer la localisation de l'interface utilisateur (Nécessite un redémarrage " +"d'OpenSCAD)" #: objects/ui_Preferences.h:649 msgid "toolBar" -msgstr "" +msgstr "boîte à outils" #: objects/ui_ProgressWidget.h:72 msgid "Form" -msgstr "" +msgstr "Formulaire" #: objects/ui_ProgressWidget.h:73 msgid "%v / %m" -msgstr "" +msgstr "%v / %m" #: src/AboutDialog.h:15 msgid "About OpenSCAD " -msgstr "" +msgstr "À propos de OpenSCAD" #: src/mainwin.cc:773 src/mainwin.cc:1315 msgid "Untitled.scad" -msgstr "" +msgstr "Untitled.scad" #: src/mainwin.cc:1314 msgid "Save File" -msgstr "" +msgstr "Enregistrer le Fichier" #: src/mainwin.cc:1316 msgid "OpenSCAD Designs (*.scad)" -msgstr "" +msgstr "OpenSCAD Designs (*.scad)" #: src/mainwin.cc:1326 msgid "" "%1 already exists.\n" "Do you want to replace it?" msgstr "" +"%1 existe déjà.\n" +"Voulez-vous le remplacer?" #: src/mainwin.cc:1654 msgid "Application" -msgstr "" +msgstr "Application" #: src/mainwin.cc:1655 msgid "" "The document has been modified.\n" "Do you really want to reload the file?" msgstr "" +"Ce document a été modifié.\n" +"Voulez-vous vraiment recharger le fichier?" #: src/mainwin.cc:1966 src/mainwin.cc:2023 msgid "Export %1 File" -msgstr "" +msgstr "Exporter %1 Fichier" #: src/mainwin.cc:1967 src/mainwin.cc:2027 msgid "%1 Files (*%2)" -msgstr "" +msgstr "%1 Fichiers (*%2)" #: src/mainwin.cc:1968 msgid "Untitled" -msgstr "" +msgstr "Sans Titre" #: src/mainwin.cc:2025 msgid "Untitled%1" -msgstr "" +msgstr "Sans Titre%1" #: src/mainwin.cc:2076 msgid "Export CSG File" -msgstr "" +msgstr "Exporter un fichier CSG" #: src/mainwin.cc:2077 msgid "Untitled.csg" -msgstr "" +msgstr "SansTitre.csg" #: src/mainwin.cc:2078 msgid "CSG Files (*.csg)" -msgstr "" +msgstr "Fichiers CSG (*.csg)" #: src/mainwin.cc:2104 msgid "Export Image" -msgstr "" +msgstr "Exporter une Image" #: src/mainwin.cc:2104 msgid "PNG Files (*.png)" -msgstr "" +msgstr "Fichiers PNG (*.png)" #: src/mainwin.cc:2344 msgid "Console" -msgstr "" +msgstr "Console" #: src/mainwin.cc:2471 msgid "The document has been modified." -msgstr "" +msgstr "Ce document a été modifié" #: src/mainwin.cc:2472 msgid "Do you want to save your changes?" -msgstr "" +msgstr "Voulez-vous enregistrer vos changements?" #: src/QGLView.cc:114 msgid "" @@ -919,12 +950,17 @@ msgid "" "Using QGLWidget\n" "\n" msgstr "" +"\n" +"Utilise QGLWidget\n" +"\n" #: src/QGLView.cc:131 msgid "" "Warning: You may experience OpenCSG rendering errors.\n" "\n" msgstr "" +"Avertissement: Vous pourriez avoir des erreurs de rendu OpenCSG\n" +"\n" #: src/QGLView.cc:134 msgid "" @@ -932,6 +968,9 @@ msgid "" "disabled.\n" "\n" msgstr "" +"Avertissement: Capacités OpenGL manquantes pour OpenCSG - OpenCSG a été " +"désactivé.\n" +"\n" #: src/QGLView.cc:137 msgid "" @@ -939,6 +978,9 @@ msgid "" "later.\n" "Your renderer information is as follows:\n" msgstr "" +"Il est hautement recommandé d'utiliser OpenSCAD sur un système compatible " +"OpenGL 2.0 ou ultérieur.\n" +"Voici les informations de votre moteur de rendu:\n" #: src/QGLView.cc:141 #, c-format @@ -947,6 +989,9 @@ msgid "" "%s (%s)\n" "OpenGL version %s\n" msgstr "" +"Version GLEW %s\n" +"%s (%s)\n" +"Version OpenGL %s\n" #: src/QGLView.cc:171 #, c-format @@ -954,18 +999,20 @@ msgid "" "Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " "distance = %.2f" msgstr "" +"Fenêtre de rendu: translation = [ %.2f %.2f %.2f ], rotation = [ %.2f %.2f " +"%.2f ], distance = %.2f" #: src/UIUtils.cc:85 msgid "Basics" -msgstr "" +msgstr "Bases" #: src/UIUtils.cc:85 msgid "Shapes" -msgstr "" +msgstr "Formes" #: src/UIUtils.cc:85 msgid "Extrusion" -msgstr "" +msgstr "Extrusion" #~ msgid "OpenGL Info" #~ msgstr "Information OpenGL" From 2c4c19d2d541dbc1b9a8251d555dac707d2bf14b Mon Sep 17 00:00:00 2001 From: Keven Villeneuve Date: Sun, 14 Dec 2014 00:45:15 -0500 Subject: [PATCH 137/263] Correct some mistakes in the french translation --- locale/fr.po | 2000 +++++++++++++++++++++++++------------------------- 1 file changed, 982 insertions(+), 1018 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index 35018057..fb9e5224 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -1,1018 +1,982 @@ -# French translations for OpenSCAD package. -# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER -# This file is distributed under the same license as the OpenSCAD package. -# don , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: OpenSCAD 2013.02.07\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-11-13 00:22+0100\n" -"PO-Revision-Date: 2014-12-13 22:25-0500\n" -"Last-Translator: Keven Villeneuve \n" -"Language-Team: French\n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Poedit-SourceCharset: utf-8\n" -"X-Generator: Poedit 1.7.1\n" - -#: objects/ui_AboutDialog.h:51 -msgid "About OpenSCAD" -msgstr "À propos de OpenSCAD" - -#: objects/ui_FontListDialog.h:102 -msgid "OpenSCAD Font List" -msgstr "Liste des polices OpenSCAD" - -#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 -msgid "&OK" -msgstr "&OK" - -#: objects/ui_FontListDialog.h:105 -msgid "Paste font selector to Editor Window" -msgstr "Coller le sélecteur de polices dans l'éditeur de fenêtres" - -#: objects/ui_FontListDialog.h:107 -msgid "Copy to Clipboard" -msgstr "Coller dans le presse-papier" - -#: objects/ui_FontListDialog.h:108 -msgid "Filter:" -msgstr "Filtre:" - -#: objects/ui_FontListDialog.h:109 -msgid "" -"

This list shows the fonts currently registered with " -"OpenSCAD.

Example:

  text(t = "
-""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
-""Liberation Sans:style=Italic");
" -msgstr "" -"

Cette liste affiche les polices présentement chargées " -"avec OpenSCAD

Example:

  text(t = "
-""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
-""Liberation Sans:style=Italic");
" - -#: objects/ui_launchingscreen.h:276 -msgid "Welcome to OpenSCAD" -msgstr "Bienvenue dans OpenSCAD" - -#: objects/ui_launchingscreen.h:277 -#, fuzzy -msgid "New" -msgstr "&Nouveau" - -#: objects/ui_launchingscreen.h:278 -#, fuzzy -msgid "Open" -msgstr "&Ouvrir..." - -#: objects/ui_launchingscreen.h:279 -#, fuzzy -msgid "Help" -msgstr "&Aide" - -#: objects/ui_launchingscreen.h:280 -msgid "Recents" -msgstr "Récents" - -#: objects/ui_launchingscreen.h:281 -msgid "Open Recent" -msgstr "Ouvrir un fichier récent" - -#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 -#: objects/ui_MainWindow.h:858 -msgid "Examples" -msgstr "&Exemples" - -#: objects/ui_launchingscreen.h:285 -msgid "Open Example" -msgstr "&Ouvrir un example" - -#: objects/ui_launchingscreen.h:287 -msgid "" -"\n" -"

OpenSCAD

\n" -"

The Programmers Solid 3D CAD Modeller

\n" -"\n" -"\n" -"\n" -msgstr "" -"\n" -"

OpenSCAD

\n" -"

Le logiciel CAD 3D de conception paramétriques des programmeurs

\n" -"\n" -"\n" -"\n" - -#: objects/ui_launchingscreen.h:294 -msgid "Don't show again" -msgstr "Ne plus afficher" - -#: objects/ui_LibraryInfoDialog.h:75 -msgid "Lib & Build Info" -msgstr "Bibliothèque et Infos de la version" - -#: objects/ui_LibraryInfoDialog.h:76 -msgid "OpenSCAD Detailed Library and Build Information" -msgstr "Informations détaillées des bibliothèques et de la version d'OpenSCAD" - -#: objects/ui_MainWindow.h:733 -msgid "&New" -msgstr "&Nouveau" - -#: objects/ui_MainWindow.h:734 -msgid "Ctrl+N" -msgstr "Ctrl+N" - -#: objects/ui_MainWindow.h:735 -msgid "&Open..." -msgstr "&Ouvrir..." - -#: objects/ui_MainWindow.h:736 -msgid "Ctrl+O" -msgstr "Ctrl+O" - -#: objects/ui_MainWindow.h:737 -msgid "&Save" -msgstr "Enregi&strer" - -#: objects/ui_MainWindow.h:738 -msgid "Ctrl+S" -msgstr "Ctrl+S" - -#: objects/ui_MainWindow.h:739 -msgid "Save &As..." -msgstr "Enregistrer &sous..." - -#: objects/ui_MainWindow.h:740 -msgid "Ctrl+Shift+S" -msgstr "Ctrl+Shift+S" - -#: objects/ui_MainWindow.h:741 -msgid "&Reload" -msgstr "&Recharger" - -#: objects/ui_MainWindow.h:742 -msgid "Ctrl+R" -msgstr "Ctrl+R" - -#: objects/ui_MainWindow.h:743 -msgid "&Quit" -msgstr "&Quitter" - -#: objects/ui_MainWindow.h:744 -msgid "Ctrl+Q" -msgstr "Ctrl+Q" - -#: objects/ui_MainWindow.h:745 -msgid "&Undo" -msgstr "Ann&uler" - -#: objects/ui_MainWindow.h:746 -msgid "Ctrl+Z" -msgstr "Ctrl+Z" - -#: objects/ui_MainWindow.h:747 -msgid "&Redo" -msgstr "&Répéter" - -#: objects/ui_MainWindow.h:748 -msgid "Ctrl+Shift+Z" -msgstr "Ctrl+Shift+Z" - -#: objects/ui_MainWindow.h:749 -msgid "Cu&t" -msgstr "Co&uper" - -#: objects/ui_MainWindow.h:750 -msgid "Ctrl+X" -msgstr "Ctrl+X" - -#: objects/ui_MainWindow.h:751 -msgid "&Copy" -msgstr "&Copier" - -#: objects/ui_MainWindow.h:752 -msgid "Ctrl+C" -msgstr "Ctrl+C" - -#: objects/ui_MainWindow.h:753 -msgid "&Paste" -msgstr "&Coller" - -#: objects/ui_MainWindow.h:754 -msgid "Ctrl+V" -msgstr "Ctrl+V" - -#: objects/ui_MainWindow.h:755 -msgid "&Indent" -msgstr "&Indenter" - -#: objects/ui_MainWindow.h:756 -msgid "Ctrl+I" -msgstr "Ctrl+I" - -#: objects/ui_MainWindow.h:757 -msgid "U&nindent" -msgstr "Dési&ndenter" - -#: objects/ui_MainWindow.h:758 -msgid "Ctrl+Shift+I" -msgstr "Ctrl+Shift+I" - -#: objects/ui_MainWindow.h:759 -msgid "C&omment" -msgstr "C&ommenter" - -#: objects/ui_MainWindow.h:760 -msgid "Ctrl+D" -msgstr "Ctrl+D" - -#: objects/ui_MainWindow.h:761 -msgid "Unco&mment" -msgstr "Déco&mmenter" - -#: objects/ui_MainWindow.h:762 -msgid "Ctrl+Shift+D" -msgstr "Ctrl+Shift+D" - -#: objects/ui_MainWindow.h:763 -msgid "Paste viewport translation" -msgstr "Coller la translation de la fenêtre de rendu" - -#: objects/ui_MainWindow.h:764 -msgid "Ctrl+T" -msgstr "Ctrl+T" - -#: objects/ui_MainWindow.h:765 -msgid "Paste viewport rotation" -msgstr "Coller la rotation de la fenêtre rendu" - -#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 -msgid "Zoom In" -msgstr "Zoom Avant" - -#: objects/ui_MainWindow.h:767 -msgid "Ctrl++" -msgstr "Ctrl++" - -#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 -msgid "Zoom Out" -msgstr "Zoom Arrière" - -#: objects/ui_MainWindow.h:769 -msgid "Ctrl+-" -msgstr "Ctrl+-" - -#: objects/ui_MainWindow.h:770 -msgid "Hide editor" -msgstr "Cacher l'éditeur" - -#: objects/ui_MainWindow.h:771 -msgid "&Reload and Preview" -msgstr "&Recharger et Aperçu" - -#: objects/ui_MainWindow.h:772 -msgid "F4" -msgstr "F4" - -#: objects/ui_MainWindow.h:773 -msgid "&Preview" -msgstr "&Aperçu" - -#: objects/ui_MainWindow.h:774 -msgid "F5" -msgstr "F5" - -#: objects/ui_MainWindow.h:775 -msgid "&Render" -msgstr "&Rendu" - -#: objects/ui_MainWindow.h:776 -msgid "F6" -msgstr "F6" - -#: objects/ui_MainWindow.h:777 -msgid "Check Validity" -msgstr "Vérifier la Validité" - -#: objects/ui_MainWindow.h:778 -msgid "Display &AST..." -msgstr "Afficher &AST..." - -#: objects/ui_MainWindow.h:779 -msgid "Display CSG &Tree..." -msgstr "Afficher CSG &Arbre" - -#: objects/ui_MainWindow.h:780 -msgid "Display CSG &Products..." -msgstr "Afficher CSG &Produits" - -#: objects/ui_MainWindow.h:781 -msgid "Export as &STL..." -msgstr "Exporter comme &STL..." - -#: objects/ui_MainWindow.h:782 -msgid "Export as &OFF..." -msgstr "Exporter comme &OFF..." - -#: objects/ui_MainWindow.h:783 -msgid "Preview" -msgstr "Aperçu" - -#: objects/ui_MainWindow.h:784 -msgid "F9" -msgstr "F9" - -#: objects/ui_MainWindow.h:785 -msgid "Surfaces" -msgstr "Surfaces" - -#: objects/ui_MainWindow.h:786 -msgid "F10" -msgstr "F10" - -#: objects/ui_MainWindow.h:787 -msgid "Wireframe" -msgstr "Wireframe" - -#: objects/ui_MainWindow.h:788 -msgid "F11" -msgstr "F11" - -#: objects/ui_MainWindow.h:789 -msgid "Thrown Together" -msgstr "" - -#: objects/ui_MainWindow.h:790 -msgid "F12" -msgstr "F12" - -#: objects/ui_MainWindow.h:791 -msgid "Show Edges" -msgstr "Afficher les Arêtes" - -#: objects/ui_MainWindow.h:792 -msgid "Ctrl+1" -msgstr "Ctrl+1" - -#: objects/ui_MainWindow.h:793 -msgid "Show Axes" -msgstr "Afficher les Axes" - -#: objects/ui_MainWindow.h:794 -msgid "Ctrl+2" -msgstr "Ctrl+2" - -#: objects/ui_MainWindow.h:795 -msgid "Show Crosshairs" -msgstr "" - -#: objects/ui_MainWindow.h:796 -msgid "Ctrl+3" -msgstr "Ctrl+3" - -#: objects/ui_MainWindow.h:797 -msgid "Animate" -msgstr "Animer" - -#: objects/ui_MainWindow.h:798 -msgid "Top" -msgstr "Dessus" - -#: objects/ui_MainWindow.h:799 -msgid "Ctrl+4" -msgstr "Ctrl+4" - -#: objects/ui_MainWindow.h:800 -msgid "Bottom" -msgstr "Dessous" - -#: objects/ui_MainWindow.h:801 -msgid "Ctrl+5" -msgstr "Ctrl+5" - -#: objects/ui_MainWindow.h:802 -msgid "Left" -msgstr "Gauche" - -#: objects/ui_MainWindow.h:803 -msgid "Ctrl+6" -msgstr "Ctrl+6" - -#: objects/ui_MainWindow.h:804 -msgid "Right" -msgstr "Droite" - -#: objects/ui_MainWindow.h:805 -msgid "Ctrl+7" -msgstr "Ctrl+7" - -#: objects/ui_MainWindow.h:806 -msgid "Front" -msgstr "Face" - -#: objects/ui_MainWindow.h:807 -msgid "Ctrl+8" -msgstr "Ctrl+8" - -#: objects/ui_MainWindow.h:808 -msgid "Back" -msgstr "Arrière" - -#: objects/ui_MainWindow.h:809 -msgid "Ctrl+9" -msgstr "Ctrl+9" - -#: objects/ui_MainWindow.h:810 -msgid "Diagonal" -msgstr "Diagonale" - -#: objects/ui_MainWindow.h:811 -msgid "Ctrl+0" -msgstr "Ctrl+0" - -#: objects/ui_MainWindow.h:812 -msgid "Center" -msgstr "Centre" - -#: objects/ui_MainWindow.h:813 -msgid "Perspective" -msgstr "Perspective" - -#: objects/ui_MainWindow.h:814 -msgid "Orthogonal" -msgstr "Orthogonal" - -#: objects/ui_MainWindow.h:815 -msgid "Hide console" -msgstr "Cache la console" - -#: objects/ui_MainWindow.h:816 -msgid "About" -msgstr "À propos" - -#: objects/ui_MainWindow.h:817 -msgid "Documentation" -msgstr "Documentation" - -#: objects/ui_MainWindow.h:818 -msgid "Clear Recent" -msgstr "Effacer Récents" - -#: objects/ui_MainWindow.h:819 -msgid "Export as DXF..." -msgstr "Exporter comme DXF..." - -#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 -msgid "Close" -msgstr "Fermer" - -#: objects/ui_MainWindow.h:821 -msgid "Ctrl+W" -msgstr "Ctrl+W" - -#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 -msgid "Preferences" -msgstr "Préférences" - -#: objects/ui_MainWindow.h:823 -msgid "Find..." -msgstr "Rechercher..." - -#: objects/ui_MainWindow.h:824 -msgid "Ctrl+F" -msgstr "Ctrl+F" - -#: objects/ui_MainWindow.h:825 -msgid "Find and Replace..." -msgstr "Rechercher et remplacer..." - -#: objects/ui_MainWindow.h:826 -msgid "Ctrl+Alt+F" -msgstr "Ctrl+Alt+F" - -#: objects/ui_MainWindow.h:827 -msgid "Find Next" -msgstr "Rechercher Suivant" - -#: objects/ui_MainWindow.h:828 -msgid "Ctrl+G" -msgstr "Ctrl+G" - -#: objects/ui_MainWindow.h:829 -msgid "Find Previous" -msgstr "Rechercher Précédent" - -#: objects/ui_MainWindow.h:830 -msgid "Ctrl+Shift+G" -msgstr "Ctrl+Shift+G" - -#: objects/ui_MainWindow.h:831 -msgid "Use Selection for Find" -msgstr "Utiliser la sélection pour Rechercher" - -#: objects/ui_MainWindow.h:832 -msgid "Ctrl+E" -msgstr "Ctrl+E" - -#: objects/ui_MainWindow.h:833 -msgid "Flush Caches" -msgstr "Vider les caches" - -#: objects/ui_MainWindow.h:834 -msgid "OpenSCAD Homepage" -msgstr "Page d'accueil OpenSCAD" - -#: objects/ui_MainWindow.h:835 -msgid "Automatic Reload and Preview" -msgstr "Recharger et Aperçu Automatique" - -#: objects/ui_MainWindow.h:836 -msgid "Export as Image..." -msgstr "Exporter comme Image..." - -#: objects/ui_MainWindow.h:837 -msgid "Export as CSG..." -msgstr "Exporter comme CSG..." - -#: objects/ui_MainWindow.h:838 -msgid "Library info" -msgstr "Informations Bibliothèque" - -#: objects/ui_MainWindow.h:839 -msgid "Check for Update.." -msgstr "Vérifier les mises à jours" - -#: objects/ui_MainWindow.h:840 -msgid "Show Library Folder..." -msgstr "Afficher le dossier de la bibliothèque" - -#: objects/ui_MainWindow.h:841 -msgid "Reset View" -msgstr "Réinitialiser la vue" - -#: objects/ui_MainWindow.h:842 -msgid "Font List" -msgstr "Liste des polices" - -#: objects/ui_MainWindow.h:843 -msgid "Export as SVG..." -msgstr "Exporter comme SVG..." - -#: objects/ui_MainWindow.h:844 -msgid "Export as AMF..." -msgstr "Exporter comme AMF..." - -#: objects/ui_MainWindow.h:846 -msgid "Ctrl+]" -msgstr "Ctrl+]" - -#: objects/ui_MainWindow.h:848 -msgid "Ctrl+[" -msgstr "Ctrl+[" - -#: objects/ui_MainWindow.h:849 -msgid "View All" -msgstr "&Voir Tout" - -#: objects/ui_MainWindow.h:850 -msgid "Convert Tabs to Spaces" -msgstr "Convertir les tabulations pour des espaces" - -#: objects/ui_MainWindow.h:851 -msgid "Hide toolbars" -msgstr "Cacher les boîtes à outils" - -#: objects/ui_MainWindow.h:852 -msgid "Time:" -msgstr "Temps:" - -#: objects/ui_MainWindow.h:853 -msgid "FPS:" -msgstr "FPS:" - -#: objects/ui_MainWindow.h:854 -msgid "Steps:" -msgstr "Étapes:" - -#: objects/ui_MainWindow.h:855 -msgid "Dump Pictures" -msgstr "Vider les photos" - -#: objects/ui_MainWindow.h:856 -msgid "&File" -msgstr "&Fichier" - -#: objects/ui_MainWindow.h:857 -msgid "Recent Files" -msgstr "Fichiers Récents" - -#: objects/ui_MainWindow.h:859 -msgid "Export" -msgstr "Exporter" - -#: objects/ui_MainWindow.h:860 -msgid "&Edit" -msgstr "&Édition" - -#: objects/ui_MainWindow.h:861 -msgid "&Design" -msgstr "Conception" - -#: objects/ui_MainWindow.h:862 -msgid "&View" -msgstr "&Vue" - -#: objects/ui_MainWindow.h:863 -msgid "&Help" -msgstr "&Aide" - -#: objects/ui_MainWindow.h:866 -msgid "Find" -msgstr "Rechercher" - -#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 -msgid "Replace" -msgstr "Remplacer" - -#: objects/ui_MainWindow.h:869 -msgid "Search string" -msgstr "Rechercher une chaîne de caractères" - -#: objects/ui_MainWindow.h:870 -msgid "<" -msgstr "<" - -#: objects/ui_MainWindow.h:871 -msgid ">" -msgstr ">" - -#: objects/ui_MainWindow.h:872 -msgid "Done" -msgstr "Terminer" - -#: objects/ui_MainWindow.h:873 -msgid "Replacement string" -msgstr "Remplacer une chaîne de caractères" - -#: objects/ui_MainWindow.h:875 -msgid "All" -msgstr "Tout" - -#: objects/ui_OpenCSGWarningDialog.h:86 -msgid "OpenGL Warning" -msgstr "Avertissements OpenGL" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" -"\n" -"\n" -"

" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "Activer OpenCSG" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "Affiche ce message à nouveau" - -#: objects/ui_Preferences.h:609 -msgid "3D View" -msgstr "&Vue 3D" - -#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 -msgid "Advanced" -msgstr "Avancé" - -#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 -msgid "Editor" -msgstr "Éditeur" - -#: objects/ui_Preferences.h:612 -msgid "Update" -msgstr "Mettre à jour" - -#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 -msgid "Features" -msgstr "Fonctionnalités" - -#: objects/ui_Preferences.h:615 -msgid "Enable/Disable experimental features" -msgstr "Activer/Désactiver les fonctionnalités expérimentales" - -#: objects/ui_Preferences.h:617 -msgid "Color scheme:" -msgstr "Palette de couleurs:" - -#: objects/ui_Preferences.h:618 -msgid "Editor Type" -msgstr "Type d'éditeur" - -#: objects/ui_Preferences.h:621 -msgid "Simple Editor" -msgstr "Éditeur Simple" - -#: objects/ui_Preferences.h:622 -msgid "QScintilla Editor" -msgstr "Éditeur QScintilla" - -#: objects/ui_Preferences.h:624 -msgid "(requires restart)" -msgstr "(nécessite un redémarrage)" - -#: objects/ui_Preferences.h:625 -msgid "Font" -msgstr "Police" - -#: objects/ui_Preferences.h:626 -msgid "Color syntax highlighting" -msgstr "Colorer la coloration syntaxique" - -#: objects/ui_Preferences.h:627 -msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" -msgstr "Utiliser Ctrl/Cmd-Roulette-Souris pour agrandir le texte" - -#: objects/ui_Preferences.h:629 -msgid "Automatically check for updates" -msgstr "Vérifier les mises à jour automatiquement" - -#: objects/ui_Preferences.h:630 -msgid "Include development snapshots" -msgstr "Inclure les versions de développement" - -#: objects/ui_Preferences.h:631 -msgid "Check Now" -msgstr "Vérifier Maintenant" - -#: objects/ui_Preferences.h:632 -msgid "Last checked: " -msgstr "Dernière vérification:" - -#: objects/ui_Preferences.h:634 -msgid "OpenCSG" -msgstr "OpenCSG" - -#: objects/ui_Preferences.h:635 -msgid "Show capability warning" -msgstr "Afficher les avertissements de capacité" - -#: objects/ui_Preferences.h:636 -msgid "Enable for OpenGL 1.x" -msgstr "Activer pour OpenGL 1.x" - -#: objects/ui_Preferences.h:637 -msgid "Turn off rendering at " -msgstr "Désactiver le rendu à" - -#: objects/ui_Preferences.h:638 -msgid "elements" -msgstr "éléments" - -#: objects/ui_Preferences.h:639 -msgid "Force Goldfeather" -msgstr "" - -#: objects/ui_Preferences.h:640 -msgid "CGAL Cache size" -msgstr "Taille du Cache de CGAL" - -#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 -msgid "bytes" -msgstr "octets" - -#: objects/ui_Preferences.h:642 -msgid "PolySet Cache size" -msgstr "Taille du Cache PolySet" - -#: objects/ui_Preferences.h:644 -msgid "Allow to open multiple documents" -msgstr "Autoriser l'ouverture de plusieurs documents" - -#: objects/ui_Preferences.h:645 -msgid "Enable docking of Editor and Console in different places" -msgstr "Activer l'ancrage de l'Éditeur et de la Console à différents endroits" - -#: objects/ui_Preferences.h:646 -msgid "Enable undocking of Editor and Console to separate windows" -msgstr "" -"Activer désancrage de l'Éditeur et de la Console dans des fenêtres séparés" - -#: objects/ui_Preferences.h:647 -msgid "Show Welcome Screen" -msgstr "Affiche l'écran d'accueil" - -#: objects/ui_Preferences.h:648 -msgid "Enable user interface localization (requires restart of OpenSCAD)" -msgstr "" -"Activer la localisation de l'interface utilisateur (Nécessite un redémarrage " -"d'OpenSCAD)" - -#: objects/ui_Preferences.h:649 -msgid "toolBar" -msgstr "boîte à outils" - -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "Formulaire" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "%v / %m" - -#: src/AboutDialog.h:15 -msgid "About OpenSCAD " -msgstr "À propos de OpenSCAD" - -#: src/mainwin.cc:773 src/mainwin.cc:1315 -msgid "Untitled.scad" -msgstr "Untitled.scad" - -#: src/mainwin.cc:1314 -msgid "Save File" -msgstr "Enregistrer le Fichier" - -#: src/mainwin.cc:1316 -msgid "OpenSCAD Designs (*.scad)" -msgstr "OpenSCAD Designs (*.scad)" - -#: src/mainwin.cc:1326 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" -"%1 existe déjà.\n" -"Voulez-vous le remplacer?" - -#: src/mainwin.cc:1654 -msgid "Application" -msgstr "Application" - -#: src/mainwin.cc:1655 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" -"Ce document a été modifié.\n" -"Voulez-vous vraiment recharger le fichier?" - -#: src/mainwin.cc:1966 src/mainwin.cc:2023 -msgid "Export %1 File" -msgstr "Exporter %1 Fichier" - -#: src/mainwin.cc:1967 src/mainwin.cc:2027 -msgid "%1 Files (*%2)" -msgstr "%1 Fichiers (*%2)" - -#: src/mainwin.cc:1968 -msgid "Untitled" -msgstr "Sans Titre" - -#: src/mainwin.cc:2025 -msgid "Untitled%1" -msgstr "Sans Titre%1" - -#: src/mainwin.cc:2076 -msgid "Export CSG File" -msgstr "Exporter un fichier CSG" - -#: src/mainwin.cc:2077 -msgid "Untitled.csg" -msgstr "SansTitre.csg" - -#: src/mainwin.cc:2078 -msgid "CSG Files (*.csg)" -msgstr "Fichiers CSG (*.csg)" - -#: src/mainwin.cc:2104 -msgid "Export Image" -msgstr "Exporter une Image" - -#: src/mainwin.cc:2104 -msgid "PNG Files (*.png)" -msgstr "Fichiers PNG (*.png)" - -#: src/mainwin.cc:2344 -msgid "Console" -msgstr "Console" - -#: src/mainwin.cc:2471 -msgid "The document has been modified." -msgstr "Ce document a été modifié" - -#: src/mainwin.cc:2472 -msgid "Do you want to save your changes?" -msgstr "Voulez-vous enregistrer vos changements?" - -#: src/QGLView.cc:114 -msgid "" -"\n" -"Using QGLWidget\n" -"\n" -msgstr "" -"\n" -"Utilise QGLWidget\n" -"\n" - -#: src/QGLView.cc:131 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" -"Avertissement: Vous pourriez avoir des erreurs de rendu OpenCSG\n" -"\n" - -#: src/QGLView.cc:134 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " -"disabled.\n" -"\n" -msgstr "" -"Avertissement: Capacités OpenGL manquantes pour OpenCSG - OpenCSG a été " -"désactivé.\n" -"\n" - -#: src/QGLView.cc:137 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " -"later.\n" -"Your renderer information is as follows:\n" -msgstr "" -"Il est hautement recommandé d'utiliser OpenSCAD sur un système compatible " -"OpenGL 2.0 ou ultérieur.\n" -"Voici les informations de votre moteur de rendu:\n" - -#: src/QGLView.cc:141 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" -"Version GLEW %s\n" -"%s (%s)\n" -"Version OpenGL %s\n" - -#: src/QGLView.cc:171 -#, c-format -msgid "" -"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " -"distance = %.2f" -msgstr "" -"Fenêtre de rendu: translation = [ %.2f %.2f %.2f ], rotation = [ %.2f %.2f " -"%.2f ], distance = %.2f" - -#: src/UIUtils.cc:85 -msgid "Basics" -msgstr "Bases" - -#: src/UIUtils.cc:85 -msgid "Shapes" -msgstr "Formes" - -#: src/UIUtils.cc:85 -msgid "Extrusion" -msgstr "Extrusion" - -#~ msgid "OpenGL Info" -#~ msgstr "Information OpenGL" +# French translations for OpenSCAD package. +# Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER +# This file is distributed under the same license as the OpenSCAD package. +# don , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2013.02.07\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-13 00:22+0100\n" +"PO-Revision-Date: 2014-12-14 00:32-0500\n" +"Last-Translator: Keven Villeneuve \n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 1.7.1\n" + +#: objects/ui_AboutDialog.h:51 +msgid "About OpenSCAD" +msgstr "À propos de OpenSCAD" + +#: objects/ui_FontListDialog.h:102 +msgid "OpenSCAD Font List" +msgstr "Liste des polices OpenSCAD" + +#: objects/ui_FontListDialog.h:103 +#: objects/ui_LibraryInfoDialog.h:77 +msgid "&OK" +msgstr "&OK" + +#: objects/ui_FontListDialog.h:105 +msgid "Paste font selector to Editor Window" +msgstr "Coller le sélecteur de polices dans l'éditeur de fenêtres" + +#: objects/ui_FontListDialog.h:107 +msgid "Copy to Clipboard" +msgstr "Coller dans le presse-papier" + +#: objects/ui_FontListDialog.h:108 +msgid "Filter:" +msgstr "Filtre:" + +#: objects/ui_FontListDialog.h:109 +msgid "

This list shows the fonts currently registered with OpenSCAD.

Example:

  text(t = "OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "Liberation Sans:style=Italic");
" +msgstr "

Cette liste affiche les polices présentement chargées avec OpenSCAD

Example:

  text(t = "OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "Liberation Sans:style=Italic");
" + +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "Bienvenue dans OpenSCAD" + +#: objects/ui_launchingscreen.h:277 +msgid "New" +msgstr "Nouveau" + +#: objects/ui_launchingscreen.h:278 +msgid "Open" +msgstr "Ouvrir..." + +#: objects/ui_launchingscreen.h:279 +msgid "Help" +msgstr "Aide" + +#: objects/ui_launchingscreen.h:280 +msgid "Recents" +msgstr "Récents" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "Ouvrir un fichier récent" + +#: objects/ui_launchingscreen.h:282 +#: objects/ui_launchingscreen.h:284 +#: objects/ui_MainWindow.h:858 +msgid "Examples" +msgstr "Exemples" + +#: objects/ui_launchingscreen.h:285 +msgid "Open Example" +msgstr "&Ouvrir un example" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" +"\n" +"

OpenSCAD

\n" +"

Le modeleur CAD 3D des programmeurs

\n" +"\n" +"\n" +"\n" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "Ne plus afficher" + +#: objects/ui_LibraryInfoDialog.h:75 +msgid "Lib & Build Info" +msgstr "Bibliothèques et Infos de la version" + +#: objects/ui_LibraryInfoDialog.h:76 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "Informations détaillées des bibliothèques et de la version d'OpenSCAD" + +#: objects/ui_MainWindow.h:733 +msgid "&New" +msgstr "&Nouveau" + +#: objects/ui_MainWindow.h:734 +msgid "Ctrl+N" +msgstr "Ctrl+N" + +#: objects/ui_MainWindow.h:735 +msgid "&Open..." +msgstr "&Ouvrir..." + +#: objects/ui_MainWindow.h:736 +msgid "Ctrl+O" +msgstr "Ctrl+O" + +#: objects/ui_MainWindow.h:737 +msgid "&Save" +msgstr "Enregi&strer" + +#: objects/ui_MainWindow.h:738 +msgid "Ctrl+S" +msgstr "Ctrl+S" + +#: objects/ui_MainWindow.h:739 +msgid "Save &As..." +msgstr "Enregistrer &sous..." + +#: objects/ui_MainWindow.h:740 +msgid "Ctrl+Shift+S" +msgstr "Ctrl+Shift+S" + +#: objects/ui_MainWindow.h:741 +msgid "&Reload" +msgstr "&Recharger" + +#: objects/ui_MainWindow.h:742 +msgid "Ctrl+R" +msgstr "Ctrl+R" + +#: objects/ui_MainWindow.h:743 +msgid "&Quit" +msgstr "&Quitter" + +#: objects/ui_MainWindow.h:744 +msgid "Ctrl+Q" +msgstr "Ctrl+Q" + +#: objects/ui_MainWindow.h:745 +msgid "&Undo" +msgstr "Ann&uler" + +#: objects/ui_MainWindow.h:746 +msgid "Ctrl+Z" +msgstr "Ctrl+Z" + +#: objects/ui_MainWindow.h:747 +msgid "&Redo" +msgstr "&Répéter" + +#: objects/ui_MainWindow.h:748 +msgid "Ctrl+Shift+Z" +msgstr "Ctrl+Shift+Z" + +#: objects/ui_MainWindow.h:749 +msgid "Cu&t" +msgstr "Co&uper" + +#: objects/ui_MainWindow.h:750 +msgid "Ctrl+X" +msgstr "Ctrl+X" + +#: objects/ui_MainWindow.h:751 +msgid "&Copy" +msgstr "&Copier" + +#: objects/ui_MainWindow.h:752 +msgid "Ctrl+C" +msgstr "Ctrl+C" + +#: objects/ui_MainWindow.h:753 +msgid "&Paste" +msgstr "&Coller" + +#: objects/ui_MainWindow.h:754 +msgid "Ctrl+V" +msgstr "Ctrl+V" + +#: objects/ui_MainWindow.h:755 +msgid "&Indent" +msgstr "&Indenter" + +#: objects/ui_MainWindow.h:756 +msgid "Ctrl+I" +msgstr "Ctrl+I" + +#: objects/ui_MainWindow.h:757 +msgid "U&nindent" +msgstr "Dési&ndenter" + +#: objects/ui_MainWindow.h:758 +msgid "Ctrl+Shift+I" +msgstr "Ctrl+Shift+I" + +#: objects/ui_MainWindow.h:759 +msgid "C&omment" +msgstr "C&ommenter" + +#: objects/ui_MainWindow.h:760 +msgid "Ctrl+D" +msgstr "Ctrl+D" + +#: objects/ui_MainWindow.h:761 +msgid "Unco&mment" +msgstr "Déco&mmenter" + +#: objects/ui_MainWindow.h:762 +msgid "Ctrl+Shift+D" +msgstr "Ctrl+Shift+D" + +#: objects/ui_MainWindow.h:763 +msgid "Paste viewport translation" +msgstr "Coller la translation de la fenêtre de rendu" + +#: objects/ui_MainWindow.h:764 +msgid "Ctrl+T" +msgstr "Ctrl+T" + +#: objects/ui_MainWindow.h:765 +msgid "Paste viewport rotation" +msgstr "Coller la rotation de la fenêtre de rendu" + +#: objects/ui_MainWindow.h:766 +#: objects/ui_MainWindow.h:845 +msgid "Zoom In" +msgstr "Zoom Avant" + +#: objects/ui_MainWindow.h:767 +msgid "Ctrl++" +msgstr "Ctrl++" + +#: objects/ui_MainWindow.h:768 +#: objects/ui_MainWindow.h:847 +msgid "Zoom Out" +msgstr "Zoom Arrière" + +#: objects/ui_MainWindow.h:769 +msgid "Ctrl+-" +msgstr "Ctrl+-" + +#: objects/ui_MainWindow.h:770 +msgid "Hide editor" +msgstr "Cacher l'éditeur" + +#: objects/ui_MainWindow.h:771 +msgid "&Reload and Preview" +msgstr "&Recharger et Aperçu" + +#: objects/ui_MainWindow.h:772 +msgid "F4" +msgstr "F4" + +#: objects/ui_MainWindow.h:773 +msgid "&Preview" +msgstr "&Aperçu" + +#: objects/ui_MainWindow.h:774 +msgid "F5" +msgstr "F5" + +#: objects/ui_MainWindow.h:775 +msgid "&Render" +msgstr "&Rendu" + +#: objects/ui_MainWindow.h:776 +msgid "F6" +msgstr "F6" + +#: objects/ui_MainWindow.h:777 +msgid "Check Validity" +msgstr "Vérifier la Validité" + +#: objects/ui_MainWindow.h:778 +msgid "Display &AST..." +msgstr "Afficher &AST..." + +#: objects/ui_MainWindow.h:779 +msgid "Display CSG &Tree..." +msgstr "Afficher CSG &Arbre" + +#: objects/ui_MainWindow.h:780 +msgid "Display CSG &Products..." +msgstr "Afficher CSG &Produits" + +#: objects/ui_MainWindow.h:781 +msgid "Export as &STL..." +msgstr "Exporter comme &STL..." + +#: objects/ui_MainWindow.h:782 +msgid "Export as &OFF..." +msgstr "Exporter comme &OFF..." + +#: objects/ui_MainWindow.h:783 +msgid "Preview" +msgstr "Aperçu" + +#: objects/ui_MainWindow.h:784 +msgid "F9" +msgstr "F9" + +#: objects/ui_MainWindow.h:785 +msgid "Surfaces" +msgstr "Surfaces" + +#: objects/ui_MainWindow.h:786 +msgid "F10" +msgstr "F10" + +#: objects/ui_MainWindow.h:787 +msgid "Wireframe" +msgstr "Wireframe" + +#: objects/ui_MainWindow.h:788 +msgid "F11" +msgstr "F11" + +#: objects/ui_MainWindow.h:789 +msgid "Thrown Together" +msgstr "" + +#: objects/ui_MainWindow.h:790 +msgid "F12" +msgstr "F12" + +#: objects/ui_MainWindow.h:791 +msgid "Show Edges" +msgstr "Afficher les Arêtes" + +#: objects/ui_MainWindow.h:792 +msgid "Ctrl+1" +msgstr "Ctrl+1" + +#: objects/ui_MainWindow.h:793 +msgid "Show Axes" +msgstr "Afficher les Axes" + +#: objects/ui_MainWindow.h:794 +msgid "Ctrl+2" +msgstr "Ctrl+2" + +#: objects/ui_MainWindow.h:795 +msgid "Show Crosshairs" +msgstr "" + +#: objects/ui_MainWindow.h:796 +msgid "Ctrl+3" +msgstr "Ctrl+3" + +#: objects/ui_MainWindow.h:797 +msgid "Animate" +msgstr "Animer" + +#: objects/ui_MainWindow.h:798 +msgid "Top" +msgstr "Dessus" + +#: objects/ui_MainWindow.h:799 +msgid "Ctrl+4" +msgstr "Ctrl+4" + +#: objects/ui_MainWindow.h:800 +msgid "Bottom" +msgstr "Dessous" + +#: objects/ui_MainWindow.h:801 +msgid "Ctrl+5" +msgstr "Ctrl+5" + +#: objects/ui_MainWindow.h:802 +msgid "Left" +msgstr "Gauche" + +#: objects/ui_MainWindow.h:803 +msgid "Ctrl+6" +msgstr "Ctrl+6" + +#: objects/ui_MainWindow.h:804 +msgid "Right" +msgstr "Droite" + +#: objects/ui_MainWindow.h:805 +msgid "Ctrl+7" +msgstr "Ctrl+7" + +#: objects/ui_MainWindow.h:806 +msgid "Front" +msgstr "Face" + +#: objects/ui_MainWindow.h:807 +msgid "Ctrl+8" +msgstr "Ctrl+8" + +#: objects/ui_MainWindow.h:808 +msgid "Back" +msgstr "Arrière" + +#: objects/ui_MainWindow.h:809 +msgid "Ctrl+9" +msgstr "Ctrl+9" + +#: objects/ui_MainWindow.h:810 +msgid "Diagonal" +msgstr "Diagonale" + +#: objects/ui_MainWindow.h:811 +msgid "Ctrl+0" +msgstr "Ctrl+0" + +#: objects/ui_MainWindow.h:812 +msgid "Center" +msgstr "Centre" + +#: objects/ui_MainWindow.h:813 +msgid "Perspective" +msgstr "Perspective" + +#: objects/ui_MainWindow.h:814 +msgid "Orthogonal" +msgstr "Orthogonale" + +#: objects/ui_MainWindow.h:815 +msgid "Hide console" +msgstr "Cache la console" + +#: objects/ui_MainWindow.h:816 +msgid "About" +msgstr "À propos" + +#: objects/ui_MainWindow.h:817 +msgid "Documentation" +msgstr "Documentation" + +#: objects/ui_MainWindow.h:818 +msgid "Clear Recent" +msgstr "Effacer Récents" + +#: objects/ui_MainWindow.h:819 +msgid "Export as DXF..." +msgstr "Exporter comme DXF..." + +#: objects/ui_MainWindow.h:820 +#: objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "Fermer" + +#: objects/ui_MainWindow.h:821 +msgid "Ctrl+W" +msgstr "Ctrl+W" + +#: objects/ui_MainWindow.h:822 +#: objects/ui_Preferences.h:608 +msgid "Preferences" +msgstr "Préférences" + +#: objects/ui_MainWindow.h:823 +msgid "Find..." +msgstr "Rechercher..." + +#: objects/ui_MainWindow.h:824 +msgid "Ctrl+F" +msgstr "Ctrl+F" + +#: objects/ui_MainWindow.h:825 +msgid "Find and Replace..." +msgstr "Rechercher et remplacer..." + +#: objects/ui_MainWindow.h:826 +msgid "Ctrl+Alt+F" +msgstr "Ctrl+Alt+F" + +#: objects/ui_MainWindow.h:827 +msgid "Find Next" +msgstr "Rechercher Suivant" + +#: objects/ui_MainWindow.h:828 +msgid "Ctrl+G" +msgstr "Ctrl+G" + +#: objects/ui_MainWindow.h:829 +msgid "Find Previous" +msgstr "Rechercher Précédent" + +#: objects/ui_MainWindow.h:830 +msgid "Ctrl+Shift+G" +msgstr "Ctrl+Shift+G" + +#: objects/ui_MainWindow.h:831 +msgid "Use Selection for Find" +msgstr "Utiliser la sélection pour Rechercher" + +#: objects/ui_MainWindow.h:832 +msgid "Ctrl+E" +msgstr "Ctrl+E" + +#: objects/ui_MainWindow.h:833 +msgid "Flush Caches" +msgstr "Vider les caches" + +#: objects/ui_MainWindow.h:834 +msgid "OpenSCAD Homepage" +msgstr "Page d'accueil OpenSCAD" + +#: objects/ui_MainWindow.h:835 +msgid "Automatic Reload and Preview" +msgstr "Recharger et Aperçu Automatique" + +#: objects/ui_MainWindow.h:836 +msgid "Export as Image..." +msgstr "Exporter comme Image..." + +#: objects/ui_MainWindow.h:837 +msgid "Export as CSG..." +msgstr "Exporter comme CSG..." + +#: objects/ui_MainWindow.h:838 +msgid "Library info" +msgstr "Informations Bibliothèques" + +#: objects/ui_MainWindow.h:839 +msgid "Check for Update.." +msgstr "Vérifier les mises à jours" + +#: objects/ui_MainWindow.h:840 +msgid "Show Library Folder..." +msgstr "Afficher le dossier des bibliothèques" + +#: objects/ui_MainWindow.h:841 +msgid "Reset View" +msgstr "Réinitialiser la vue" + +#: objects/ui_MainWindow.h:842 +msgid "Font List" +msgstr "Liste des polices" + +#: objects/ui_MainWindow.h:843 +msgid "Export as SVG..." +msgstr "Exporter comme SVG..." + +#: objects/ui_MainWindow.h:844 +msgid "Export as AMF..." +msgstr "Exporter comme AMF..." + +#: objects/ui_MainWindow.h:846 +msgid "Ctrl+]" +msgstr "Ctrl+]" + +#: objects/ui_MainWindow.h:848 +msgid "Ctrl+[" +msgstr "Ctrl+[" + +#: objects/ui_MainWindow.h:849 +msgid "View All" +msgstr "&Voir Tout" + +#: objects/ui_MainWindow.h:850 +msgid "Convert Tabs to Spaces" +msgstr "Convertir les tabulations par des espaces" + +#: objects/ui_MainWindow.h:851 +msgid "Hide toolbars" +msgstr "Cacher les boîtes à outils" + +#: objects/ui_MainWindow.h:852 +msgid "Time:" +msgstr "Temps:" + +#: objects/ui_MainWindow.h:853 +msgid "FPS:" +msgstr "FPS:" + +#: objects/ui_MainWindow.h:854 +msgid "Steps:" +msgstr "Étapes:" + +#: objects/ui_MainWindow.h:855 +msgid "Dump Pictures" +msgstr "Vider les photos" + +#: objects/ui_MainWindow.h:856 +msgid "&File" +msgstr "&Fichier" + +#: objects/ui_MainWindow.h:857 +msgid "Recent Files" +msgstr "Fichiers Récents" + +#: objects/ui_MainWindow.h:859 +msgid "Export" +msgstr "Exporter" + +#: objects/ui_MainWindow.h:860 +msgid "&Edit" +msgstr "&Édition" + +#: objects/ui_MainWindow.h:861 +msgid "&Design" +msgstr "Conception" + +#: objects/ui_MainWindow.h:862 +msgid "&View" +msgstr "&Vue" + +#: objects/ui_MainWindow.h:863 +msgid "&Help" +msgstr "&Aide" + +#: objects/ui_MainWindow.h:866 +msgid "Find" +msgstr "Rechercher" + +#: objects/ui_MainWindow.h:867 +#: objects/ui_MainWindow.h:874 +msgid "Replace" +msgstr "Remplacer" + +#: objects/ui_MainWindow.h:869 +msgid "Search string" +msgstr "Rechercher une chaîne de caractères" + +#: objects/ui_MainWindow.h:870 +msgid "<" +msgstr "<" + +#: objects/ui_MainWindow.h:871 +msgid ">" +msgstr ">" + +#: objects/ui_MainWindow.h:872 +msgid "Done" +msgstr "Terminer" + +#: objects/ui_MainWindow.h:873 +msgid "Replacement string" +msgstr "Remplacer une chaîne de caractères" + +#: objects/ui_MainWindow.h:875 +msgid "All" +msgstr "Tout" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "Avertissements OpenGL" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" +"\n" +"\n" +"

" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "Activer OpenCSG" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "Affiche ce message à nouveau" + +#: objects/ui_Preferences.h:609 +msgid "3D View" +msgstr "&Vue 3D" + +#: objects/ui_Preferences.h:610 +#: src/UIUtils.cc:85 +msgid "Advanced" +msgstr "Avancé" + +#: objects/ui_Preferences.h:611 +#: src/mainwin.cc:2339 +msgid "Editor" +msgstr "Éditeur" + +#: objects/ui_Preferences.h:612 +msgid "Update" +msgstr "Mettre à jour" + +#: objects/ui_Preferences.h:613 +#: objects/ui_Preferences.h:633 +msgid "Features" +msgstr "Fonctionnalités" + +#: objects/ui_Preferences.h:615 +msgid "Enable/Disable experimental features" +msgstr "Activer/Désactiver les fonctionnalités expérimentales" + +#: objects/ui_Preferences.h:617 +msgid "Color scheme:" +msgstr "Palette de couleurs:" + +#: objects/ui_Preferences.h:618 +msgid "Editor Type" +msgstr "Type d'éditeur" + +#: objects/ui_Preferences.h:621 +msgid "Simple Editor" +msgstr "Éditeur Simple" + +#: objects/ui_Preferences.h:622 +msgid "QScintilla Editor" +msgstr "Éditeur QScintilla" + +#: objects/ui_Preferences.h:624 +msgid "(requires restart)" +msgstr "(nécessite un redémarrage)" + +#: objects/ui_Preferences.h:625 +msgid "Font" +msgstr "Police" + +#: objects/ui_Preferences.h:626 +msgid "Color syntax highlighting" +msgstr "Colorer la coloration syntaxique" + +#: objects/ui_Preferences.h:627 +msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" +msgstr "Utiliser Ctrl/Cmd-Roulette-Souris pour agrandir le texte" + +#: objects/ui_Preferences.h:629 +msgid "Automatically check for updates" +msgstr "Vérifier les mises à jour automatiquement" + +#: objects/ui_Preferences.h:630 +msgid "Include development snapshots" +msgstr "Inclure les versions de développement" + +#: objects/ui_Preferences.h:631 +msgid "Check Now" +msgstr "Vérifier Maintenant" + +#: objects/ui_Preferences.h:632 +msgid "Last checked: " +msgstr "Dernière vérification:" + +#: objects/ui_Preferences.h:634 +msgid "OpenCSG" +msgstr "OpenCSG" + +#: objects/ui_Preferences.h:635 +msgid "Show capability warning" +msgstr "Afficher les avertissements de capacité" + +#: objects/ui_Preferences.h:636 +msgid "Enable for OpenGL 1.x" +msgstr "Activer pour OpenGL 1.x" + +#: objects/ui_Preferences.h:637 +msgid "Turn off rendering at " +msgstr "Désactiver le rendu à" + +#: objects/ui_Preferences.h:638 +msgid "elements" +msgstr "éléments" + +#: objects/ui_Preferences.h:639 +msgid "Force Goldfeather" +msgstr "" + +#: objects/ui_Preferences.h:640 +msgid "CGAL Cache size" +msgstr "Taille du Cache de CGAL" + +#: objects/ui_Preferences.h:641 +#: objects/ui_Preferences.h:643 +msgid "bytes" +msgstr "octets" + +#: objects/ui_Preferences.h:642 +msgid "PolySet Cache size" +msgstr "Taille du Cache PolySet" + +#: objects/ui_Preferences.h:644 +msgid "Allow to open multiple documents" +msgstr "Autoriser l'ouverture de plusieurs documents" + +#: objects/ui_Preferences.h:645 +msgid "Enable docking of Editor and Console in different places" +msgstr "Activer l'ancrage de l'Éditeur et de la Console à différents endroits" + +#: objects/ui_Preferences.h:646 +msgid "Enable undocking of Editor and Console to separate windows" +msgstr "Activer désancrage de l'Éditeur et de la Console dans des fenêtres séparés" + +#: objects/ui_Preferences.h:647 +msgid "Show Welcome Screen" +msgstr "Affiche l'écran d'accueil" + +#: objects/ui_Preferences.h:648 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "Activer la localisation de l'interface utilisateur (Nécessite un redémarrage d'OpenSCAD)" + +#: objects/ui_Preferences.h:649 +msgid "toolBar" +msgstr "boîte à outils" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "Formulaire" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "%v / %m" + +#: src/AboutDialog.h:15 +msgid "About OpenSCAD " +msgstr "À propos de OpenSCAD" + +#: src/mainwin.cc:773 +#: src/mainwin.cc:1315 +msgid "Untitled.scad" +msgstr "Untitled.scad" + +#: src/mainwin.cc:1314 +msgid "Save File" +msgstr "Enregistrer le Fichier" + +#: src/mainwin.cc:1316 +msgid "OpenSCAD Designs (*.scad)" +msgstr "OpenSCAD Designs (*.scad)" + +#: src/mainwin.cc:1326 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" +"%1 existe déjà.\n" +"Voulez-vous le remplacer?" + +#: src/mainwin.cc:1654 +msgid "Application" +msgstr "Application" + +#: src/mainwin.cc:1655 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" +"Ce document a été modifié.\n" +"Voulez-vous vraiment recharger le fichier?" + +#: src/mainwin.cc:1966 +#: src/mainwin.cc:2023 +msgid "Export %1 File" +msgstr "Exporter %1 Fichier" + +#: src/mainwin.cc:1967 +#: src/mainwin.cc:2027 +msgid "%1 Files (*%2)" +msgstr "%1 Fichiers (*%2)" + +#: src/mainwin.cc:1968 +msgid "Untitled" +msgstr "Sans Titre" + +#: src/mainwin.cc:2025 +msgid "Untitled%1" +msgstr "Sans Titre%1" + +#: src/mainwin.cc:2076 +msgid "Export CSG File" +msgstr "Exporter un fichier CSG" + +#: src/mainwin.cc:2077 +msgid "Untitled.csg" +msgstr "SansTitre.csg" + +#: src/mainwin.cc:2078 +msgid "CSG Files (*.csg)" +msgstr "Fichiers CSG (*.csg)" + +#: src/mainwin.cc:2104 +msgid "Export Image" +msgstr "Exporter une Image" + +#: src/mainwin.cc:2104 +msgid "PNG Files (*.png)" +msgstr "Fichiers PNG (*.png)" + +#: src/mainwin.cc:2344 +msgid "Console" +msgstr "Console" + +#: src/mainwin.cc:2471 +msgid "The document has been modified." +msgstr "Ce document a été modifié" + +#: src/mainwin.cc:2472 +msgid "Do you want to save your changes?" +msgstr "Voulez-vous enregistrer vos changements?" + +#: src/QGLView.cc:114 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" +"\n" +"Utilise QGLWidget\n" +"\n" + +#: src/QGLView.cc:131 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" +"Avertissement: Vous pourriez avoir des erreurs de rendu OpenCSG\n" +"\n" + +#: src/QGLView.cc:134 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n" +"\n" +msgstr "" +"Avertissement: Capacités OpenGL manquantes pour OpenCSG - OpenCSG a été désactivé.\n" +"\n" + +#: src/QGLView.cc:137 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or later.\n" +"Your renderer information is as follows:\n" +msgstr "" +"Il est hautement recommandé d'utiliser OpenSCAD sur un système compatible OpenGL 2.0 ou ultérieur.\n" +"Voici les informations de votre moteur de rendu:\n" + +#: src/QGLView.cc:141 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" +"Version GLEW %s\n" +"%s (%s)\n" +"Version OpenGL %s\n" + +#: src/QGLView.cc:171 +#, c-format +msgid "Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f" +msgstr "Fenêtre de rendu: translation = [ %.2f %.2f %.2f ], rotation = [ %.2f %.2f %.2f ], distance = %.2f" + +#: src/UIUtils.cc:85 +msgid "Basics" +msgstr "Bases" + +#: src/UIUtils.cc:85 +msgid "Shapes" +msgstr "Formes" + +#: src/UIUtils.cc:85 +msgid "Extrusion" +msgstr "Extrusion" + +#~ msgid "OpenGL Info" +#~ msgstr "Information OpenGL" From db4e609dbd60eef9cf3eb514177cf122a8e6f58d Mon Sep 17 00:00:00 2001 From: Keven Villeneuve Date: Sun, 14 Dec 2014 10:21:08 -0500 Subject: [PATCH 138/263] Finish french translation --- locale/fr.po | 50 ++++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index fb9e5224..0a25b954 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: OpenSCAD 2013.02.07\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-13 00:22+0100\n" -"PO-Revision-Date: 2014-12-14 00:32-0500\n" +"PO-Revision-Date: 2014-12-14 10:20-0500\n" "Last-Translator: Keven Villeneuve \n" "Language-Team: French\n" "Language: fr\n" @@ -27,8 +27,7 @@ msgstr "À propos de OpenSCAD" msgid "OpenSCAD Font List" msgstr "Liste des polices OpenSCAD" -#: objects/ui_FontListDialog.h:103 -#: objects/ui_LibraryInfoDialog.h:77 +#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 msgid "&OK" msgstr "&OK" @@ -72,8 +71,7 @@ msgstr "Récents" msgid "Open Recent" msgstr "Ouvrir un fichier récent" -#: objects/ui_launchingscreen.h:282 -#: objects/ui_launchingscreen.h:284 +#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 #: objects/ui_MainWindow.h:858 msgid "Examples" msgstr "Exemples" @@ -242,8 +240,7 @@ msgstr "Ctrl+T" msgid "Paste viewport rotation" msgstr "Coller la rotation de la fenêtre de rendu" -#: objects/ui_MainWindow.h:766 -#: objects/ui_MainWindow.h:845 +#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 msgid "Zoom In" msgstr "Zoom Avant" @@ -251,8 +248,7 @@ msgstr "Zoom Avant" msgid "Ctrl++" msgstr "Ctrl++" -#: objects/ui_MainWindow.h:768 -#: objects/ui_MainWindow.h:847 +#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 msgid "Zoom Out" msgstr "Zoom Arrière" @@ -338,7 +334,7 @@ msgstr "F11" #: objects/ui_MainWindow.h:789 msgid "Thrown Together" -msgstr "" +msgstr "Jeté ensemble" #: objects/ui_MainWindow.h:790 msgid "F12" @@ -362,7 +358,7 @@ msgstr "Ctrl+2" #: objects/ui_MainWindow.h:795 msgid "Show Crosshairs" -msgstr "" +msgstr "Afficher la Mire" #: objects/ui_MainWindow.h:796 msgid "Ctrl+3" @@ -460,8 +456,7 @@ msgstr "Effacer Récents" msgid "Export as DXF..." msgstr "Exporter comme DXF..." -#: objects/ui_MainWindow.h:820 -#: objects/ui_OpenCSGWarningDialog.h:94 +#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 msgid "Close" msgstr "Fermer" @@ -469,8 +464,7 @@ msgstr "Fermer" msgid "Ctrl+W" msgstr "Ctrl+W" -#: objects/ui_MainWindow.h:822 -#: objects/ui_Preferences.h:608 +#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 msgid "Preferences" msgstr "Préférences" @@ -630,8 +624,7 @@ msgstr "&Aide" msgid "Find" msgstr "Rechercher" -#: objects/ui_MainWindow.h:867 -#: objects/ui_MainWindow.h:874 +#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 msgid "Replace" msgstr "Remplacer" @@ -689,13 +682,11 @@ msgstr "Affiche ce message à nouveau" msgid "3D View" msgstr "&Vue 3D" -#: objects/ui_Preferences.h:610 -#: src/UIUtils.cc:85 +#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 msgid "Advanced" msgstr "Avancé" -#: objects/ui_Preferences.h:611 -#: src/mainwin.cc:2339 +#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 msgid "Editor" msgstr "Éditeur" @@ -703,8 +694,7 @@ msgstr "Éditeur" msgid "Update" msgstr "Mettre à jour" -#: objects/ui_Preferences.h:613 -#: objects/ui_Preferences.h:633 +#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 msgid "Features" msgstr "Fonctionnalités" @@ -782,14 +772,13 @@ msgstr "éléments" #: objects/ui_Preferences.h:639 msgid "Force Goldfeather" -msgstr "" +msgstr "Forcer Goldfeather" #: objects/ui_Preferences.h:640 msgid "CGAL Cache size" msgstr "Taille du Cache de CGAL" -#: objects/ui_Preferences.h:641 -#: objects/ui_Preferences.h:643 +#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 msgid "bytes" msgstr "octets" @@ -833,8 +822,7 @@ msgstr "%v / %m" msgid "About OpenSCAD " msgstr "À propos de OpenSCAD" -#: src/mainwin.cc:773 -#: src/mainwin.cc:1315 +#: src/mainwin.cc:773 src/mainwin.cc:1315 msgid "Untitled.scad" msgstr "Untitled.scad" @@ -866,13 +854,11 @@ msgstr "" "Ce document a été modifié.\n" "Voulez-vous vraiment recharger le fichier?" -#: src/mainwin.cc:1966 -#: src/mainwin.cc:2023 +#: src/mainwin.cc:1966 src/mainwin.cc:2023 msgid "Export %1 File" msgstr "Exporter %1 Fichier" -#: src/mainwin.cc:1967 -#: src/mainwin.cc:2027 +#: src/mainwin.cc:1967 src/mainwin.cc:2027 msgid "%1 Files (*%2)" msgstr "%1 Fichiers (*%2)" From 77c865d1bead1dffb9bc5a5191fce35ab481275f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 16 Dec 2014 13:03:12 -0500 Subject: [PATCH 139/263] Improved regex to correctly match quoted characters in strings --- src/Tree.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tree.cc b/src/Tree.cc index e2dc1182..9e67b923 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -49,7 +49,7 @@ const std::string &Tree::getIdString(const AbstractNode &node) const assert(this->root_node); if (!this->nodeidcache.contains(node)) { const std::string &str = getString(node); - const boost::regex re("(\".*\")|\\S+"); + const boost::regex re("[^\\s\\\"]+|\\\"(?:[^\\\"\\\\]|\\\\.)*\\\""); std::stringstream sstream; boost::sregex_token_iterator i(str.begin(), str.end(), re, 0); std::copy(i, boost::sregex_token_iterator(), std::ostream_iterator(sstream)); From 4be9a43b406726fdb0bf6eb8e0c234e2ed2e9266 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 16 Dec 2014 21:21:06 +0100 Subject: [PATCH 140/263] Add debug output for the Node Id Cache. --- src/Tree.cc | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Tree.cc b/src/Tree.cc index 9e67b923..7264d89d 100644 --- a/src/Tree.cc +++ b/src/Tree.cc @@ -1,5 +1,6 @@ #include "Tree.h" #include "nodedumper.h" +#include "printutils.h" #include #include @@ -31,11 +32,6 @@ 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. @@ -47,16 +43,22 @@ static bool filter(char c) const std::string &Tree::getIdString(const AbstractNode &node) const { assert(this->root_node); + if (!this->nodeidcache.contains(node)) { - const std::string &str = getString(node); + const std::string &nodestr = getString(node); const boost::regex re("[^\\s\\\"]+|\\\"(?:[^\\\"\\\\]|\\\\.)*\\\""); std::stringstream sstream; - boost::sregex_token_iterator i(str.begin(), str.end(), re, 0); - std::copy(i, boost::sregex_token_iterator(), std::ostream_iterator(sstream)); + boost::sregex_token_iterator i(nodestr.begin(), nodestr.end(), re, 0); + std::copy(i, boost::sregex_token_iterator(), std::ostream_iterator(sstream)); - return this->nodeidcache.insert(node, sstream.str()); + const std::string & result = this->nodeidcache.insert(node, sstream.str()); + PRINTDB("Id Cache MISS: %s", result); + return result; + } else { + const std::string & result = this->nodeidcache[node]; + PRINTDB("Id Cache HIT: %s", result); + return result; } - return this->nodeidcache[node]; } /*! From 0f2806ab8adbbae7725d369d29e56990bc93e5d3 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 16 Dec 2014 21:31:00 +0100 Subject: [PATCH 141/263] Assume internally used strings are stored in UTF-8. --- src/mainwin.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mainwin.cc b/src/mainwin.cc index a4601f59..73071ad0 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1595,9 +1595,9 @@ void MainWindow::compileTopLevelDocument() this->last_compiled_doc = editor->toPlainText(); std::string fulltext = - std::string(this->last_compiled_doc.toLocal8Bit().constData()) + + std::string(this->last_compiled_doc.toUtf8().constData()) + "\n" + commandline_commands; - + delete this->root_module; this->root_module = NULL; @@ -1819,7 +1819,7 @@ void MainWindow::actionDisplayAST() e->setWindowTitle("AST Dump"); e->setReadOnly(true); if (root_module) { - e->setPlainText(QString::fromLocal8Bit(root_module->dump("", "").c_str())); + e->setPlainText(QString::fromUtf8(root_module->dump("", "").c_str())); } else { e->setPlainText("No AST to dump. Please try compiling first..."); } @@ -1837,7 +1837,7 @@ void MainWindow::actionDisplayCSGTree() e->setWindowTitle("CSG Tree Dump"); e->setReadOnly(true); if (this->root_node) { - e->setPlainText(QString::fromLocal8Bit(this->tree.getString(*this->root_node).c_str())); + e->setPlainText(QString::fromUtf8(this->tree.getString(*this->root_node).c_str())); } else { e->setPlainText("No CSG to dump. Please try compiling first..."); } @@ -1856,11 +1856,11 @@ void MainWindow::actionDisplayCSGProducts() 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 ? QString::fromLocal8Bit(root_raw_term->dump().c_str()) : "N/A", - root_norm_term ? QString::fromLocal8Bit(root_norm_term->dump().c_str()) : "N/A", - this->root_chain ? QString::fromLocal8Bit(this->root_chain->dump().c_str()) : "N/A", - highlights_chain ? QString::fromLocal8Bit(highlights_chain->dump().c_str()) : "N/A", - background_chain ? QString::fromLocal8Bit(background_chain->dump().c_str()) : "N/A")); + .arg(root_raw_term ? QString::fromUtf8(root_raw_term->dump().c_str()) : "N/A", + root_norm_term ? QString::fromUtf8(root_norm_term->dump().c_str()) : "N/A", + this->root_chain ? QString::fromUtf8(this->root_chain->dump().c_str()) : "N/A", + highlights_chain ? QString::fromUtf8(highlights_chain->dump().c_str()) : "N/A", + background_chain ? QString::fromUtf8(background_chain->dump().c_str()) : "N/A")); e->show(); e->resize(600, 400); @@ -2528,7 +2528,7 @@ void MainWindow::consoleOutput(const std::string &msg, void *userdata) // originates in a worker thread. MainWindow *thisp = static_cast(userdata); QMetaObject::invokeMethod(thisp->console, "append", Qt::QueuedConnection, - Q_ARG(QString, QString::fromLocal8Bit(msg.c_str()))); + Q_ARG(QString, QString::fromUtf8(msg.c_str()))); if (thisp->procevents) QApplication::processEvents(); } From fe3cae81200862df06107de58c674fa74ebbc221 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 16 Dec 2014 17:03:06 -0500 Subject: [PATCH 142/263] #1065 Text preview optimization: Don't tesselate every frame --- src/CSGTermEvaluator.cc | 8 +++++++- src/renderer.cc | 28 ++++++---------------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index eef880f8..4adfa62d 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -95,7 +95,13 @@ static shared_ptr evaluate_csg_term_from_geometry(const State &state, { std::stringstream stream; stream << node.name() << node.index(); - shared_ptr t(new CSGTerm(geom, state.matrix(), state.color(), stream.str())); + + // We cannot render Polygon2d directly, so we preprocess (tessellate) it here + shared_ptr g = geom; + shared_ptr p2d = dynamic_pointer_cast(geom); + if (p2d) g.reset(p2d->tessellate()); + + shared_ptr t(new CSGTerm(g, state.matrix(), state.color(), stream.str())); if (modinst->isHighlight()) { t->flag = CSGTerm::FLAG_HIGHLIGHT; highlights.push_back(t); diff --git a/src/renderer.cc b/src/renderer.cc index 3b7a2a8a..79e4f4d2 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -101,31 +101,15 @@ void Renderer::setColorScheme(const ColorScheme &cs) { void Renderer::render_surface(shared_ptr geom, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo) { - shared_ptr ps; - shared_ptr p2d = dynamic_pointer_cast(geom); - if (p2d) { - ps.reset(p2d->tessellate()); - } - else { - ps = dynamic_pointer_cast(geom); - } - if (ps) { - ps->render_surface(csgmode, m, shaderinfo); - } + shared_ptr ps = dynamic_pointer_cast(geom); + assert(ps); + ps->render_surface(csgmode, m, shaderinfo); } void Renderer::render_edges(shared_ptr geom, csgmode_e csgmode) { - shared_ptr ps; - shared_ptr p2d = dynamic_pointer_cast(geom); - if (p2d) { - ps.reset(p2d->tessellate()); - } - else { - ps = dynamic_pointer_cast(geom); - } - if (ps) { - ps->render_edges(csgmode); - } + shared_ptr ps = dynamic_pointer_cast(geom); + assert(ps); + ps->render_edges(csgmode); } From 93b6113edc5895903393ef54d7926964bf573cfd Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 16 Dec 2014 17:22:41 -0500 Subject: [PATCH 143/263] #1065 fix: It's allowed to pass NULL geometry to the preview renderer --- src/renderer.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/renderer.cc b/src/renderer.cc index 79e4f4d2..e7373ea1 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -102,14 +102,12 @@ void Renderer::setColorScheme(const ColorScheme &cs) { void Renderer::render_surface(shared_ptr geom, csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo) { shared_ptr ps = dynamic_pointer_cast(geom); - assert(ps); - ps->render_surface(csgmode, m, shaderinfo); + if (ps) ps->render_surface(csgmode, m, shaderinfo); } void Renderer::render_edges(shared_ptr geom, csgmode_e csgmode) { shared_ptr ps = dynamic_pointer_cast(geom); - assert(ps); - ps->render_edges(csgmode); + if (ps) ps->render_edges(csgmode); } From 1126a0ef17ea74f99caa7c4963dc079c31588c65 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 16 Dec 2014 23:15:11 +0100 Subject: [PATCH 144/263] Use separate project for winconsole and don't statically link Qt (fixes #870). --- openscad.pro | 4 ---- scripts/release-common.sh | 4 ++-- winconsole.pri | 28 ---------------------------- winconsole.pro | 23 +++++++++++++++++++++++ 4 files changed, 25 insertions(+), 34 deletions(-) delete mode 100644 winconsole.pri create mode 100644 winconsole.pro diff --git a/openscad.pro b/openscad.pro index d745c708..5ffa39fe 100644 --- a/openscad.pro +++ b/openscad.pro @@ -546,7 +546,3 @@ INSTALLS += icons man.path = $$PREFIX/share/man/man1 man.extra = cp -f doc/openscad.1 \"\$(INSTALL_ROOT)$${man.path}/$${FULLNAME}.1\" INSTALLS += man - -CONFIG(winconsole) { - include(winconsole.pri) -} diff --git a/scripts/release-common.sh b/scripts/release-common.sh index f9faf8a6..709d508a 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -254,8 +254,8 @@ case $OS in echo "cant find $TARGET/openscad.exe. build failed. stopping." exit fi - # make console pipe-able openscad.com - see winconsole.pri for info - qmake CONFIG+=winconsole ../openscad.pro + # make console pipe-able openscad.com - see winconsole.pro for info + qmake ../winconsole.pro make if [ ! -e $TARGET/openscad.com ]; then echo "cant find $TARGET/openscad.com. build failed. stopping." diff --git a/winconsole.pri b/winconsole.pri deleted file mode 100644 index a3991ae7..00000000 --- a/winconsole.pri +++ /dev/null @@ -1,28 +0,0 @@ -# Windows console issues workaround stub. -# -# Usage: put at the end of .pro file, then run qmake CONFIG+=winconsole -# -# This attempts to solve the problem of piping OpenSCAD under windows -# command line (GUI mode programs in Windows dont allow this). We use -# the 'devenv' solution, which means building two binaries: -# openscad.exe, and openscad.com, the latter being a wrapper for the -# former. See src/winconsole.c for more details. -# -# Qmake doesn't like building two binaries in the same directory so we -# depend on release-common.sh to call qmake twice and package the file properly - -CONFIG(winconsole) { - TEMPLATE = app - TARGET = openscad_winconsole - FORMS = - HEADERS = - FLEXSOURCES = - BISONSOURCES = - RESOURCES = - SOURCES = src/winconsole.c - CONFIG += console # sets IMAGE_SUBSYSTEM_WINDOWS_CUI in binary - LIBS -= $$LIBS - RC_FILE -= $$RC_FILE - QMAKE_POST_LINK = cd $(DESTDIR) && mv openscad_winconsole.exe openscad.com -} - diff --git a/winconsole.pro b/winconsole.pro new file mode 100644 index 00000000..11078f36 --- /dev/null +++ b/winconsole.pro @@ -0,0 +1,23 @@ +# Windows console issues workaround stub. +# +# This attempts to solve the problem of piping OpenSCAD under windows +# command line (GUI mode programs in Windows dont allow this). We use +# the 'devenv' solution, which means building two binaries: +# openscad.exe, and openscad.com, the latter being a wrapper for the +# former. See src/winconsole.c for more details. +# +# Qmake doesn't like building two binaries in the same directory so we +# depend on release-common.sh to call qmake twice and package the file +# properly + +TEMPLATE = app +TARGET = openscad_winconsole +FORMS = +HEADERS = +FLEXSOURCES = +BISONSOURCES = +RESOURCES = +SOURCES = src/winconsole.c +CONFIG -= qt +CONFIG += console # sets IMAGE_SUBSYSTEM_WINDOWS_CUI in binary +QMAKE_POST_LINK = cd $(DESTDIR) && mv openscad_winconsole.exe openscad.com From a40b2848e90e7b6aa8d247b94f2321bad7d516c4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 16 Dec 2014 17:39:38 -0500 Subject: [PATCH 145/263] killed compiler warning --- src/PlatformUtils-mac.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm index 768d9c09..6ddf252a 100644 --- a/src/PlatformUtils-mac.mm +++ b/src/PlatformUtils-mac.mm @@ -46,7 +46,6 @@ std::string PlatformUtils::sysinfo() result += "Mac OS X "; result += [[[NSProcessInfo processInfo] operatingSystemVersionString] UTF8String]; - int mib[2]; int64_t physical_memory; int32_t numcpu; size_t length64 = sizeof(int64_t); From 0448b0f1dbc73e98478bffd6d0beec80f66feef8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 16 Dec 2014 17:40:13 -0500 Subject: [PATCH 146/263] #1076 Fix memory display on 64-bit Windows --- src/PlatformUtils.cc | 2 +- src/PlatformUtils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index a15a0a3c..329fb8fb 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -192,7 +192,7 @@ int PlatformUtils::setenv(const char *name, const char *value, int overwrite) #endif } -std::string PlatformUtils::toMemorySizeString(unsigned long bytes, int digits) +std::string PlatformUtils::toMemorySizeString(uint64_t bytes, int digits) { static const char *units[] = { "B", "kB", "MB", "GB", "TB", NULL }; diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index 5210dc85..0e9f9868 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -84,5 +84,5 @@ namespace PlatformUtils { * Convert the number of bytes to a human readable string with * a given number of digits. */ - std::string toMemorySizeString(unsigned long bytes, int digits); + std::string toMemorySizeString(uint64_t bytes, int digits); } From 3d0749b61939ccefa2d01dad07206992b96e81e5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 16 Dec 2014 18:01:25 -0500 Subject: [PATCH 147/263] Improve displayed rendering time by including compilation time --- src/MainWindow.h | 3 +++ src/mainwin.cc | 11 +++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/MainWindow.h b/src/MainWindow.h index edf595c2..5d415734 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -14,6 +14,7 @@ #include #include #include +#include enum export_type_e { EXPORT_TYPE_UNKNOWN, @@ -40,6 +41,8 @@ public: std::string autoReloadId; QTimer *waitAfterReloadTimer; + QTime renderingTime; + ModuleContext top_ctx; FileModule *root_module; // Result of parsing ModuleInstantiation root_inst; // Top level instance diff --git a/src/mainwin.cc b/src/mainwin.cc index 73071ad0..2c46b4db 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -862,6 +862,8 @@ void MainWindow::compile(bool reload, bool forcedone) bool shouldcompiletoplevel = false; bool didcompile = false; + this->renderingTime.start(); + // Reload checks the timestamp of the toplevel file and refreshes if necessary, if (reload) { // Refresh files if it has changed on disk @@ -1035,9 +1037,6 @@ void MainWindow::compileCSG(bool procevents) if (procevents) QApplication::processEvents(); // Main CSG evaluation - QTime t; - t.start(); - this->progresswidget = new ProgressWidget(this); connect(this->progresswidget, SIGNAL(requestShow()), this, SLOT(showProgress())); @@ -1123,8 +1122,8 @@ void MainWindow::compileCSG(bool procevents) this->thrownTogetherRenderer = new ThrownTogetherRenderer(this->root_chain, this->highlights_chain, this->background_chain); - PRINT("CSG generation finished."); - int s = t.elapsed() / 1000; + PRINT("Compile and preview finished."); + int s = this->renderingTime.elapsed() / 1000; PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60)); if (procevents) QApplication::processEvents(); } @@ -1762,7 +1761,7 @@ void MainWindow::actionRenderDone(shared_ptr root_geom) CGALCache::instance()->print(); #endif - int s = this->progresswidget->elapsedTime() / 1000; + int s = this->renderingTime.elapsed() / 1000; PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60)); if (root_geom && !root_geom->isEmpty()) { From 1aef9f275857a1b5942d8b2cbdc077df6b5942fb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 17 Dec 2014 12:12:53 -0500 Subject: [PATCH 148/263] #1065 Show progress dialog while building font cache --- src/FontCache.cc | 13 ++++++++++++- src/FontCache.h | 6 ++++++ src/Polygon2d-CGAL.cc | 1 + src/openscad.cc | 21 +++++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/FontCache.cc b/src/FontCache.cc index 29599e32..c4b9a9dc 100644 --- a/src/FontCache.cc +++ b/src/FontCache.cc @@ -81,6 +81,9 @@ const std::string &FontInfo::get_file() const } FontCache * FontCache::self = NULL; +FontCache::ProgressHandlerFunc *FontCache::start_cb = NULL; +FontCache::ProgressHandlerFunc *FontCache::end_cb = NULL; +void *FontCache::cb_userdata = NULL; const std::string FontCache::DEFAULT_FONT("XXX"); FontCache::FontCache() @@ -131,8 +134,9 @@ FontCache::FontCache() } } - // FIXME: Caching happens here. This would be a good place to notify the user + if (FontCache::start_cb) FontCache::start_cb(FontCache::cb_userdata); FcConfigBuildFonts(this->config); + if (FontCache::end_cb) FontCache::end_cb(FontCache::cb_userdata); // For use by LibraryInfo FcStrList *dirs = FcConfigGetFontDirs(this->config); @@ -162,6 +166,13 @@ FontCache * FontCache::instance() return self; } +void FontCache::registerProgressHandler(ProgressHandlerFunc *start, ProgressHandlerFunc *end, void *userdata) +{ + FontCache::start_cb = start; + FontCache::end_cb = end; + FontCache::cb_userdata = userdata; +} + void FontCache::register_font_file(const std::string &path) { if (!FcConfigAppFontAddFile(this->config, reinterpret_cast (path.c_str()))) { diff --git a/src/FontCache.h b/src/FontCache.h index 2633c04d..e8dd318a 100644 --- a/src/FontCache.h +++ b/src/FontCache.h @@ -75,11 +75,17 @@ public: FontInfoList *list_fonts() const; static FontCache *instance(); + + typedef void (ProgressHandlerFunc)(void *userdata); + static void registerProgressHandler(ProgressHandlerFunc *start, ProgressHandlerFunc *end, void *userdata = NULL); private: typedef std::pair cache_entry_t; typedef std::map cache_t; static FontCache *self; + static ProgressHandlerFunc *start_cb; + static ProgressHandlerFunc *end_cb; + static void *cb_userdata; bool init_ok; cache_t cache; diff --git a/src/Polygon2d-CGAL.cc b/src/Polygon2d-CGAL.cc index cd322d99..b6f2f663 100644 --- a/src/Polygon2d-CGAL.cc +++ b/src/Polygon2d-CGAL.cc @@ -105,6 +105,7 @@ mark_domains(CDT &cdt) */ PolySet *Polygon2d::tessellate() const { + PRINTDB("Polygon2d::tessellate(): %d outlines", this->outlines().size()); PolySet *polyset = new PolySet(*this); Polygon2DCGAL::CDT cdt; // Uses a constrained Delaunay triangulator. diff --git a/src/openscad.cc b/src/openscad.cc index 54349f7f..621ea7b1 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -41,6 +41,7 @@ #include "nodedumper.h" #include "stackcheck.h" #include "CocoaUtils.h" +#include "FontCache.h" #include #include @@ -577,6 +578,22 @@ bool QtUseGUI() return useGUI; } + +#include +QProgressDialog *fontCacheProgress = NULL; + +void fontCacheStart(void *userdata) +{ + fontCacheProgress = new QProgressDialog("Fontconfig needs to update its font cache.\nThis can take up to a couple of minutes.", QString(), 0, 0); + fontCacheProgress->show(); +} + +void fontCacheEnd(void *userdata) +{ + delete fontCacheProgress; + fontCacheProgress = NULL; +} + int gui(vector &inputFiles, const fs::path &original_path, int argc, char ** argv) { #ifdef Q_OS_MACX @@ -607,6 +624,10 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha const QString &app_path = app.applicationDirPath(); PlatformUtils::registerApplicationPath(app_path.toLocal8Bit().constData()); + FontCache::registerProgressHandler(fontCacheStart, fontCacheEnd); + + + parser_init(); QSettings settings; From 6492d252651a9ecb2ded12b2d1f8499ae8b4eb86 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 17 Dec 2014 12:56:52 -0500 Subject: [PATCH 149/263] #1065 The text module is no longer experimental --- src/feature.cc | 1 - src/feature.h | 2 -- src/text.cc | 2 +- .../features}/text-empty-tests.scad | 0 .../features}/text-font-alignment-tests.scad | 0 .../features}/text-font-composition.scad | 0 .../features}/text-font-direction-tests.scad | 0 .../features}/text-font-simple-tests.scad | 0 .../features}/text-font-symbol.scad | 6 ++--- .../features}/text-font-tests.scad | 4 ++-- .../features}/text-search-test.scad | 0 .../features}/tessellation-text-test.scad | 0 tests/CMakeLists.txt | 19 +++++---------- tests/export_import_pngtest.py | 4 ++-- .../csgtexttest/allmodules-expected.txt | 2 +- .../logo_and_text-expected.csg | 16 +++++++++---- .../text_on_cube-expected.csg | 24 ++++++++++++++----- .../dumptest/allmodules-expected.csg | 1 + 18 files changed, 46 insertions(+), 35 deletions(-) rename testdata/scad/{experimental => 2D/features}/text-empty-tests.scad (100%) rename testdata/scad/{experimental => 2D/features}/text-font-alignment-tests.scad (100%) rename testdata/scad/{experimental => 2D/features}/text-font-composition.scad (100%) rename testdata/scad/{experimental => 2D/features}/text-font-direction-tests.scad (100%) rename testdata/scad/{experimental => 2D/features}/text-font-simple-tests.scad (100%) rename testdata/scad/{experimental => 2D/features}/text-font-symbol.scad (84%) rename testdata/scad/{experimental => 2D/features}/text-font-tests.scad (86%) rename testdata/scad/{experimental => 2D/features}/text-search-test.scad (100%) rename testdata/scad/{experimental => 3D/features}/tessellation-text-test.scad (100%) diff --git a/src/feature.cc b/src/feature.cc index eb0ee8fd..79df7cce 100644 --- a/src/feature.cc +++ b/src/feature.cc @@ -18,7 +18,6 @@ Feature::list_t Feature::feature_list; * argument to enable the option and for saving the option value in GUI * context. */ -const Feature Feature::ExperimentalTextModule("text", "Enable the text() module."); Feature::Feature(const std::string &name, const std::string &description) : enabled(false), name(name), description(description) diff --git a/src/feature.h b/src/feature.h index 5922295a..579ba3c0 100644 --- a/src/feature.h +++ b/src/feature.h @@ -12,8 +12,6 @@ public: typedef std::vector list_t; typedef list_t::iterator iterator; - static const Feature ExperimentalTextModule; - const std::string& get_name() const; const std::string& get_description() const; diff --git a/src/text.cc b/src/text.cc index 3b4f1a7c..87372fc0 100644 --- a/src/text.cc +++ b/src/text.cc @@ -40,7 +40,7 @@ using namespace boost::assign; // bring 'operator+=()' into scope class TextModule : public AbstractModule { public: - TextModule() : AbstractModule(Feature::ExperimentalTextModule) { } + TextModule() : AbstractModule() { } virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx) const; }; diff --git a/testdata/scad/experimental/text-empty-tests.scad b/testdata/scad/2D/features/text-empty-tests.scad similarity index 100% rename from testdata/scad/experimental/text-empty-tests.scad rename to testdata/scad/2D/features/text-empty-tests.scad diff --git a/testdata/scad/experimental/text-font-alignment-tests.scad b/testdata/scad/2D/features/text-font-alignment-tests.scad similarity index 100% rename from testdata/scad/experimental/text-font-alignment-tests.scad rename to testdata/scad/2D/features/text-font-alignment-tests.scad diff --git a/testdata/scad/experimental/text-font-composition.scad b/testdata/scad/2D/features/text-font-composition.scad similarity index 100% rename from testdata/scad/experimental/text-font-composition.scad rename to testdata/scad/2D/features/text-font-composition.scad diff --git a/testdata/scad/experimental/text-font-direction-tests.scad b/testdata/scad/2D/features/text-font-direction-tests.scad similarity index 100% rename from testdata/scad/experimental/text-font-direction-tests.scad rename to testdata/scad/2D/features/text-font-direction-tests.scad diff --git a/testdata/scad/experimental/text-font-simple-tests.scad b/testdata/scad/2D/features/text-font-simple-tests.scad similarity index 100% rename from testdata/scad/experimental/text-font-simple-tests.scad rename to testdata/scad/2D/features/text-font-simple-tests.scad diff --git a/testdata/scad/experimental/text-font-symbol.scad b/testdata/scad/2D/features/text-font-symbol.scad similarity index 84% rename from testdata/scad/experimental/text-font-symbol.scad rename to testdata/scad/2D/features/text-font-symbol.scad index eb7d4d48..bbb3dc87 100644 --- a/testdata/scad/experimental/text-font-symbol.scad +++ b/testdata/scad/2D/features/text-font-symbol.scad @@ -1,6 +1,6 @@ -use <../../ttf/marvosym-3.10/marvosym.ttf> -use <../../ttf/liberation-2.00.1/LiberationSans-Regular.ttf> -use <../../ttf/amiri-0.106/amiri-regular.ttf> +use <../../../ttf/marvosym-3.10/marvosym.ttf> +use <../../../ttf/liberation-2.00.1/LiberationSans-Regular.ttf> +use <../../../ttf/amiri-0.106/amiri-regular.ttf> // FIXME: Needs a freely distributable font that is encoded like Webdings // FIXME: with Microsoft/System charmap and charcodes at 0xf000. Using diff --git a/testdata/scad/experimental/text-font-tests.scad b/testdata/scad/2D/features/text-font-tests.scad similarity index 86% rename from testdata/scad/experimental/text-font-tests.scad rename to testdata/scad/2D/features/text-font-tests.scad index ae10b0c9..d7b566f5 100644 --- a/testdata/scad/experimental/text-font-tests.scad +++ b/testdata/scad/2D/features/text-font-tests.scad @@ -1,5 +1,5 @@ -use <../../ttf/amiri-0.106/amiri-regular.ttf> -use <../../ttf/liberation-2.00.1/LiberationSans-Regular.ttf> +use <../../../ttf/amiri-0.106/amiri-regular.ttf> +use <../../../ttf/liberation-2.00.1/LiberationSans-Regular.ttf> t1="OpenSCAD"; t2="الخط الأميري"; diff --git a/testdata/scad/experimental/text-search-test.scad b/testdata/scad/2D/features/text-search-test.scad similarity index 100% rename from testdata/scad/experimental/text-search-test.scad rename to testdata/scad/2D/features/text-search-test.scad diff --git a/testdata/scad/experimental/tessellation-text-test.scad b/testdata/scad/3D/features/tessellation-text-test.scad similarity index 100% rename from testdata/scad/experimental/tessellation-text-test.scad rename to testdata/scad/3D/features/tessellation-text-test.scad diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9c9f84c1..290d8448 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -913,7 +913,7 @@ function(add_cmdline_test TESTCMD_BASENAME) if( "${match_result1}" STREQUAL "" ) if( "${match_result2}" STREQUAL "" ) if( "${match_result3}" STREQUAL "" ) - set(EXPERIMENTAL_OPTION "--enable=text") + set(EXPERIMENTAL_OPTION "") endif() endif() endif() @@ -1085,8 +1085,7 @@ list(APPEND CGALPNGTEST_3D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/inclu ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-pcbvicebar.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-tardis.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/bad-stl-wing.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/experimental/tessellation-text-test.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/rotate_extrude-hole.scad) list(APPEND CGALPNGTEST_FILES ${CGALPNGTEST_2D_FILES} ${CGALPNGTEST_3D_FILES}) list(APPEND OPENCSGTEST_FILES ${CGALPNGTEST_FILES}) @@ -1095,7 +1094,6 @@ list(APPEND THROWNTOGETHERTEST_FILES ${OPENCSGTEST_FILES}) list(APPEND CGALSTLSANITYTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/normal-nan.scad) -file(GLOB EXPERIMENTAL_TEXT_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/experimental/text-*.scad) # Issue #899 set_test_config(Bugs dxfpngtest_text-font-direction-tests cgalpngtest_text-font-direction-tests @@ -1140,7 +1138,7 @@ disable_tests( ) # 2D tests -list(APPEND FILES_2D ${FEATURES_2D_FILES} ${SCAD_DXF_FILES} ${EXAMPLE_2D_FILES} ${EXPERIMENTAL_TEXT_FILES}) +list(APPEND FILES_2D ${FEATURES_2D_FILES} ${SCAD_DXF_FILES} ${EXAMPLE_2D_FILES}) list(APPEND ALL_2D_FILES ${FILES_2D}) # FIXME: This test illustrates a weakness in child() combined with modifiers. @@ -1342,8 +1340,8 @@ add_cmdline_test(csgtermtest EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX term FILES add_cmdline_test(echotest EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX echo FILES ${ECHO_FILES}) add_cmdline_test(dumptest EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX csg FILES ${DUMPTEST_FILES}) add_cmdline_test(dumptest-examples EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX csg FILES ${EXAMPLE_FILES}) -add_cmdline_test(cgalpngtest EXE ${OPENSCAD_BINPATH} ARGS --enable=text --render -o SUFFIX png FILES ${CGALPNGTEST_FILES}) -add_cmdline_test(opencsgtest EXE ${OPENSCAD_BINPATH} ARGS --enable=text -o SUFFIX png FILES ${OPENCSGTEST_FILES}) +add_cmdline_test(cgalpngtest EXE ${OPENSCAD_BINPATH} ARGS --render -o SUFFIX png FILES ${CGALPNGTEST_FILES}) +add_cmdline_test(opencsgtest EXE ${OPENSCAD_BINPATH} ARGS -o SUFFIX png FILES ${OPENCSGTEST_FILES}) add_cmdline_test(csgpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=csg --render EXPECTEDDIR cgalpngtest SUFFIX png FILES ${CGALPNGTEST_FILES}) add_cmdline_test(throwntogethertest EXE ${OPENSCAD_BINPATH} ARGS --preview=throwntogether -o SUFFIX png FILES ${THROWNTOGETHERTEST_FILES}) # FIXME: We don't actually need to compare the output of cgalstlsanitytest @@ -1364,7 +1362,7 @@ set_test_config(Bugs offpngtest_polyhedron-tests # No issue - this was introduced when fixing #1033 set_test_config(Bugs stlpngtest_bad-stl-wing) -add_cmdline_test(monotonepngtest EXE ${OPENSCAD_BINPATH} ARGS --colorscheme=Monotone --enable=text --render -o SUFFIX png FILES ${EXPORT3D_TEST_FILES}) +add_cmdline_test(monotonepngtest EXE ${OPENSCAD_BINPATH} ARGS --colorscheme=Monotone --render -o SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(stlpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=STL --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(offpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=OFF --render=cgal EXPECTEDDIR monotonepngtest SUFFIX png FILES ${EXPORT3D_TEST_FILES}) add_cmdline_test(dxfpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=DXF --render=cgal EXPECTEDDIR cgalpngtest SUFFIX png FILES ${FILES_2D}) @@ -1380,11 +1378,6 @@ add_failing_test(offfailedtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DI # # Add experimental tests # -add_cmdline_test(dumptest EXE ${OPENSCAD_BINPATH} ARGS --enable=text -o SUFFIX csg FILES ${EXPERIMENTAL_TEXT_FILES}) -add_cmdline_test(cgalpngtest EXE ${OPENSCAD_BINPATH} ARGS --render --enable=text -o SUFFIX png FILES ${EXPERIMENTAL_TEXT_FILES}) -add_cmdline_test(opencsgtest EXE ${OPENSCAD_BINPATH} ARGS --enable=text -o SUFFIX png FILES ${EXPERIMENTAL_TEXT_FILES}) -add_cmdline_test(csgpngtest EXE ${PYTHON_EXECUTABLE} SCRIPT ${CMAKE_SOURCE_DIR}/export_import_pngtest.py ARGS --openscad=${OPENSCAD_BINPATH} --format=csg --render EXPECTEDDIR cgalpngtest SUFFIX png FILES ${EXPERIMENTAL_TEXT_FILES}) -add_cmdline_test(throwntogethertest EXE ${OPENSCAD_BINPATH} ARGS --preview=throwntogether --enable=text -o SUFFIX png FILES ${EXPERIMENTAL_TEXT_FILES}) # Tests using the actual OpenSCAD binary diff --git a/tests/export_import_pngtest.py b/tests/export_import_pngtest.py index 710aa880..3b85f72b 100644 --- a/tests/export_import_pngtest.py +++ b/tests/export_import_pngtest.py @@ -83,7 +83,7 @@ if inputsuffix != '.scad' and inputsuffix != '.csg': # # First run: Just export the given filetype # -export_cmd = [args.openscad, inputfile, '--enable=text', '-o', exportfile] + remaining_args +export_cmd = [args.openscad, inputfile, '-o', exportfile] + remaining_args print('Running OpenSCAD #1:') print(' '.join(export_cmd)) result = subprocess.call(export_cmd) @@ -100,7 +100,7 @@ if args.format != 'csg': newscadfile += '.scad' createImport(exportfile, newscadfile) -create_png_cmd = [args.openscad, newscadfile, '--enable=text', '-o', pngfile] + remaining_args +create_png_cmd = [args.openscad, newscadfile, '-o', pngfile] + remaining_args print('Running OpenSCAD #2:') print(' '.join(create_png_cmd)) fontdir = os.path.join(os.path.dirname(args.openscad), "..", "testdata"); diff --git a/tests/regression/csgtexttest/allmodules-expected.txt b/tests/regression/csgtexttest/allmodules-expected.txt index c881bfa5..cfd35242 100644 --- a/tests/regression/csgtexttest/allmodules-expected.txt +++ b/tests/regression/csgtexttest/allmodules-expected.txt @@ -1 +1 @@ -group1(minkowski2+glide3+subdiv4+hull5+resize6+group7+group7+group7+intersection10+group11(sphere)+union13+difference14+intersection10+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import+import+import+import+group7+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render33+surface+transform35+transform35+transform37+transform35+transform35+color40+offset) +group1(minkowski2+glide3+subdiv4+hull5+resize6+group7+group7+group7+intersection10+group11(sphere)+union13+difference14+intersection10+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import+import+import+import+group7+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render33+surface+transform35+transform35+transform37+transform35+transform35+color40+offset+text) diff --git a/tests/regression/dumptest-examples/logo_and_text-expected.csg b/tests/regression/dumptest-examples/logo_and_text-expected.csg index 51c60980..aff99f53 100644 --- a/tests/regression/dumptest-examples/logo_and_text-expected.csg +++ b/tests/regression/dumptest-examples/logo_and_text-expected.csg @@ -29,7 +29,9 @@ group() { group() { group() { multmatrix([[1, 0, 0, 0], [0, 0, -1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { - linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "Open", size = 42, spacing = 1, font = "Liberation Serif:style=Bold", direction = "ltr", language = "en", script = "latin", halign = "left", valign = "baseline", $fn = 16, $fa = 12, $fs = 2); + } } } } @@ -42,7 +44,9 @@ group() { group() { group() { multmatrix([[1, 0, 0, 0], [0, 0, -1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { - linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "SCAD", size = 42, spacing = 1, font = "Liberation Serif:style=Bold", direction = "ltr", language = "en", script = "latin", halign = "left", valign = "baseline", $fn = 16, $fa = 12, $fs = 2); + } } } } @@ -55,7 +59,9 @@ group() { group() { group() { multmatrix([[1, 0, 0, 0], [0, 0, -1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { - linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "The Programmers", size = 18, spacing = 1, font = "Liberation Serif", direction = "ltr", language = "en", script = "latin", halign = "left", valign = "baseline", $fn = 16, $fa = 12, $fs = 2); + } } } } @@ -68,7 +74,9 @@ group() { group() { group() { multmatrix([[1, 0, 0, 0], [0, 0, -1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { - linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 1, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "Solid 3D CAD Modeller", size = 18, spacing = 1, font = "Liberation Serif", direction = "ltr", language = "en", script = "latin", halign = "left", valign = "baseline", $fn = 16, $fa = 12, $fs = 2); + } } } } diff --git a/tests/regression/dumptest-examples/text_on_cube-expected.csg b/tests/regression/dumptest-examples/text_on_cube-expected.csg index f05e5658..a5bbed7c 100644 --- a/tests/regression/dumptest-examples/text_on_cube-expected.csg +++ b/tests/regression/dumptest-examples/text_on_cube-expected.csg @@ -8,40 +8,52 @@ group() { multmatrix([[1, 0, 0, 0], [0, 1, 0, -27.5], [0, 0, 1, 0], [0, 0, 0, 1]]) { multmatrix([[1, 0, 0, 0], [0, 0, -1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { group() { - linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "C", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 16, $fa = 12, $fs = 2); + } } } } multmatrix([[1, 0, 0, 27.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { multmatrix([[0, 0, 1, 0], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { group() { - linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "U", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 16, $fa = 12, $fs = 2); + } } } } multmatrix([[1, 0, 0, 0], [0, 1, 0, 27.5], [0, 0, 1, 0], [0, 0, 0, 1]]) { multmatrix([[-1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { group() { - linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "B", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 16, $fa = 12, $fs = 2); + } } } } multmatrix([[1, 0, 0, -27.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { multmatrix([[0, 0, -1, 0], [-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) { group() { - linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "E", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 16, $fa = 12, $fs = 2); + } } } } } multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 27.5], [0, 0, 0, 1]]) { group() { - linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "☺", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 16, $fa = 12, $fs = 2); + } } } multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -32.5], [0, 0, 0, 1]]) { group() { - linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2); + linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + text(text = "☼", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 16, $fa = 12, $fs = 2); + } } } } diff --git a/tests/regression/dumptest/allmodules-expected.csg b/tests/regression/dumptest/allmodules-expected.csg index f2a5308d..653ca751 100644 --- a/tests/regression/dumptest/allmodules-expected.csg +++ b/tests/regression/dumptest/allmodules-expected.csg @@ -40,4 +40,5 @@ group() { multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]); color([-1, -1, -1, 1]); offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2); + text(text = "", size = 10, spacing = 1, font = "", direction = "ltr", language = "en", script = "latin", halign = "left", valign = "baseline", $fn = 0, $fa = 12, $fs = 2); } From ca11624f52c86c52ae5c11aa1b585fca1d2f46b1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 17 Dec 2014 13:13:27 -0500 Subject: [PATCH 150/263] #1065 Added new expected test result --- .../tessellation-text-test-expected.csg | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/regression/dumptest/tessellation-text-test-expected.csg diff --git a/tests/regression/dumptest/tessellation-text-test-expected.csg b/tests/regression/dumptest/tessellation-text-test-expected.csg new file mode 100644 index 00000000..bee0d15b --- /dev/null +++ b/tests/regression/dumptest/tessellation-text-test-expected.csg @@ -0,0 +1,22 @@ +group() { + linear_extrude(height = 10, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + group() { + text(text = "C", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 8, $fa = 12, $fs = 2); + } + multmatrix([[1, 0, 0, 50], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + text(text = "C", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 16, $fa = 12, $fs = 2); + } + } + multmatrix([[1, 0, 0, 0], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + text(text = "C", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 24, $fa = 12, $fs = 2); + } + } + multmatrix([[1, 0, 0, 50], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + text(text = "C", size = 50, spacing = 1, font = "Liberation Sans", direction = "ltr", language = "en", script = "latin", halign = "center", valign = "center", $fn = 32, $fa = 12, $fs = 2); + } + } + } +} From 450dd836fa406cd239967f04768b589a7dda189b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 17 Dec 2014 15:52:51 -0500 Subject: [PATCH 151/263] Added png of document icon --- icons/SCAD.png | Bin 0 -> 103137 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 icons/SCAD.png diff --git a/icons/SCAD.png b/icons/SCAD.png new file mode 100644 index 0000000000000000000000000000000000000000..1d4e986f804a6df7e0133c3d6fb9181ff4a36d68 GIT binary patch literal 103137 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�E?WTwUPG@}BnNMenZSaGr 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�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 z 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 literal 0 HcmV?d00001 From f0c7ee6d61821e75f512490fe58146e995769603 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 17 Dec 2014 16:19:13 -0500 Subject: [PATCH 152/263] #1068 Attempt to fix the Windows line ending issue --- src/scintillaeditor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index e2d4d781..efc80d90 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -50,6 +50,8 @@ ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent) scintillaLayout = new QVBoxLayout(this); qsci = new QsciScintilla(this); + // Force EOL mode to Unix, since QTextStream will manage local EOL modes. + qsci->setEolMode(QsciScintilla::EolUnix); // // Remapping some scintilla key binding which conflict with OpenSCAD global From e34530f752df4987a704df88edf2af142ca7c22e Mon Sep 17 00:00:00 2001 From: Frode Lillerud Date: Wed, 17 Dec 2014 22:26:12 +0100 Subject: [PATCH 153/263] Create visualstudio.json Color scheme similar to default in Visual Studio. --- color-schemes/visualstudio.json | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 color-schemes/visualstudio.json diff --git a/color-schemes/visualstudio.json b/color-schemes/visualstudio.json new file mode 100644 index 00000000..5dc86651 --- /dev/null +++ b/color-schemes/visualstudio.json @@ -0,0 +1,31 @@ +{ + "name" : "Visual Studio", + "index" : 1400, + "paper" : "white", + "text" : "#111", + "caret" : { + "width" : 2, + "foreground" : "#000000", + "line-background" : "#eee" + }, + "colors" : { + "keyword1" : "blue", + "keyword2" : "blue", + "keyword3" : "#2B91AF", + "comment" : "DarkGreen", + "number" : "DarkRed", + "string" : "#A31515", + "operator" : "Blue", + "commentline" : "DarkGreen", + "selection-foreground" : "black", + "selection-background" : "lightblue", + "margin-background" : "white", + "margin-foreground" : "#2B91AF", + "matched-brace-background" : "darkgrey", + "matched-brace-foreground" : "black", + "unmatched-brace-background" : "red", + "unmatched-brace-foreground" : "#fff", + "error-marker" : "#ff0000", + "edge" : "#ffffff" + } +} From 832fca967224e49779d7d5c0341d600279fa8bda Mon Sep 17 00:00:00 2001 From: Frode Lillerud Date: Wed, 17 Dec 2014 22:26:41 +0100 Subject: [PATCH 154/263] Delete visualstudio.json --- color-schemes/visualstudio.json | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 color-schemes/visualstudio.json diff --git a/color-schemes/visualstudio.json b/color-schemes/visualstudio.json deleted file mode 100644 index 5dc86651..00000000 --- a/color-schemes/visualstudio.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name" : "Visual Studio", - "index" : 1400, - "paper" : "white", - "text" : "#111", - "caret" : { - "width" : 2, - "foreground" : "#000000", - "line-background" : "#eee" - }, - "colors" : { - "keyword1" : "blue", - "keyword2" : "blue", - "keyword3" : "#2B91AF", - "comment" : "DarkGreen", - "number" : "DarkRed", - "string" : "#A31515", - "operator" : "Blue", - "commentline" : "DarkGreen", - "selection-foreground" : "black", - "selection-background" : "lightblue", - "margin-background" : "white", - "margin-foreground" : "#2B91AF", - "matched-brace-background" : "darkgrey", - "matched-brace-foreground" : "black", - "unmatched-brace-background" : "red", - "unmatched-brace-foreground" : "#fff", - "error-marker" : "#ff0000", - "edge" : "#ffffff" - } -} From 69b644fcc22e00c2caf51eee89962f016af6c644 Mon Sep 17 00:00:00 2001 From: Frode Lillerud Date: Wed, 17 Dec 2014 22:27:13 +0100 Subject: [PATCH 155/263] Create visualstudio.json --- color-schemes/editor/visualstudio.json | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 color-schemes/editor/visualstudio.json diff --git a/color-schemes/editor/visualstudio.json b/color-schemes/editor/visualstudio.json new file mode 100644 index 00000000..5dc86651 --- /dev/null +++ b/color-schemes/editor/visualstudio.json @@ -0,0 +1,31 @@ +{ + "name" : "Visual Studio", + "index" : 1400, + "paper" : "white", + "text" : "#111", + "caret" : { + "width" : 2, + "foreground" : "#000000", + "line-background" : "#eee" + }, + "colors" : { + "keyword1" : "blue", + "keyword2" : "blue", + "keyword3" : "#2B91AF", + "comment" : "DarkGreen", + "number" : "DarkRed", + "string" : "#A31515", + "operator" : "Blue", + "commentline" : "DarkGreen", + "selection-foreground" : "black", + "selection-background" : "lightblue", + "margin-background" : "white", + "margin-foreground" : "#2B91AF", + "matched-brace-background" : "darkgrey", + "matched-brace-foreground" : "black", + "unmatched-brace-background" : "red", + "unmatched-brace-foreground" : "#fff", + "error-marker" : "#ff0000", + "edge" : "#ffffff" + } +} From 0aa215b90cbe0e3cf28294b5f7fceaecbb442d27 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 19 Dec 2014 02:27:56 -0500 Subject: [PATCH 156/263] Quantize vertices when building Nef polyhedrons from PolySets --- src/cgalutils.cc | 6 ++++-- src/polyset.cc | 15 +++++++++++++++ src/polyset.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index cc8d870f..c1a57e05 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -275,8 +275,10 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) // Since is_convex doesn't work well with non-planar faces, // we tessellate the polyset before checking. - PolySet ps_tri(3); - PolysetUtils::tessellate_faces(ps, ps_tri); + PolySet psq(ps); + psq.quantizeVertices(); + PolySet ps_tri(3); + PolysetUtils::tessellate_faces(psq, ps_tri); if (ps_tri.is_convex()) { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; // Collect point cloud diff --git a/src/polyset.cc b/src/polyset.cc index ad6b6e59..fbfacd31 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -28,6 +28,8 @@ #include "polyset-utils.h" #include "linalg.h" #include "printutils.h" +#include "grid.h" + #include #include @@ -174,6 +176,19 @@ void PolySet::resize(Vector3d newsize, const Eigen::Matrix &autosize) this->transform(t); } +void PolySet::quantizeVertices() +{ + Grid3d grid(GRID_FINE); + BOOST_FOREACH(Polygon &p, this->polygons) { + BOOST_FOREACH(Vector3d &v, p) { + if (!grid.has(v[0], v[1], v[2])) { + // align v to the grid + grid.align(v[0], v[1], v[2]); + } + } + } +} + // all GL functions grouped together here #ifndef NULLGL static void gl_draw_triangle(GLint *shaderinfo, const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, bool e0, bool e1, bool e2, double z, bool mirrored) diff --git a/src/polyset.h b/src/polyset.h index 5701137d..d200bf39 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -27,6 +27,7 @@ public: virtual bool isEmpty() const { return polygons.size() == 0; } virtual Geometry *copy() const { return new PolySet(*this); } + void quantizeVertices(); size_t numPolygons() const { return polygons.size(); } void append_poly(); void append_vertex(double x, double y, double z = 0.0); From d72c121fa696392e5d24a9d022eb6883d1e101bc Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 19 Dec 2014 02:40:17 -0500 Subject: [PATCH 157/263] Minor Grid3 refactoring --- src/cgalutils.cc | 6 +++--- src/grid.h | 35 +++++++++++++---------------------- src/polyset.cc | 6 ++---- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index c1a57e05..d08730cb 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -69,9 +69,9 @@ namespace /* anonymous */ { BOOST_FOREACH(const Polygon &p, ps.polygons) { BOOST_REVERSE_FOREACH(Vector3d v, p) { - if (!grid.has(v[0], v[1], v[2])) { + if (!grid.has(v)) { // align v to the grid; the CGALPoint will receive the aligned vertex - grid.align(v[0], v[1], v[2]) = vertices.size(); + grid.align(v) = vertices.size(); vertices.push_back(CGALPoint(v[0], v[1], v[2])); } } @@ -91,7 +91,7 @@ namespace /* anonymous */ { #endif indices.clear(); BOOST_FOREACH(const Vector3d &v, p) { - indices.push_back(grid.data(v[0], v[1], v[2])); + indices.push_back(grid.data(v)); } // We perform this test since there is a bug in CGAL's diff --git a/src/grid.h b/src/grid.h index 23690b3f..f9fe4d0e 100644 --- a/src/grid.h +++ b/src/grid.h @@ -1,6 +1,8 @@ #pragma once #include "mathc99.h" +#include "linalg.h" + #ifdef WIN32 typedef __int64 int64_t; #else @@ -96,10 +98,10 @@ public: res = resolution; } - T &align(double &x, double &y, double &z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); + T &align(Vector3d &v) { + int64_t ix = (int64_t)round(v[0] / res); + int64_t iy = (int64_t)round(v[1] / res); + int64_t iz = (int64_t)round(v[2] / res); if (db.find(std::make_pair(std::make_pair(ix, iy), iz)) == db.end()) { int dist = 10; for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { @@ -118,14 +120,14 @@ public: } } } - x = ix * res, y = iy * res, z = iz * res; + v[0] = ix * res, v[1] = iy * res, v[2] = iz * res; return db[std::make_pair(std::make_pair(ix, iy), iz)]; } - bool has(double x, double y, double z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); + bool has(const Vector3d &v) { + int64_t ix = (int64_t)round(v[0] / res); + int64_t iy = (int64_t)round(v[1] / res); + int64_t iz = (int64_t)round(v[2] / res); if (db.find(std::make_pair(std::make_pair(ix, iy), iz)) != db.end()) return true; for (int64_t jx = ix - 1; jx <= ix + 1; jx++) @@ -137,19 +139,8 @@ public: return false; } - bool eq(double x1, double y1, double z1, double x2, double y2, double z2) { - align(x1, y1, z1); - align(x2, y2, z2); - if (fabs(x1 - x2) < res && fabs(y1 - y2) < res && fabs(z1 - z2) < res) - return true; - return false; + T &data(Vector3d v) { + return align(v); } - T &data(double x, double y, double z) { - return align(x, y, z); - } - - T &operator()(double x, double y, double z) { - return align(x, y, z); - } }; diff --git a/src/polyset.cc b/src/polyset.cc index fbfacd31..e85dd19b 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -181,10 +181,8 @@ void PolySet::quantizeVertices() Grid3d grid(GRID_FINE); BOOST_FOREACH(Polygon &p, this->polygons) { BOOST_FOREACH(Vector3d &v, p) { - if (!grid.has(v[0], v[1], v[2])) { - // align v to the grid - grid.align(v[0], v[1], v[2]); - } + // align v to the grid + if (!grid.has(v)) grid.align(v); } } } From ad51cadfbd36d3050c219aeda18925e6318e98eb Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 8 Nov 2014 19:37:10 +0100 Subject: [PATCH 158/263] Update offset() parameter handling. - Rounded offset is now using parameter r - Using delta only or delta with camfer = false creates no chamfer - Using delta with chamfer =true creates chamfer at delta distance --- src/offset.cc | 59 ++- src/offsetnode.h | 6 +- src/value.cc | 12 +- src/value.h | 2 + testdata/scad/2D/features/offset-tests.scad | 73 ++-- .../cgalpngtest/offset-tests-expected.png | Bin 9091 -> 4980 bytes .../dumptest-examples/offset-expected.csg | 6 +- .../dumptest/allmodules-expected.csg | 2 +- .../dumptest/offset-tests-expected.csg | 399 +++++++++++++----- .../opencsgtest/offset-tests-expected.png | Bin 7887 -> 3846 bytes .../offset-tests-expected.png | Bin 7929 -> 3869 bytes 11 files changed, 370 insertions(+), 189 deletions(-) diff --git a/src/offset.cc b/src/offset.cc index 08705907..d54da806 100644 --- a/src/offset.cc +++ b/src/offset.cc @@ -54,7 +54,7 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti OffsetNode *node = new OffsetNode(inst); AssignmentList args; - args += Assignment("delta"); + args += Assignment("r"); Context c(ctx); c.setVariables(args, evalctx); @@ -64,30 +64,25 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti node->fs = c.lookup_variable("$fs")->toDouble(); node->fa = c.lookup_variable("$fa")->toDouble(); - ValuePtr delta = c.lookup_variable("delta"); + // default with no argument at all is round / delta = 1 + // radius takes precedence if both r and delta are given. node->delta = 1; - delta->getDouble(node->delta); + node->chamfer = false; + node->join_type = ClipperLib::jtRound; + const ValuePtr r = c.lookup_variable("r", true); + const ValuePtr delta = c.lookup_variable("delta", true); + const ValuePtr chamfer = c.lookup_variable("chamfer", true); - ValuePtr miter_limit = c.lookup_variable("miter_limit", true); - node->miter_limit = 2; - miter_limit->getDouble(node->miter_limit); - - ValuePtr join_type = c.lookup_variable("join_type", true); - if (join_type->type() == Value::STRING) { - std::string jt = join_type->toString(); - if (std::string("bevel") == jt) { - node->join_type = ClipperLib::jtSquare; - } else if (std::string("round") == jt) { - node->join_type = ClipperLib::jtRound; - } else if (std::string("miter") == jt) { - node->join_type = ClipperLib::jtMiter; - } else { - PRINTB("WARNING: Unknown join_type for offset(): '%s'", jt); - } - - if ((node->join_type != ClipperLib::jtMiter) && !miter_limit->isUndefined()) { - PRINTB("WARNING: miter_limit is ignored in offset() for join_type: '%s'", jt); - } + if (r->isDefinedAs(Value::NUMBER)) { + r->getDouble(node->delta); + } else if (delta->isDefinedAs(Value::NUMBER)) { + delta->getDouble(node->delta); + + node->join_type = ClipperLib::jtMiter; + if (chamfer->isDefinedAs(Value::BOOL) && chamfer->toBool()) { + node->chamfer = true; + node->join_type = ClipperLib::jtSquare; + } } std::vector instantiatednodes = inst->instantiateChildren(evalctx); @@ -100,21 +95,17 @@ std::string OffsetNode::toString() const { std::stringstream stream; - stream << this->name() - << "(delta = " << std::dec << this->delta - << ", join_type = \"" - << (this->join_type == ClipperLib::jtSquare - ? "bevel" - : this->join_type == ClipperLib::jtRound - ? "round" - : "miter") << "\""; - if (this->join_type == ClipperLib::jtMiter) { - stream << ", miter_limit = " << this->miter_limit; + bool isRadius = this->join_type == ClipperLib::jtRound; + const char *var = isRadius ? "(r = " : "(delta = "; + + stream << this->name() << var << std::dec << this->delta; + if (!isRadius) { + stream << ", chamfer = " << (this->chamfer ? "true" : "false"); } stream << ", $fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs << ")"; - + return stream.str(); } diff --git a/src/offsetnode.h b/src/offsetnode.h index be651903..d8981fd4 100644 --- a/src/offsetnode.h +++ b/src/offsetnode.h @@ -8,13 +8,15 @@ class OffsetNode : public AbstractPolyNode { public: - OffsetNode(const ModuleInstantiation *mi) : AbstractPolyNode(mi), fn(0), fs(0), fa(0), delta(1), miter_limit(2.0), join_type(ClipperLib::jtMiter) { } + OffsetNode(const ModuleInstantiation *mi) : AbstractPolyNode(mi), fn(0), fs(0), fa(0), delta(1), miter_limit(1000000.0), join_type(ClipperLib::jtRound) { } virtual Response accept(class State &state, Visitor &visitor) const { return visitor.visit(state, *this); } virtual std::string toString() const; virtual std::string name() const { return "offset"; } - double fn, fs, fa, delta, miter_limit; + bool chamfer; + double fn, fs, fa, delta; + double miter_limit; // currently fixed high value to disable chamfers with jtMiter ClipperLib::JoinType join_type; }; diff --git a/src/value.cc b/src/value.cc index d3eea01a..4723b611 100644 --- a/src/value.cc +++ b/src/value.cc @@ -130,9 +130,19 @@ Value::ValueType Value::type() const return static_cast(this->value.which()); } +bool Value::isDefined() const +{ + return this->type() != UNDEFINED; +} + +bool Value::isDefinedAs(const ValueType type) const +{ + return this->type() == type; +} + bool Value::isUndefined() const { - return this->type() == UNDEFINED; + return !isDefined(); } bool Value::toBool() const diff --git a/src/value.h b/src/value.h index e3822309..63b57ce6 100644 --- a/src/value.h +++ b/src/value.h @@ -117,6 +117,8 @@ public: ~Value() {} ValueType type() const; + bool isDefined() const; + bool isDefinedAs(const ValueType type) const; bool isUndefined() const; double toDouble() const; diff --git a/testdata/scad/2D/features/offset-tests.scad b/testdata/scad/2D/features/offset-tests.scad index 06855c64..9148b26a 100644 --- a/testdata/scad/2D/features/offset-tests.scad +++ b/testdata/scad/2D/features/offset-tests.scad @@ -1,46 +1,55 @@ - -module shape1(x, y) { - translate([50 * x, 50 * y]) difference() { - square([30, 30], center = true); - square([8, 8], center = true); - } +module m(x, y) { + translate(60 * [x, y]) children(); } -module shape2(x, y) { - translate([50 * x, 50 * y]) { - polygon(points=[ - [-15, 80],[15, 80],[0,-15],[-8, 60],[8, 60],[0, 5] - ], paths=[ - [0,1,2],[3,4,5] - ]); - } +module shape1(w = 20) { + difference() { + square([ w, w], center = true); + square([10, 10], center = true); + } } -offset(delta = -1, join_type = "miter") shape2(-1, 2); -shape2(0, 2); -offset(delta = 1, join_type = "miter") shape2(1, 2); +module shape2() { + polygon(points=[ + [-15, 80],[15, 80],[0,-15],[-8, 60],[8, 60],[0, 5] + ], paths=[ + [0,1,2],[3,4,5] + ]); +} -offset(delta = -1, join_type = "miter", miter_limit = 10) shape2(2, 2); -offset(delta = 1, join_type = "miter", miter_limit = 10) shape2(3, 2); +m(-1, 0) shape1(); +m(-1, 2) shape2(); -offset(delta = -1, join_type = "bevel") shape2(2, -1); -offset(delta = 1, join_type = "bevel") shape2(3, -1); +m(0, 0) offset() shape1(); +m(0, 1) offset(5) shape1(); +m(0, 2) offset(5) shape2(); -offset(delta = -5, join_type = "round") shape1(-1, 1); -shape1(0, 1); -offset(delta = 5, join_type = "round") shape1(1, 1); +m(1, 0) offset(r = 1) shape1(30); +m(1, 1) offset(r = 5) shape1(30); +m(1, 2) offset(r = 5) shape2(); -offset(-4) shape1(-1, 0); -shape1(0, 0); -offset(4) shape1(1, 0); +m(2, 0) offset(r = -5) shape1(40); +m(2, 1) offset(r = -10.01) shape1(50); +m(2, 2) offset(r = -1) shape2(); -offset(delta = -5) shape1(2, 1); -shape1(0, -1); -offset(delta = 5) shape1(1, -1); +m(3, 0) offset(delta = 4) shape1(); +m(3, 1) offset(delta = 1) shape1(); +m(3, 2) offset(delta = 5) shape2(); + +m(4, 0) offset(delta = -2) shape1(30); +m(4, 1) offset(delta = -5) shape1(40); +m(4, 2) offset(delta = -1) shape2(); + +m(5, 0) offset(delta = 4, chamfer = true) shape1(); +m(5, 1) offset(delta = 1, chamfer = true) shape1(); +m(5, 2) offset(delta = 5, chamfer = true) shape2(); + +m(6, 0) offset(delta = -2, chamfer = true) shape1(30); +m(6, 1) offset(delta = -5, chamfer = true) shape1(40); +m(6, 2) offset(delta = -1, chamfer = true) shape2(); // Bug with fragment calculateion with delta < 1 due to abs() instead of std::abs() -translate([-50,-50]) scale([25,25,1]) - offset(delta = 0.9, join_type="round") square(.1); +m(-2, 1) scale([30, 30]) offset(r = 0.8) square(1); // Malformed offsets offset(); diff --git a/tests/regression/cgalpngtest/offset-tests-expected.png b/tests/regression/cgalpngtest/offset-tests-expected.png index c1f667beaf0edc47fe5b1f76f6c474f164735707..fbcd7248bf689cec8e19ba0c7a47c4dc599965a7 100644 GIT binary patch literal 4980 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 S@K%q;Dljv$GORm;jQS&oj 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 z zO4??AnCI_;US6)z2KiP9&W5i(EgJQ#KWN!p?^nTJ-9B8qy}1*HH+F_*6E@l&Nzpnm zdz)9E)&r>EFby~b?nerbr^k%w;#9J3&gI^r;S-VdMx=MK{ea9VpT2P%6EQNtF2hFB zS@3DuM9fEC!o)lIFoe$ehhvA^0f+NU_yPD67fw7>*A-V1xhStcmqB+y<;U+`HJrca zJhM$%Xu;U|52 z-c6z96Zcm4NLao!YcBzr53AVlQ2>+Y>@+K_eNzNvXdBtReK(%YO-0iYsZx77SEn4w zdy8HU8tqSOX)=+S{Jhln)}Yn(Z_^8VyP>rm$GyV%!xy{iG*tKoP61yHEW1TX zB9AQp-@QdjQQ!oqV!-Xd>zTj(mJY&|BARcJMJI*Z;v&%{uW6Wrgw}tzJ(x}E+ztiZ z6FbT-X*C9scIY;zSniel$7$L?J>aGPQ<`xCXtb8e+BP;e{Y0kX*Om_F`fNmO9j5;D zc_>SJZSP&Yx!2v@t9BjYd`;;qaK5beFL*pBWQwO!mP0`lgM9_c1G;r%ZVOW4(&1Hw z1{QRM4RH>~Ew{{VRPYPtXb diff --git a/tests/regression/dumptest-examples/offset-expected.csg b/tests/regression/dumptest-examples/offset-expected.csg index 41de8cc3..5c640f8e 100644 --- a/tests/regression/dumptest-examples/offset-expected.csg +++ b/tests/regression/dumptest-examples/offset-expected.csg @@ -1,7 +1,7 @@ group() { group(); linear_extrude(height = 20, center = false, convexity = 1, scale = [0.5, 0.5], $fn = 40, $fa = 12, $fs = 2) { - offset(delta = 10, join_type = "round", $fn = 40, $fa = 12, $fs = 2) { + offset(r = 10, $fn = 40, $fa = 12, $fs = 2) { square(size = [50, 50], center = true); } } @@ -9,12 +9,12 @@ group() { linear_extrude(height = 20, center = false, convexity = 1, scale = [1, 1], $fn = 40, $fa = 12, $fs = 2) { group() { difference() { - offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 40, $fa = 12, $fs = 2) { + offset(r = 1, $fn = 40, $fa = 12, $fs = 2) { group() { circle($fn = 40, $fa = 12, $fs = 2, r = 15); } } - offset(delta = -1, join_type = "miter", miter_limit = 2, $fn = 40, $fa = 12, $fs = 2) { + offset(r = -1, $fn = 40, $fa = 12, $fs = 2) { group() { circle($fn = 40, $fa = 12, $fs = 2, r = 15); } diff --git a/tests/regression/dumptest/allmodules-expected.csg b/tests/regression/dumptest/allmodules-expected.csg index 653ca751..9af5da4b 100644 --- a/tests/regression/dumptest/allmodules-expected.csg +++ b/tests/regression/dumptest/allmodules-expected.csg @@ -39,6 +39,6 @@ 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]]); color([-1, -1, -1, 1]); - offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2); + offset(r = 1, $fn = 0, $fa = 12, $fs = 2); text(text = "", size = 10, spacing = 1, font = "", direction = "ltr", language = "en", script = "latin", halign = "left", valign = "baseline", $fn = 0, $fa = 12, $fs = 2); } diff --git a/tests/regression/dumptest/offset-tests-expected.csg b/tests/regression/dumptest/offset-tests-expected.csg index 3f3888ee..39617983 100644 --- a/tests/regression/dumptest/offset-tests-expected.csg +++ b/tests/regression/dumptest/offset-tests-expected.csg @@ -1,144 +1,311 @@ group() { - offset(delta = -1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, -50], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) { - polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); - } - } - } group() { - multmatrix([[1, 0, 0, 0], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) { - polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); - } - } - offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 50], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) { - polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); - } - } - } - offset(delta = -1, join_type = "miter", miter_limit = 10, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 100], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) { - polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); - } - } - } - offset(delta = 1, join_type = "miter", miter_limit = 10, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 150], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) { - polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); - } - } - } - offset(delta = -1, join_type = "bevel", $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 100], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); - } - } - } - offset(delta = 1, join_type = "bevel", $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 150], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); - } - } - } - offset(delta = -5, join_type = "round", $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, -50], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); + multmatrix([[1, 0, 0, -60], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + group() { + difference() { + square(size = [20, 20], center = true); + square(size = [10, 10], center = true); + } } } } } group() { - multmatrix([[1, 0, 0, 0], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); - } - } - } - offset(delta = 5, join_type = "round", $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 50], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); - } - } - } - } - offset(delta = -4, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, -50], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); + multmatrix([[1, 0, 0, -60], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); } } } } group() { multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); - } - } - } - offset(delta = 4, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 50], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); - } - } - } - } - offset(delta = -5, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 100], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); + group() { + offset(r = 1, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [20, 20], center = true); + square(size = [10, 10], center = true); + } + } } } } } group() { - multmatrix([[1, 0, 0, 0], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); - } - } - } - offset(delta = 5, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { - group() { - multmatrix([[1, 0, 0, 50], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - difference() { - square(size = [30, 30], center = true); - square(size = [8, 8], center = true); + multmatrix([[1, 0, 0, 0], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = 5, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [20, 20], center = true); + square(size = [10, 10], center = true); + } + } } } } } - multmatrix([[1, 0, 0, -50], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) { - multmatrix([[25, 0, 0, 0], [0, 25, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { - offset(delta = 0.9, join_type = "round", $fn = 0, $fa = 12, $fs = 2) { - square(size = [0.1, 0.1], center = false); + group() { + multmatrix([[1, 0, 0, 0], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = 5, $fn = 0, $fa = 12, $fs = 2) { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); + } + } } } } - offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2); - offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) { + group() { + multmatrix([[1, 0, 0, 60], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = 1, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [30, 30], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 60], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = 5, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [30, 30], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 60], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = 5, $fn = 0, $fa = 12, $fs = 2) { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 120], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = -5, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [40, 40], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 120], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = -10.01, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [50, 50], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 120], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(r = -1, $fn = 0, $fa = 12, $fs = 2) { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 180], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = 4, chamfer = false, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [20, 20], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 180], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = 1, chamfer = false, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [20, 20], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 180], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = 5, chamfer = false, $fn = 0, $fa = 12, $fs = 2) { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 240], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = -2, chamfer = false, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [30, 30], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 240], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = -5, chamfer = false, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [40, 40], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 240], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = -1, chamfer = false, $fn = 0, $fa = 12, $fs = 2) { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 300], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = 4, chamfer = true, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [20, 20], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 300], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = 1, chamfer = true, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [20, 20], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 300], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = 5, chamfer = true, $fn = 0, $fa = 12, $fs = 2) { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 360], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = -2, chamfer = true, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [30, 30], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 360], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = -5, chamfer = true, $fn = 0, $fa = 12, $fs = 2) { + group() { + difference() { + square(size = [40, 40], center = true); + square(size = [10, 10], center = true); + } + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, 360], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + offset(delta = -1, chamfer = true, $fn = 0, $fa = 12, $fs = 2) { + group() { + polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1); + } + } + } + } + } + group() { + multmatrix([[1, 0, 0, -120], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + group() { + multmatrix([[30, 0, 0, 0], [0, 30, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + offset(r = 0.8, $fn = 0, $fa = 12, $fs = 2) { + square(size = [1, 1], center = false); + } + } + } + } + } + offset(r = 1, $fn = 0, $fa = 12, $fs = 2); + offset(r = 1, $fn = 0, $fa = 12, $fs = 2) { square(size = [0, 0], center = false); } } diff --git a/tests/regression/opencsgtest/offset-tests-expected.png b/tests/regression/opencsgtest/offset-tests-expected.png index ea7eee890e85152705157721bef9d3fa78d80389..a671a091157ece2f191656d428ef75897c81b47c 100644 GIT binary patch literal 3846 zcmds4c{r8p7GK}qwt3vdHg8kNkV2V& zmtyG`aa>&MnU#y(9M+0vuA@??g%NUr)M@ReQ89h;;f2`Nt4Wz5{0w$~ypbYT;BeMr zsbQC2*O?REK3_R`dM{kb%?r4oNqA(nnq;o!+0>5TDsp%{%}nmu17Za}aQUv>h#Icr zHqZVJaYVtg5D-eS#AxTJ$ExW)B^97K^hb)l%ewWL-$vx}0`Vz6Zi2Mh@(;$4B@0vlmihYCaq6-mXn zav!s#_6x<2ozG<_hEsf zZ*b%fdB63>s#8%@0{UdW&)Rm8KN-(N28ebcld5xb{Zy`nw9;JxJ5rNtq`SNaW( zk9-XdZDmxcgdnT)Ej2=gLWg0kWO-RZaGnfl^}Tdm{qd~E_W6!w90zPrK6}i3S>gAw z*=9D6mEoHgbEe9sGqBvb*mzY5@n=>B;lRA#Ptb&_K#j&yY)N1+^zq?s+L^M z9-`+V1Q_WGsJN@Qn8UVEVlRj3)ZQxtPI-J0I5g7OpbSwjjgnnmYe`Z>CHV@tA=wlW zi<{`)e9}!sEfrAp<1N8{o>xb*sY3U0BwVz=z@Xh+`wNnrcB1nUP~$D6NP9HUcDXpQ zQ_`$N4_dC@rf-_mw1vfsY=mv{ODdpS0pj?FdL0r3UTEbr;u0{*(Ubqo3X}+(ma_GG z-2)S$Co}q_@~3t@1xn`gM^ARdd`Ka=>E(W}SAZxhS`m|sOY_WVO^IUR6c2VvBbD>5Hzy3H zL+x=dHaKhtEVM9W@fL1X`E9dqt%Zglx?cf~M;_O<8mEizb{Cgf&?t;5TxP)tHxvoF zEEnU!+onuv-q><#8F*!&hz7GeondMd_A^0(I$lK^o^`>gnQY(9+z?W0esnpe<2vQ^ zb(%dCa)T5P> zLV7kASySUFS>Z`N(kj<;eI8pT_3LH3AVqpNC(fmap0Cft!!JHusf9CkE1J1+H7#X( z@o02l&uORrvRFMcAq5U0qeP$kH?BDsU+CW&zBt4;l~D)@+4is|daNvM&4>+Io8cgL zoaGYO;YJ=xXD}wr0??aYz=49! zj*t7h5-Mey(of-Nf|Fsp4dr!4XcSs;ilG)U9Mgy_o^(cr-s2113eg!8S%H7;Bkt2iaRXs1iGp)xUd15CDBQk z|Lt|c=&uQ7uFoH;R|-}X?`U+Qhe}N3M_Y?|jtaczyz!(bTG+>Lg=TPHyuf|9K&MC2 z1y?E!s_orAlOu~7L1k%XSCQm%(f5juzG!afJ7g0+CKD3B9CUit$1PWa9sU?e=A>5z zAN^X?8|`me?d!1+Y~2}nXKvYANvq~r>-&wJ9DtH^nW_Dpyg;+=7h(-%g8k=Q>#i|@ zk$vnW4wXzOtGeNwNOb9=6n*ItZ~@q}Ey8HXIf&Sei?|qqu5~8?cn@N1EQPDWs~%t{3r8lRgK`x7sDxg z)mN;i%pL=2&|QAiokO%!r|O#RyiD~ktrrBr)KT7Aq+InAnpzTbIWtW(aBE}ZJbfVC z_RUWNQ*B3o*6DcL{d3vJ)M-D$^G{dP^BR!(echSj*$(LV2Np&@`KEukbiqH8d$q}v zv)>mMGT(LiD|VKzKWfI!_i93Fz99aYA>-%@1hB^O1N$wAsr&Te50?Cu{@%jBIDmlwl&Vxx*HO? zl6Kmr){m8FrbfK%!H+ym4d{?G>{>adA7p1X_ik4F z%aXP0)jL*8IY`&{(oC}h>$i&6Mr77LzzXM3O>K2*3JqY*o&;*I>%v7+cs@Dp%1RP zpI>5ezR{Cdan?V>?AS+lkQ6hWh;}>XwFCjhAw1OnwHn*n7fd6A@e^oLz<@E#8Kkj)GWvj_e3YsxJ(zOXJ@Z1F$23Yrk9O9{=fLeT2MP2 z@M5q2Kal_53A?Z1=kHYN>;yp1kj94n^=D2om_SeJZ_w$p{ri}bkG!bV;l+l&?HNZu lW-!qNlKKBu!_5!Kc!wenZfVUCc5I#li$gXh`3ERr{{$L-aZvyO literal 7887 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 A)&Kwi From b1871c630921494a6aaf56f1288cd72729a0db02 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 02:51:11 +0100 Subject: [PATCH 159/263] Fix color schemes (brace highlight / selection color / line-end markers). --- color-schemes/editor/dark-background.json | 40 +++++++++++++--------- color-schemes/editor/light-background.json | 16 ++++++--- color-schemes/editor/monokai.json | 38 +++++++++++--------- color-schemes/editor/solarized-dark.json | 37 ++++++++++++++++++++ color-schemes/editor/solarized-light.json | 37 ++++++++++++++++++++ color-schemes/editor/solarized.json | 31 ----------------- color-schemes/editor/visualstudio.json | 16 ++++++--- src/scintillaeditor.cpp | 14 +++++++- 8 files changed, 154 insertions(+), 75 deletions(-) create mode 100644 color-schemes/editor/solarized-dark.json create mode 100644 color-schemes/editor/solarized-light.json delete mode 100644 color-schemes/editor/solarized.json diff --git a/color-schemes/editor/dark-background.json b/color-schemes/editor/dark-background.json index c9fc3e01..7ae0857e 100644 --- a/color-schemes/editor/dark-background.json +++ b/color-schemes/editor/dark-background.json @@ -1,31 +1,37 @@ { "name" : "For Dark Background", "index" : 1100, - "paper" : "#272822", - "text" : "#ffffff", + "paper" : "#222222", + "text" : "#e0e0e0", "caret" : { "width" : 2, "foreground" : "#ffff00", - "line-background" : "#68e1687f" + "line-background" : "#303030" }, "colors" : { - "keyword1" : "#f12971", + "keyword1" : "#90ee90", "keyword2" : "#56dbf0", - "keyword3" : "#56d8f0", - "comment" : "#ccdf32", - "number" : "#af7dff", + "keyword3" : "#add8e6", + "comment" : "#808080", + "commentline" : "#808080", + "commentdoc" : "#808080", + "commentdockeyword" : "#808080", + "number" : "#ff0000", "string" : "#e6db74", - "operator" : "#d8d8d8", - "commentline" : "#e6db74", - "selection-foreground" : "#ffff00", - "selection-background" : "#a0a0ff", - "margin-background" : "#14141496", - "margin-foreground" : "#fff", - "matched-brace-background" : "#333", - "matched-brace-foreground" : "#fff", - "unmatched-brace-background" : "#333", - "unmatched-brace-foreground" : "#fff", + "operator" : "#e8b609", + "whitespace-background" : "#222222", + "whitespace-foreground" : "#e0e0e0", + "selection-foreground" : "#ffffff", + "selection-background" : "#4a90d9", + "margin-background" : "#272822", + "margin-foreground" : "#e0e0e0", + "matched-brace-background" : "#505050", + "matched-brace-foreground" : "#ffffff", + "unmatched-brace-background" : "#dc322f", + "unmatched-brace-foreground" : "#fdf6e3", "error-marker" : "#ff0000", + "error-indicator" : "#60ff0000", + "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 35471b50..535834aa 100644 --- a/color-schemes/editor/light-background.json +++ b/color-schemes/editor/light-background.json @@ -1,24 +1,28 @@ { "name" : "For Light Background", "index" : 1000, - "paper" : "#fff", + "paper" : "#ffffff", "text" : "#272822", "caret" : { "width" : 2, "foreground" : "#000000", - "line-background" : "#ffe4e4" + "line-background" : "#f0f0f0" }, "colors" : { "keyword1" : "Green", "keyword2" : "Green", "keyword3" : "DarkBlue", "comment" : "DarkCyan", + "commentline" : "DarkCyan", + "commentdoc" : "DarkCyan", + "commentdockeyword" : "DarkCyan", "number" : "DarkRed", "string" : "DarkMagenta", "operator" : "Blue", - "commentline" : "DarkCyan", - "selection-foreground" : "#ffff00", - "selection-background" : "#a0a0ff", + "whitespace-background" : "#ffffff", + "whitespace-foreground" : "#272822", + "selection-foreground" : "#ffffff", + "selection-background" : "#4a90d9", "margin-background" : "#ccc", "margin-foreground" : "#111", "matched-brace-background" : "#333", @@ -26,6 +30,8 @@ "unmatched-brace-background" : "#333", "unmatched-brace-foreground" : "#fff", "error-marker" : "#ff0000", + "error-indicator" : "#60ff0000", + "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 17bf8f9a..1d6f1b5e 100644 --- a/color-schemes/editor/monokai.json +++ b/color-schemes/editor/monokai.json @@ -5,27 +5,33 @@ "text" : "#f8f8f2", "caret" : { "width" : 2, - "foreground" : "#ffff00", - "line-background" : "#3e3d32" + "foreground" : "#f8f8f0", + "line-background" : "#49483e" }, "colors" : { - "keyword1" : "#66c3b3", - "keyword2" : "#79abff", - "keyword3" : "#ffffff", - "comment" : "#ccdf32", - "number" : "#7fb347", - "string" : "#e6db74", - "operator" : "#d8d8d8", + "keyword1" : "#66d9ef", + "keyword2" : "#a6e22e", + "keyword3" : "#f92672", + "comment" : "#75715e", "commentline" : "#75715e", - "selection-foreground" : "#ffff00", - "selection-background" : "#a0a0ff", - "margin-background" : "#757575", + "commentdoc" : "#75715e", + "commentdockeyword" : "#7b9a3c", + "number" : "#ae81ff", + "string" : "#e6db74", + "operator" : "#f92672", + "whitespace-background" : "#272822", + "whitespace-foreground" : "#f8f8f2", + "selection-foreground" : "#272822", + "selection-background" : "#f8f8f2", + "margin-background" : "#3e3d32", "margin-foreground" : "#f8f8f2", - "matched-brace-background" : "#333", - "matched-brace-foreground" : "#fff", - "unmatched-brace-background" : "#333", - "unmatched-brace-foreground" : "#fff", + "matched-brace-background" : "#606060", + "matched-brace-foreground" : "#f8f8f2", + "unmatched-brace-background" : "#dc322f", + "unmatched-brace-foreground" : "#f8f8f2", "error-marker" : "#ff0000", + "error-indicator" : "#80ffe0e0", + "error-indicator-outline" : "#ff000000", "edge" : "#ffffff" } } \ No newline at end of file diff --git a/color-schemes/editor/solarized-dark.json b/color-schemes/editor/solarized-dark.json new file mode 100644 index 00000000..b73eff19 --- /dev/null +++ b/color-schemes/editor/solarized-dark.json @@ -0,0 +1,37 @@ +{ + "name" : "Solarized (dark)", + "index" : 1310, + "paper" : "#002b36", + "text" : "#839496", + "caret" : { + "width" : 2, + "foreground" : "#fff070", + "line-background" : "#073642" + }, + "colors" : { + "keyword1" : "#268ad1", + "keyword2" : "#2aa198", + "keyword3" : "#859900", + "comment" : "#657b83", + "commentline" : "#657b83", + "commentdoc" : "#657b83", + "commentdockeyword" : "#6c71c4", + "number" : "#d33682", + "string" : "#b58900", + "operator" : "#cb4b16", + "whitespace-background" : "#002b36", + "whitespace-foreground" : "#839496", + "selection-foreground" : "#fdf6e3", + "selection-background" : "#657b83", + "margin-background" : "#002b36", + "margin-foreground" : "#839496", + "matched-brace-background" : "#93a1a1", + "matched-brace-foreground" : "#586e75", + "unmatched-brace-background" : "#dc322f", + "unmatched-brace-foreground" : "#fdf6e3", + "error-marker" : "#ff0000", + "error-indicator" : "#90ff8080", + "error-indicator-outline" : "#ff000000", + "edge" : "#d33682" + } +} \ No newline at end of file diff --git a/color-schemes/editor/solarized-light.json b/color-schemes/editor/solarized-light.json new file mode 100644 index 00000000..4033e509 --- /dev/null +++ b/color-schemes/editor/solarized-light.json @@ -0,0 +1,37 @@ +{ + "name" : "Solarized (light)", + "index" : 1300, + "paper" : "#fdf6e3", + "text" : "#657b83", + "caret" : { + "width" : 2, + "foreground" : "#000000", + "line-background" : "#eee8d5" + }, + "colors" : { + "keyword1" : "#268ad1", + "keyword2" : "#2aa198", + "keyword3" : "#859900", + "comment" : "#93a1a1", + "commentline" : "#93a1a1", + "commentdoc" : "#93a1a1", + "commentdockeyword" : "#6c71c4", + "number" : "#d33682", + "string" : "#b58900", + "operator" : "#cb4b16", + "whitespace-background" : "#fdf6e3", + "whitespace-foreground" : "#657b83", + "selection-foreground" : "#fdf6e3", + "selection-background" : "#657b83", + "margin-background" : "#eee8d5", + "margin-foreground" : "#657b83", + "matched-brace-background" : "#93a1a1", + "matched-brace-foreground" : "#586e75", + "unmatched-brace-background" : "#ed8987", + "unmatched-brace-foreground" : "#fdf6e3", + "error-marker" : "#ff0000", + "error-indicator" : "#80ff0000", + "error-indicator-outline" : "#ff000000", + "edge" : "#d33682" + } +} \ No newline at end of file diff --git a/color-schemes/editor/solarized.json b/color-schemes/editor/solarized.json deleted file mode 100644 index c9ee3dd3..00000000 --- a/color-schemes/editor/solarized.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name" : "Solarized", - "index" : 1300, - "paper" : "#fdf6e3", - "text" : "#657b83", - "caret" : { - "width" : 2, - "foreground" : "#0000ff", - "line-background" : "#eeead5" - }, - "colors" : { - "keyword1" : "#268ad1", - "keyword2" : "#6c71c4", - "keyword3" : "#b58800", - "comment" : "#b58900", - "number" : "#cb4b16", - "string" : "#2aa198", - "operator" : "#859900", - "commentline" : "#b58800", - "selection-foreground" : "#fdf6e3", - "selection-background" : "#657b83", - "margin-background" : "#eee8d5", - "margin-foreground" : "#93a1a1", - "matched-brace-background" : "#333", - "matched-brace-foreground" : "#fff", - "unmatched-brace-background" : "#333", - "unmatched-brace-foreground" : "#fff", - "error-marker" : "#ff0000", - "edge" : "#ffffff" - } -} \ No newline at end of file diff --git a/color-schemes/editor/visualstudio.json b/color-schemes/editor/visualstudio.json index 5dc86651..3f797596 100644 --- a/color-schemes/editor/visualstudio.json +++ b/color-schemes/editor/visualstudio.json @@ -1,22 +1,26 @@ { "name" : "Visual Studio", "index" : 1400, - "paper" : "white", - "text" : "#111", + "paper" : "#ffffff", + "text" : "#101010", "caret" : { "width" : 2, "foreground" : "#000000", - "line-background" : "#eee" + "line-background" : "#eeeeee" }, "colors" : { "keyword1" : "blue", "keyword2" : "blue", "keyword3" : "#2B91AF", "comment" : "DarkGreen", + "commentline" : "DarkGreen", + "commentdoc" : "#DarkGreen", + "commentdockeyword" : "#DarkGreen", "number" : "DarkRed", "string" : "#A31515", "operator" : "Blue", - "commentline" : "DarkGreen", + "whitespace-background" : "#ffffff", + "whitespace-foreground" : "#101010", "selection-foreground" : "black", "selection-background" : "lightblue", "margin-background" : "white", @@ -24,8 +28,10 @@ "matched-brace-background" : "darkgrey", "matched-brace-foreground" : "black", "unmatched-brace-background" : "red", - "unmatched-brace-foreground" : "#fff", + "unmatched-brace-foreground" : "#ffffff", "error-marker" : "#ff0000", + "error-indicator" : "#60ff0000", + "error-indicator-outline" : "#ff000000", "edge" : "#ffffff" } } diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index efc80d90..0612ef9d 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -175,11 +175,15 @@ void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme) lexer->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword); lexer->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2); lexer->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass); - lexer->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::CommentDocKeyword); lexer->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number); + lexer->setColor(readColor(colors, "string", textColor), QsciLexerCPP::SingleQuotedString); lexer->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString); lexer->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator); + lexer->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::Comment); lexer->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine); + lexer->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentDoc); + lexer->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentLineDoc); + lexer->setColor(readColor(colors, "commentdockeyword", textColor), QsciLexerCPP::CommentDocKeyword); const boost::property_tree::ptree& caret = pt.get_child("caret"); @@ -188,6 +192,10 @@ void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme) qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor)); qsci->setMarkerBackgroundColor(readColor(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber); + qsci->setIndicatorForegroundColor(readColor(colors, "error-indicator", QColor(255, 0, 0, 100)), indicatorNumber); + qsci->setIndicatorOutlineColor(readColor(colors, "error-indicator-outline", QColor(255, 0, 0, 100)), indicatorNumber); + qsci->setWhitespaceBackgroundColor(readColor(colors, "whitespace-background", paperColor)); + qsci->setWhitespaceForegroundColor(readColor(colors, "whitespace-foreground", textColor)); qsci->setMarginsBackgroundColor(readColor(colors, "margin-background", paperColor)); qsci->setMarginsForegroundColor(readColor(colors, "margin-foreground", textColor)); qsci->setMatchedBraceBackgroundColor(readColor(colors, "matched-brace-background", paperColor)); @@ -211,7 +219,11 @@ void ScintillaEditor::noColor() qsci->setCaretWidth(2); qsci->setCaretForegroundColor(Qt::black); qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber); + qsci->setIndicatorForegroundColor(QColor(255, 0, 0, 128), indicatorNumber); + qsci->setIndicatorOutlineColor(QColor(0, 0, 0, 255), indicatorNumber); // only alpha part is used qsci->setCaretLineBackgroundColor(Qt::white); + qsci->setWhitespaceBackgroundColor(Qt::white); + qsci->setWhitespaceForegroundColor(Qt::black); qsci->setMarginsBackgroundColor(Qt::white); qsci->setMarginsForegroundColor(Qt::black); qsci->setSelectionForegroundColor(Qt::white); From 90b7dd82c20d089b3c4984168e686399bc6c78df Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 04:46:59 +0100 Subject: [PATCH 160/263] Update lexer keywords. --- src/scadlexer.cpp | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/scadlexer.cpp b/src/scadlexer.cpp index ff774dff..cb04d2c7 100644 --- a/src/scadlexer.cpp +++ b/src/scadlexer.cpp @@ -14,25 +14,34 @@ const char *ScadLexer::language() const const char *ScadLexer::keywords(int set) const { + if (set == 1) { + // -> Style: Keyword (lexer.l / primitives.cc) + return "if else let for module function true false undef " + "cube sphere cylinder polyhedron square circle polygon text " + "include use"; + } - if (set == 1) - return "if else for module function intersection_for assign echo search " - " str let true false "; // -> Style: Keyword + if (set == 2) { + // -> Style: KeywordSet2 (func.cc) + return "abs sign rands min max sin cos asin acos tan atan atan2 " + "round ceil floor pow sqrt exp len log ln str chr concat " + "lookup search version version_num norm cross parent_module " + "dxf_dim dxf_cross"; + } - if (set == 2) - return " abs sign acos asin atan atan2 sin cos tan floor round ceil len ln " - " log lookup min max pow sqrt exp rands version version_num " - " group difference union intersection render translate rotate scale multmatrix color " - " projection hull resize mirror minkowski glide subdiv child " - " include use dxf_dim dxf_cross " - " linear_extrude rotate_extrude "; // -> Style: KeywordSet2 + if (set == 3) { + // -> used in comments only like /*! \cube */ + return "struct union enum fn var def typedef file namespace package " + "interface param see return class brief"; + } - if (set == 3) - return " param author "; // -> used in comments only like /*! \cube */ - - if (set == 4) - return "cube circle cylinder polygon polyhedron square sphere " - "surface import "; // -> Style: GlobalClass + if (set == 4) { + // -> Style: GlobalClass + return "minkowski hull resize child echo union difference " + "intersection linear_extrude rotate_extrude import group " + "projection render surface scale rotate mirror translate " + "multmatrix color offset "; + } return 0; } From 128498a6786fb9ca193006a79453347b8f876c8b Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 17:27:18 +0100 Subject: [PATCH 161/263] Allow reading the keyword lists from the color scheme files. --- src/scadlexer.cpp | 86 ++++++++++++++++++++++++----------------- src/scadlexer.h | 4 +- src/scintillaeditor.cpp | 66 +++++++++++++++++++++---------- src/scintillaeditor.h | 1 + 4 files changed, 100 insertions(+), 57 deletions(-) diff --git a/src/scadlexer.cpp b/src/scadlexer.cpp index cb04d2c7..9fc2d4d3 100644 --- a/src/scadlexer.cpp +++ b/src/scadlexer.cpp @@ -1,47 +1,63 @@ +#include + #include "scadlexer.h" -ScadLexer::ScadLexer(QObject *parent) - : QsciLexerCPP(parent) -{ } +ScadLexer::ScadLexer(QObject *parent) : QsciLexerCPP(parent) +{ + // -> Style: Keyword (lexer.l) + keywordSet[0] = + "if else let for module function true false undef " + "include use"; + + // -> Style: KeywordSet2 (func.cc) + keywordSet[1] = + "abs sign rands min max sin cos asin acos tan atan atan2 " + "round ceil floor pow sqrt exp len log ln str chr concat " + "lookup search version version_num norm cross parent_module " + "dxf_dim dxf_cross"; + + // -> used in comments only like /*! \cube */ + keywordSet[2] = + "struct union enum fn var def typedef file namespace package " + "interface param see return class brief"; + + // -> Style: GlobalClass + keywordSet[3] = + "cube sphere cylinder polyhedron square circle polygon text " + "minkowski hull resize child echo union difference " + "intersection linear_extrude rotate_extrude import group " + "projection render surface scale rotate mirror translate " + "multmatrix color offset "; +} ScadLexer::~ScadLexer() -{ } +{ +} const char *ScadLexer::language() const { - return "SCAD"; + return "SCAD"; +} + +void ScadLexer::setKeywords(int set, const std::string& keywords) +{ + if ((set < 1) || (set > 4)) { + return; + } + + std::string trimmedKeywords(keywords); + boost::algorithm::trim(trimmedKeywords); + if (trimmedKeywords.empty()) { + return; + } + + keywordSet[set - 1] = trimmedKeywords; } const char *ScadLexer::keywords(int set) const { - if (set == 1) { - // -> Style: Keyword (lexer.l / primitives.cc) - return "if else let for module function true false undef " - "cube sphere cylinder polyhedron square circle polygon text " - "include use"; - } - - if (set == 2) { - // -> Style: KeywordSet2 (func.cc) - return "abs sign rands min max sin cos asin acos tan atan atan2 " - "round ceil floor pow sqrt exp len log ln str chr concat " - "lookup search version version_num norm cross parent_module " - "dxf_dim dxf_cross"; - } - - if (set == 3) { - // -> used in comments only like /*! \cube */ - return "struct union enum fn var def typedef file namespace package " - "interface param see return class brief"; - } - - if (set == 4) { - // -> Style: GlobalClass - return "minkowski hull resize child echo union difference " - "intersection linear_extrude rotate_extrude import group " - "projection render surface scale rotate mirror translate " - "multmatrix color offset "; - } - - return 0; + if ((set < 1) || (set > 4)) { + return 0; + } + return keywordSet[set - 1].c_str(); } diff --git a/src/scadlexer.h b/src/scadlexer.h index 50e6347a..b6a349d7 100644 --- a/src/scadlexer.h +++ b/src/scadlexer.h @@ -12,8 +12,10 @@ public: virtual ~ScadLexer(); const char *language() const; const char *keywords(int set) const; - + + void setKeywords(int set, const std::string& keywords); private: + std::string keywordSet[4]; ScadLexer(const ScadLexer &); ScadLexer &operator=(const ScadLexer &); }; diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 0612ef9d..2d0f07d0 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -89,7 +89,7 @@ ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent) qsci->setIndentationsUseTabs(false); lexer = new ScadLexer(this); - initLexer(); + qsci->setLexer(lexer); initMargin(); qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4); qsci->setCaretLineVisible(true); @@ -150,6 +150,16 @@ QColor ScintillaEditor::readColor(const boost::property_tree::ptree &pt, const s } } +std::string ScintillaEditor::readString(const boost::property_tree::ptree &pt, const std::string name, const std::string defaultValue) +{ + try { + const std::string val = pt.get(name); + return val; + } catch (std::exception e) { + return defaultValue; + } +} + int ScintillaEditor::readInt(const boost::property_tree::ptree &pt, const std::string name, const int defaultValue) { try { @@ -165,28 +175,47 @@ void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme) const boost::property_tree::ptree & pt = colorScheme->propertyTree(); try { + QFont font = lexer->font(lexer->defaultStyle()); const QColor textColor(pt.get("text").c_str()); const QColor paperColor(pt.get("paper").c_str()); - lexer->setColor(textColor); - lexer->setPaper(paperColor); + ScadLexer *l = new ScadLexer(this); + + // Keywords must be set before the lexer is attached to QScintilla + // as they seem to be read and cached at attach time. + boost::optional keywords = pt.get_child_optional("keywords"); + if (keywords.is_initialized()) { + l->setKeywords(1, readString(keywords.get(), "keyword-set1", "")); + l->setKeywords(2, readString(keywords.get(), "keyword-set2", "")); + l->setKeywords(3, readString(keywords.get(), "keyword-set-doc", "")); + l->setKeywords(4, readString(keywords.get(), "keyword-set3", "")); + } + + qsci->setLexer(l); + delete lexer; + lexer = l; + + // All other properties must be set after attaching to QSCintilla so + // the editor gets the change events and updates itself to match + l->setFont(font); + l->setColor(textColor); + l->setPaper(paperColor); const boost::property_tree::ptree& colors = pt.get_child("colors"); - lexer->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword); - lexer->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2); - lexer->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass); - lexer->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number); - lexer->setColor(readColor(colors, "string", textColor), QsciLexerCPP::SingleQuotedString); - lexer->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString); - lexer->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator); - lexer->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::Comment); - lexer->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine); - lexer->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentDoc); - lexer->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentLineDoc); - lexer->setColor(readColor(colors, "commentdockeyword", textColor), QsciLexerCPP::CommentDocKeyword); + l->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword); + l->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2); + l->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass); + l->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number); + l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::SingleQuotedString); + l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString); + l->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator); + l->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::Comment); + l->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine); + l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentDoc); + l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentLineDoc); + l->setColor(readColor(colors, "commentdockeyword", textColor), QsciLexerCPP::CommentDocKeyword); const boost::property_tree::ptree& caret = pt.get_child("caret"); - qsci->setCaretWidth(readInt(caret, "width", 1)); qsci->setCaretForegroundColor(readColor(caret, "foreground", textColor)); qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor)); @@ -356,11 +385,6 @@ void ScintillaEditor::initFont(const QString& fontName, uint size) lexer->setFont(font); } -void ScintillaEditor::initLexer() -{ - qsci->setLexer(lexer); -} - void ScintillaEditor::initMargin() { QFontMetrics fontmetrics = QFontMetrics(qsci->font()); diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h index 3b582ea6..42fcd274 100644 --- a/src/scintillaeditor.h +++ b/src/scintillaeditor.h @@ -58,6 +58,7 @@ private: void getRange(int *lineFrom, int *lineTo); void setColormap(const EditorColorScheme *colorScheme); int readInt(const boost::property_tree::ptree &pt, const std::string name, const int defaultValue); + std::string readString(const boost::property_tree::ptree &pt, const std::string name, const std::string defaultValue); QColor readColor(const boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor); void enumerateColorSchemesInPath(colorscheme_set_t &result_set, const fs::path path); colorscheme_set_t enumerateColorSchemes(); From a603afb767b428eecf41e3478721e6bf10d75097 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 17:27:34 +0100 Subject: [PATCH 162/263] Add keyword lists. --- color-schemes/editor/visualstudio.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/color-schemes/editor/visualstudio.json b/color-schemes/editor/visualstudio.json index 3f797596..aeab6b70 100644 --- a/color-schemes/editor/visualstudio.json +++ b/color-schemes/editor/visualstudio.json @@ -33,5 +33,10 @@ "error-indicator" : "#60ff0000", "error-indicator-outline" : "#ff000000", "edge" : "#ffffff" + }, + "keywords" : { + "keyword-set1" : "if else let for module function true false undef include use", + "keyword-set2" : "abs sign rands min max sin cos asin acos tan atan atan2 round ceil floor pow sqrt exp len log ln str chr concat lookup search version version_num norm cross parent_module dxf_dim dxf_cross", + "keyword-set3" : "cube sphere cylinder polyhedron square circle polygon text minkowski hull resize child echo union difference intersection linear_extrude rotate_extrude import group projection render surface scale rotate mirror translate multmatrix color offset" } } From b488242548d48e0f93aa9b8eb5a66efae1900c63 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 17:30:37 +0100 Subject: [PATCH 163/263] Swap colors so the bright red is only used for language keywords. --- color-schemes/editor/monokai.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/color-schemes/editor/monokai.json b/color-schemes/editor/monokai.json index 1d6f1b5e..4e072594 100644 --- a/color-schemes/editor/monokai.json +++ b/color-schemes/editor/monokai.json @@ -9,16 +9,16 @@ "line-background" : "#49483e" }, "colors" : { - "keyword1" : "#66d9ef", + "keyword1" : "#f92672", "keyword2" : "#a6e22e", - "keyword3" : "#f92672", + "keyword3" : "#66d9ef", "comment" : "#75715e", "commentline" : "#75715e", "commentdoc" : "#75715e", "commentdockeyword" : "#7b9a3c", "number" : "#ae81ff", "string" : "#e6db74", - "operator" : "#f92672", + "operator" : "#f8f8f2", "whitespace-background" : "#272822", "whitespace-foreground" : "#f8f8f2", "selection-foreground" : "#272822", From ba2f150f336a045e3feea9ccb2b31d01882e0395 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 21:38:52 +0100 Subject: [PATCH 164/263] Remove eigen2 detection, eigen3 is required. --- eigen.pri | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/eigen.pri b/eigen.pri index 79f0a5f0..03315ff5 100644 --- a/eigen.pri +++ b/eigen.pri @@ -1,18 +1,14 @@ -# Detect eigen3 + eigen2, then use this priority list to determine -# which eigen to use: +# Detect eigen3 # # Priority -# 0. EIGENDIR if set (also EIGEN2DIR for backwards compatability) +# 0. EIGENDIR if set # 1. OPENSCAD_LIBRARIES eigen3 -# 2. OPENSCAD_LIBRARIES eigen2 # 3. system's standard include paths for eigen3 -# 4. system's standard include paths for eigen2 eigen { # read environment variables OPENSCAD_LIBRARIES_DIR = $$(OPENSCAD_LIBRARIES) -EIGEN2_DIR = $$(EIGEN2DIR) EIGEN_DIR = $$(EIGENDIR) # Optionally specify location of Eigen3 using the @@ -23,20 +19,8 @@ EIGEN_DIR = $$(EIGENDIR) EIGEN_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/eigen3 } } - isEmpty(EIGEN_INCLUDEPATH) { - exists($$OPENSCAD_LIBRARIES_DIR/include/eigen2) { - EIGEN_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/eigen2 - } - } } - -# Optionally specify location of Eigen using the -# EIGENDIR env. variable (EIGEN2 for backwards compatability) -!isEmpty(EIGEN2_DIR) { - EIGEN_INCLUDEPATH = $$EIGEN2_DIR - message("User set EIGEN location: $$EIGEN_INCLUDEPATH") -} !isEmpty(EIGEN_DIR) { EIGEN_INCLUDEPATH = $$EIGEN_DIR message("User set EIGEN location: $$EIGEN_INCLUDEPATH") @@ -47,17 +31,6 @@ isEmpty(EIGEN_INCLUDEPATH) { freebsd-g++: EIGEN_INCLUDEPATH = /usr/local/include/eigen3 netbsd*: EIGEN_INCLUDEPATH = /usr/pkg/include/eigen3 macx: EIGEN_INCLUDEPATH = /opt/local/include/eigen3 - !exists($$EIGEN_INCLUDEPATH) { - linux*|hurd*|unix*: EIGEN_INCLUDEPATH = /usr/include/eigen2 - freebsd-g++: EIGEN_INCLUDEPATH = /usr/local/include/eigen2 - netbsd*: EIGEN_INCLUDEPATH = /usr/pkg/include/eigen2 - macx: EIGEN_INCLUDEPATH = /opt/local/include/eigen2 - } -} - -!exists($$EIGEN_INCLUDEPATH/Eigen/Core) { - EIGEN_CFLAGS = $$system("pkg-config --cflags eigen2") - EIGEN_INCLUDEPATH = $$replace(EIGEN_CFLAGS,"-I","") } !exists($$EIGEN_INCLUDEPATH/Eigen/Core) { @@ -72,7 +45,7 @@ isEmpty(EIGEN_INCLUDEPATH) { } } -# EIGEN being under 'include/eigen[2-3]' needs special prepending +# EIGEN being under 'include/eigen3' needs special prepending contains(QT_VERSION, ^5\\..*) { QMAKE_INCDIR = $$EIGEN_INCLUDEPATH $$QMAKE_INCDIR } else { From 33a8c2baaadae0954cab92fa58fa7f7433199e39 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 21:39:32 +0100 Subject: [PATCH 165/263] Catch win32-mingw used when building on MSYS2. --- version.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.pri b/version.pri index e490d7dc..069d0bdd 100644 --- a/version.pri +++ b/version.pri @@ -1,7 +1,7 @@ # get VERSION from system date isEmpty(VERSION) { - win32-msvc*:!mingw-cross-env { + win32*:!mingw-cross-env { # # Windows XP date command only has one argument, /t # and it can print the date in various localized formats. From 4a75c572090edf6b0f7806f620eab91e6a496e71 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 21:46:30 +0100 Subject: [PATCH 166/263] Move -DNOGDI to main project file. This is not related to the cross build but a workaround when including windows.h that also defines Polygon. So it's now enabled for all Windows builds including MSYS2. --- mingw-cross-env.pri | 2 +- openscad.pro | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mingw-cross-env.pri b/mingw-cross-env.pri index 97ee3814..5a6502a2 100644 --- a/mingw-cross-env.pri +++ b/mingw-cross-env.pri @@ -19,7 +19,7 @@ CONFIG(mingw-cross-env) { LIBS += mingw-cross-env/lib/libexpat.a LIBS += mingw-cross-env/lib/libintl.a LIBS += mingw-cross-env/lib/libiconv.a - QMAKE_CXXFLAGS += -fpermissive -DNOGDI + QMAKE_CXXFLAGS += -fpermissive WINSTACKSIZE = 8388608 # 8MB # github issue 116 QMAKE_CXXFLAGS += -Wl,--stack,$$WINSTACKSIZE LIBS += -Wl,--stack,$$WINSTACKSIZE diff --git a/openscad.pro b/openscad.pro index d745c708..ff90be45 100644 --- a/openscad.pro +++ b/openscad.pro @@ -116,6 +116,7 @@ macx { win* { RC_FILE = openscad_win32.rc + QMAKE_CXXFLAGS += -DNOGDI } CONFIG += qt From 7d863d2bf26a61bd11a10a3d14418ce23c46c8a6 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 23:09:03 +0100 Subject: [PATCH 167/263] Updates to build on MSYS2. --- boost.pri | 2 +- cgal.pri | 10 ++++------ glew.pri | 7 +++++-- openscad.pro | 7 +++++++ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/boost.pri b/boost.pri index daa6b1df..61ebd5e2 100644 --- a/boost.pri +++ b/boost.pri @@ -19,7 +19,7 @@ boost { } isEmpty(BOOST_LINK_FLAGS):win* { - BOOST_LINK_FLAGS = -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1 -llibboost_filesystem-vc90-mt-s-1_46_1 -llibboost_system-vc90-mt-s-1_46_1 -llibboost_regex-vc90-mt-s-1_46_1 + BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt } # check for OPENSCAD_LIBDIR + multithread diff --git a/cgal.pri b/cgal.pri index e61b6def..355cf010 100644 --- a/cgal.pri +++ b/cgal.pri @@ -6,7 +6,6 @@ cgal { CGAL_DIR = $$(CGALDIR) !isEmpty(CGAL_DIR) { QMAKE_INCDIR += $$CGAL_DIR/include - win*: QMAKE_INCDIR += $$CGAL_DIR/auxiliary/gmp/include QMAKE_LIBDIR += $$CGAL_DIR/lib message("CGAL location: $$CGAL_DIR") } @@ -19,14 +18,13 @@ cgal { *-g++* { QMAKE_CXXFLAGS += -frounding-math } - LIBS += $$CGAL_DIR/auxiliary/gmp/lib/libmpfr-4.lib -lCGAL-vc110-mt-gd } else { - LIBS += -lgmp -lmpfr -lCGAL QMAKE_CXXFLAGS += -frounding-math } + LIBS += -lCGAL -lmpfr -lgmp } - *clang* { - QMAKE_CXXFLAGS -= -frounding-math - } + *clang* { + QMAKE_CXXFLAGS -= -frounding-math + } } diff --git a/glew.pri b/glew.pri index 9898af59..1bd3236e 100644 --- a/glew.pri +++ b/glew.pri @@ -9,6 +9,9 @@ glew { } unix:LIBS += -lGLEW - win32:LIBS += -lglew32s - CONFIG(mingw-cross-env):DEFINES += GLEW_STATIC + CONFIG(mingw-cross-env): { + DEFINES += GLEW_STATIC + } else { + win32:LIBS += -lglew32 + } } diff --git a/openscad.pro b/openscad.pro index ff90be45..cc2b4a58 100644 --- a/openscad.pro +++ b/openscad.pro @@ -119,6 +119,13 @@ win* { QMAKE_CXXFLAGS += -DNOGDI } +mingw* { + # needed to prevent compilation error on MSYS2: + # as.exe: objects/cgalutils.o: too many sections (76541) + QMAKE_CXXFLAGS += -Wa,-mbig-obj + debug: QMAKE_CXXFLAGS += -O1 +} + CONFIG += qt QT += opengl From abdf80c494829c7484ec78b81ce3e75fba0d2d94 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 20 Dec 2014 23:28:23 +0100 Subject: [PATCH 168/263] Revert usage of the -Wa,-mbig-obj flag as that does not work on MXE. --- openscad.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openscad.pro b/openscad.pro index cc2b4a58..dc041267 100644 --- a/openscad.pro +++ b/openscad.pro @@ -122,7 +122,7 @@ win* { mingw* { # needed to prevent compilation error on MSYS2: # as.exe: objects/cgalutils.o: too many sections (76541) - QMAKE_CXXFLAGS += -Wa,-mbig-obj + # using -Wa,-mbig-obj did not help debug: QMAKE_CXXFLAGS += -O1 } From 5a0ea7abe2dc356253776c0c60ea987e7b2a9584 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 21 Dec 2014 02:11:02 +0100 Subject: [PATCH 169/263] Color code warning and error messages in the console window (fixes #855). --- src/CGAL_Nef_polyhedron_DxfData.cc | 2 +- src/FontCache.cc | 4 ++-- src/GeometryEvaluator.cc | 2 +- src/Polygon2d.cc | 2 +- src/export.cc | 12 ++++++------ src/func.cc | 2 +- src/mainwin.cc | 13 +++++++++---- 7 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/CGAL_Nef_polyhedron_DxfData.cc b/src/CGAL_Nef_polyhedron_DxfData.cc index 5ca39e8e..cbb5ce77 100644 --- a/src/CGAL_Nef_polyhedron_DxfData.cc +++ b/src/CGAL_Nef_polyhedron_DxfData.cc @@ -46,7 +46,7 @@ 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"); + PRINT("WARNING: Scaling a 3D object with 0 - removing object"); this->reset(); } else { diff --git a/src/FontCache.cc b/src/FontCache.cc index c4b9a9dc..29534383 100644 --- a/src/FontCache.cc +++ b/src/FontCache.cc @@ -101,7 +101,7 @@ FontCache::FontCache() // Just load the configs. We'll build the fonts once all configs are loaded this->config = FcInitLoadConfig(); if (!this->config) { - PRINT("Can't initialize fontconfig library, text() objects will not be rendered"); + PRINT("WARNING: Can't initialize fontconfig library, text() objects will not be rendered"); return; } @@ -147,7 +147,7 @@ FontCache::FontCache() const FT_Error error = FT_Init_FreeType(&this->library); if (error) { - PRINT("Can't initialize freetype library, text() objects will not be rendered"); + PRINT("WARNING: Can't initialize freetype library, text() objects will not be rendered"); return; } diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 24118c1f..3c2c8965 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -530,7 +530,7 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node) if (!isSmartCached(node)) { if (matrix_contains_infinity(node.matrix) || matrix_contains_nan(node.matrix)) { // due to the way parse/eval works we can't currently distinguish between NaN and Inf - PRINT("Warning: Transformation matrix contains Not-a-Number and/or Infinity - removing object."); + PRINT("WARNING: Transformation matrix contains Not-a-Number and/or Infinity - removing object."); } else { // First union all children diff --git a/src/Polygon2d.cc b/src/Polygon2d.cc index aeb22b22..a1e2a664 100644 --- a/src/Polygon2d.cc +++ b/src/Polygon2d.cc @@ -59,7 +59,7 @@ bool Polygon2d::isEmpty() const void Polygon2d::transform(const Transform2d &mat) { if (mat.matrix().determinant() == 0) { - PRINT("Warning: Scaling a 2D object with 0 - removing object"); + PRINT("WARNING: Scaling a 2D object with 0 - removing object"); this->theoutlines.clear(); return; } diff --git a/src/export.cc b/src/export.cc index 7f0331d1..62ff4089 100644 --- a/src/export.cc +++ b/src/export.cc @@ -246,7 +246,7 @@ static void export_stl(const CGAL_Polyhedron &P, std::ostream &output) void export_stl(const CGAL_Nef_polyhedron *root_N, std::ostream &output) { if (!root_N->p3->is_simple()) { - PRINT("Warning: Exported object may not be a valid 2-manifold and may need repair"); + PRINT("WARNING: Exported object may not be a valid 2-manifold and may need repair"); } bool usePolySet = true; @@ -271,10 +271,10 @@ void export_stl(const CGAL_Nef_polyhedron *root_N, std::ostream &output) export_stl(P, output); } catch (const CGAL::Assertion_exception &e) { - PRINTB("CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s", e.what()); + PRINTB("ERROR: CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s", e.what()); } catch (...) { - PRINT("CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()"); + PRINT("ERROR: CGAL unknown error in CGAL_Nef_polyhedron3::convert_to_Polyhedron()"); } CGAL::set_error_behaviour(old_behaviour); } @@ -291,7 +291,7 @@ void export_off(const class PolySet &ps, std::ostream &output) void export_off(const CGAL_Nef_polyhedron *root_N, std::ostream &output) { if (!root_N->p3->is_simple()) { - PRINT("Object isn't a valid 2-manifold! Modify your design."); + PRINT("WARNING: Export failed, the object isn't a valid 2-manifold."); return; } CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); @@ -301,7 +301,7 @@ void export_off(const CGAL_Nef_polyhedron *root_N, std::ostream &output) output << P; } catch (const CGAL::Assertion_exception &e) { - PRINTB("CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s", e.what()); + PRINTB("ERROR: CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s", e.what()); } CGAL::set_error_behaviour(old_behaviour); } @@ -321,7 +321,7 @@ void export_amf(const class PolySet &ps, std::ostream &output) void export_amf(const CGAL_Nef_polyhedron *root_N, std::ostream &output) { if (!root_N->p3->is_simple()) { - PRINT("Object isn't a valid 2-manifold! Modify your design."); + PRINT("WARNING: Export failed, the object isn't a valid 2-manifold."); return; } CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); diff --git a/src/func.cc b/src/func.cc index e6830099..75597720 100644 --- a/src/func.cc +++ b/src/func.cc @@ -930,7 +930,7 @@ ValuePtr builtin_norm(const Context *, const EvalContext *evalctx) register double x = v[i].toDouble(); sum += x*x; } else { - PRINT(" WARNING: Incorrect arguments to norm()"); + PRINT("WARNING: Incorrect arguments to norm()"); return ValuePtr::undefined; } return ValuePtr(sqrt(sum)); diff --git a/src/mainwin.cc b/src/mainwin.cc index 2c46b4db..b2ef178f 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1936,7 +1936,7 @@ void MainWindow::actionExport(export_type_e, QString, QString) const CGAL_Nef_polyhedron *N = dynamic_cast(this->root_geom.get()); if (N && !N->p3->is_simple()) { - PRINT("Warning: Object may not be a valid 2-manifold and may need repair! See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export"); + PRINT("WARNING: Object may not be a valid 2-manifold and may need repair! See http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/STL_Import_and_Export"); } QString title = QString(_("Export %1 File")).arg(type_name); @@ -2524,10 +2524,15 @@ void MainWindow::quit() void MainWindow::consoleOutput(const std::string &msg, void *userdata) { // Invoke the append function in the main thread in case the output - // originates in a worker thread. + // originates in a worker thread. MainWindow *thisp = static_cast(userdata); - QMetaObject::invokeMethod(thisp->console, "append", Qt::QueuedConnection, - Q_ARG(QString, QString::fromUtf8(msg.c_str()))); + QString qmsg = QString::fromUtf8(msg.c_str()); + if (qmsg.startsWith("WARNING:")) { + qmsg = "" + qmsg + ""; + } else if (qmsg.startsWith("ERROR:")) { + qmsg = "" + qmsg + ""; + } + QMetaObject::invokeMethod(thisp->console, "append", Qt::QueuedConnection, Q_ARG(QString, qmsg)); if (thisp->procevents) QApplication::processEvents(); } From 98a9ea7e129e3374d0df1ea2ac4c11b26c77d32d Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 21 Dec 2014 03:46:13 +0100 Subject: [PATCH 170/263] Use QtConcurrentRun to initialize FontConfig in a separate thread. --- openscad.pro | 2 +- src/FontCache.cc | 23 +++++++++++++++-------- src/FontCache.h | 27 +++++++++++++++++++++------ src/openscad.cc | 36 +++++++++++++++++++++++------------- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/openscad.pro b/openscad.pro index dc041267..c90942ea 100644 --- a/openscad.pro +++ b/openscad.pro @@ -127,7 +127,7 @@ mingw* { } CONFIG += qt -QT += opengl +QT += opengl concurrent # see http://fedoraproject.org/wiki/UnderstandingDSOLinkChange # and https://github.com/openscad/openscad/pull/119 diff --git a/src/FontCache.cc b/src/FontCache.cc index c4b9a9dc..b2e0d23d 100644 --- a/src/FontCache.cc +++ b/src/FontCache.cc @@ -81,11 +81,20 @@ const std::string &FontInfo::get_file() const } FontCache * FontCache::self = NULL; -FontCache::ProgressHandlerFunc *FontCache::start_cb = NULL; -FontCache::ProgressHandlerFunc *FontCache::end_cb = NULL; +FontCache::InitHandlerFunc *FontCache::cb_handler = FontCache::defaultInitHandler; void *FontCache::cb_userdata = NULL; const std::string FontCache::DEFAULT_FONT("XXX"); +/** + * Default implementation for the font cache initialization. In case no other + * handler is registered, the cache build is just called synchronously in the + * current thread by this handler. + */ +void FontCache::defaultInitHandler(FontCacheInitializer *initializer, void *) +{ + initializer->run(); +} + FontCache::FontCache() { this->init_ok = false; @@ -134,9 +143,8 @@ FontCache::FontCache() } } - if (FontCache::start_cb) FontCache::start_cb(FontCache::cb_userdata); - FcConfigBuildFonts(this->config); - if (FontCache::end_cb) FontCache::end_cb(FontCache::cb_userdata); + FontCacheInitializer initializer(this->config); + cb_handler(&initializer, cb_userdata); // For use by LibraryInfo FcStrList *dirs = FcConfigGetFontDirs(this->config); @@ -166,10 +174,9 @@ FontCache * FontCache::instance() return self; } -void FontCache::registerProgressHandler(ProgressHandlerFunc *start, ProgressHandlerFunc *end, void *userdata) +void FontCache::registerProgressHandler(InitHandlerFunc *handler, void *userdata) { - FontCache::start_cb = start; - FontCache::end_cb = end; + FontCache::cb_handler = handler; FontCache::cb_userdata = userdata; } diff --git a/src/FontCache.h b/src/FontCache.h index e8dd318a..ea74d147 100644 --- a/src/FontCache.h +++ b/src/FontCache.h @@ -59,6 +59,19 @@ private: typedef std::vector FontInfoList; +/** + * Slow call of the font cache initialization. This is separated here so it + * can be passed to the GUI to run in a separate thread while showing a + * progress dialog. + */ +class FontCacheInitializer { +public: + FontCacheInitializer(FcConfig *config) : config(config) { } + void run() { FcConfigBuildFonts(config); } +private: + FcConfig *config; +}; + class FontCache { public: const static std::string DEFAULT_FONT; @@ -76,17 +89,19 @@ public: static FontCache *instance(); - typedef void (ProgressHandlerFunc)(void *userdata); - static void registerProgressHandler(ProgressHandlerFunc *start, ProgressHandlerFunc *end, void *userdata = NULL); + typedef void (InitHandlerFunc)(FontCacheInitializer *initializer, void *userdata); + static void registerProgressHandler(InitHandlerFunc *handler, void *userdata = NULL); + private: typedef std::pair cache_entry_t; typedef std::map cache_t; static FontCache *self; - static ProgressHandlerFunc *start_cb; - static ProgressHandlerFunc *end_cb; - static void *cb_userdata; - + static InitHandlerFunc *cb_handler; + static void *cb_userdata; + + static void defaultInitHandler(FontCacheInitializer *delegate, void *userdata); + bool init_ok; cache_t cache; FcConfig *config; diff --git a/src/openscad.cc b/src/openscad.cc index 621ea7b1..89d2bf12 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -549,6 +549,9 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets) #include #include #include +#include +#include +#include Q_DECLARE_METATYPE(shared_ptr); @@ -578,20 +581,29 @@ bool QtUseGUI() return useGUI; } - -#include -QProgressDialog *fontCacheProgress = NULL; - -void fontCacheStart(void *userdata) +void dialogThreadFunc(FontCacheInitializer *initializer) { - fontCacheProgress = new QProgressDialog("Fontconfig needs to update its font cache.\nThis can take up to a couple of minutes.", QString(), 0, 0); - fontCacheProgress->show(); + initializer->run(); } -void fontCacheEnd(void *userdata) +void dialogInitHandler(FontCacheInitializer *initializer, void *) { - delete fontCacheProgress; - fontCacheProgress = NULL; + QProgressDialog dialog; + dialog.setLabelText("Fontconfig needs to update its font cache.\nThis can take up to a couple of minutes."); + dialog.setCancelButton(0); + + QFutureWatcher futureWatcher; + QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset())); + QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel())); + QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int))); + QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int))); + + QFuture future = QtConcurrent::run(boost::bind(dialogThreadFunc, initializer)); + futureWatcher.setFuture(future); + + dialog.exec(); + + futureWatcher.waitForFinished(); } int gui(vector &inputFiles, const fs::path &original_path, int argc, char ** argv) @@ -624,9 +636,7 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha const QString &app_path = app.applicationDirPath(); PlatformUtils::registerApplicationPath(app_path.toLocal8Bit().constData()); - FontCache::registerProgressHandler(fontCacheStart, fontCacheEnd); - - + FontCache::registerProgressHandler(dialogInitHandler); parser_init(); From 310ca16c1bc2dfc24aebfc7b46a8301ba7911c22 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 21 Dec 2014 04:40:24 +0100 Subject: [PATCH 171/263] Update test reference file for norm(). --- tests/regression/echotest/norm-tests-expected.echo | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/regression/echotest/norm-tests-expected.echo b/tests/regression/echotest/norm-tests-expected.echo index cfa2e572..5e27997c 100644 --- a/tests/regression/echotest/norm-tests-expected.echo +++ b/tests/regression/echotest/norm-tests-expected.echo @@ -11,15 +11,15 @@ ECHO: undef ECHO: undef ECHO: undef ECHO: undef - WARNING: Incorrect arguments to norm() +WARNING: Incorrect arguments to norm() ECHO: undef - WARNING: Incorrect arguments to norm() +WARNING: Incorrect arguments to norm() ECHO: undef - WARNING: Incorrect arguments to norm() +WARNING: Incorrect arguments to norm() ECHO: undef - WARNING: Incorrect arguments to norm() +WARNING: Incorrect arguments to norm() ECHO: undef - WARNING: Incorrect arguments to norm() +WARNING: Incorrect arguments to norm() ECHO: undef ECHO: undef ECHO: undef From 8214cabe500884a178cab86d1dcbd312ee4d96ef Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 21 Dec 2014 16:43:51 +0100 Subject: [PATCH 172/263] Remove qtcreator user configuration. --- openscad.pro.user | 201 ---------------------------------------------- 1 file changed, 201 deletions(-) delete mode 100644 openscad.pro.user diff --git a/openscad.pro.user b/openscad.pro.user deleted file mode 100644 index bc4fd482..00000000 --- a/openscad.pro.user +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - true - 1 - true - 0 - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - - ProjectExplorer.Project.Target.0 - - Qt 4.8.6 (qt4) - Qt 4.8.6 (qt4) - {90222843-28c9-4a66-ac82-99bd31ae7263} - 0 - 0 - 0 - - - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - false - CONFIG+=experimental - false - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - false - - - - 2 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - -w - -r - - true - clean - - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - 1 - - - 0 - Deploy - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deploy locally - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - openscad - - Qt4ProjectManager.Qt4RunConfiguration:/home/shaina/openscad/openscad.pro - - openscad.pro - false - false - - 3768 - true - false - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.EnvironmentId - {56f57d1a-fe9b-42b2-a96b-3ac76cf7565f} - - - ProjectExplorer.Project.Updater.FileVersion - 15 - - From c278963a850b77fd7e5e0ffb9c645dcd54eac6e5 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 21 Dec 2014 17:11:44 +0100 Subject: [PATCH 173/263] Path and filenames need to use system encoding (fixes #1092). --- src/PlatformUtils-win.cc | 11 ++++++----- src/mainwin.cc | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index 1f07b683..2a54d8fd 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -61,11 +61,12 @@ static const std::string getFolderPath(int nFolder) int result = SHGetFolderPathW( hwndOwner, nFolder, hToken, dwFlags, pszPath ); if (result == S_OK) { - path = std::wstring( path.c_str() ); // strip extra NULLs - //std::wcerr << "wchar path:" << "\n"; - const std::string retval = winapi_wstr_to_utf8( path ); - //PRINTB("Path found: %s",retval); - return retval; + path = std::wstring( path.c_str() ); // strip extra NULLs + // Use boost::filesystem to decide how to convert from wstring + // to string. Normally the path encoding is system local and + // we don't want to force conversion to UTF-8. + fs::path p(path); + return p.string(); } return ""; } diff --git a/src/mainwin.cc b/src/mainwin.cc index b2ef178f..8f399c21 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1232,7 +1232,7 @@ void MainWindow::writeBackup(QFile *file) writer.setCodec("UTF-8"); writer << this->editor->toPlainText(); - PRINTB("Saved backup file: %s", file->fileName().toLocal8Bit().constData()); + PRINTB("Saved backup file: %s", file->fileName().toUtf8().constData()); } void MainWindow::saveBackup() @@ -1243,7 +1243,7 @@ void MainWindow::saveBackup() return; } - QString backupPath = QString::fromStdString(path); + QString backupPath = QString::fromLocal8Bit(path.c_str()); if (!backupPath.endsWith("/")) backupPath.append("/"); QString basename = "unsaved"; From b697003b0a31e50575b03892b90c9e03653c32fb Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 21 Dec 2014 17:15:53 +0100 Subject: [PATCH 174/263] Handle different naming conventions for debug versions of QScintilla. --- qscintilla2.prf | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/qscintilla2.prf b/qscintilla2.prf index 5fd22307..754f5614 100644 --- a/qscintilla2.prf +++ b/qscintilla2.prf @@ -10,9 +10,25 @@ INCLUDEPATH += $$[QT_INSTALL_HEADERS] LIBS += -L$$[QT_INSTALL_LIBS] -greaterThan(QT_MAJOR_VERSION, 4) { - win32|macx:LIBS += -lqscintilla2 - else:LIBS += -lqt5scintilla2 +CONFIG(debug, debug|release) { + mac: { + #LIBS += -lqscintilla2_debug + LIBS += -lqscintilla2 + } else { + win32: { + LIBS += -lqscintilla2d + } else { + greaterThan(QT_MAJOR_VERSION, 4) { + LIBS += -lqt5scintilla2 + } else { + LIBS += -lqscintilla2 + } + } + } } else { - LIBS += -lqscintilla2 + greaterThan(QT_MAJOR_VERSION, 4) { + LIBS += -lqt5scintilla2 + } else { + LIBS += -lqscintilla2 + } } From b79954237ca005e0dd35ca171b368f562de65a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Sun, 21 Dec 2014 23:23:25 +0100 Subject: [PATCH 175/263] Updated the Czech translation --- locale/cs.po | 321 ++++++++++++++++++++++++++------------------------- 1 file changed, 163 insertions(+), 158 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index 016b186f..7e1d08ca 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: OpenSCAD 2013.02.24\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-13 00:22+0100\n" -"PO-Revision-Date: 2014-01-29 18:32+0100\n" +"PO-Revision-Date: 2014-12-21 23:22+0100\n" "Last-Translator: Miro Hrončok \n" "Language-Team: Czech \n" "Language: cs\n" @@ -20,30 +20,28 @@ msgstr "" "X-Poedit-SourceCharset: UTF-8\n" #: objects/ui_AboutDialog.h:51 -#, fuzzy msgid "About OpenSCAD" -msgstr "Manuál k OpenSCADu (anglicky)" +msgstr "O OpenSCADu" #: objects/ui_FontListDialog.h:102 -#, fuzzy msgid "OpenSCAD Font List" -msgstr "Manuál k OpenSCADu (anglicky)" +msgstr "Seznam OpenSCAD písem" #: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 msgid "&OK" -msgstr "" +msgstr "&OK" #: objects/ui_FontListDialog.h:105 msgid "Paste font selector to Editor Window" -msgstr "" +msgstr "Vložit výběr písma do zdrojového kódu" #: objects/ui_FontListDialog.h:107 msgid "Copy to Clipboard" -msgstr "" +msgstr "Kopírovat do schránky" #: objects/ui_FontListDialog.h:108 msgid "Filter:" -msgstr "" +msgstr "Filtr:" #: objects/ui_FontListDialog.h:109 msgid "" @@ -57,35 +55,39 @@ msgid "" "family:'Courier New,courier';\"> text(t = "OpenSCAD", font = " ""Liberation Sans:style=Italic");" msgstr "" +"

Tento seznam zobrazuje písma momentálně dostupná pro " +"OpenSCAD.

Příklad:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" #: objects/ui_launchingscreen.h:276 -#, fuzzy msgid "Welcome to OpenSCAD" -msgstr "Manuál k OpenSCADu (anglicky)" +msgstr "Vítá vás OpenSCAD" #: objects/ui_launchingscreen.h:277 -#, fuzzy msgid "New" -msgstr "&Nový" +msgstr "Nový" #: objects/ui_launchingscreen.h:278 -#, fuzzy msgid "Open" -msgstr "OpenCSG" +msgstr "Otevřít" #: objects/ui_launchingscreen.h:279 -#, fuzzy msgid "Help" -msgstr "&Nápověda" +msgstr "Nápověda" #: objects/ui_launchingscreen.h:280 -#, fuzzy msgid "Recents" -msgstr "Nedávné soubory" +msgstr "Nedávné" #: objects/ui_launchingscreen.h:281 msgid "Open Recent" -msgstr "Nedávné soubory" +msgstr "Otevřít nedávný soubor" #: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 #: objects/ui_MainWindow.h:858 @@ -93,9 +95,8 @@ msgid "Examples" msgstr "Příklady" #: objects/ui_launchingscreen.h:285 -#, fuzzy msgid "Open Example" -msgstr "Příklady" +msgstr "Otevřít příklad" #: objects/ui_launchingscreen.h:287 msgid "" @@ -113,15 +114,15 @@ msgstr "" #: objects/ui_launchingscreen.h:294 msgid "Don't show again" -msgstr "" +msgstr "Příště nezobrazovat" #: objects/ui_LibraryInfoDialog.h:75 msgid "Lib & Build Info" -msgstr "" +msgstr "Info o knihovnách a sestavení" #: objects/ui_LibraryInfoDialog.h:76 msgid "OpenSCAD Detailed Library and Build Information" -msgstr "" +msgstr "Podrobné informace o tomto sestavení OpenSCADu a použitých knihovnách" #: objects/ui_MainWindow.h:733 msgid "&New" @@ -129,7 +130,7 @@ msgstr "&Nový" #: objects/ui_MainWindow.h:734 msgid "Ctrl+N" -msgstr "" +msgstr "Ctrl+N" #: objects/ui_MainWindow.h:735 msgid "&Open..." @@ -137,7 +138,7 @@ msgstr "&Otevřít..." #: objects/ui_MainWindow.h:736 msgid "Ctrl+O" -msgstr "" +msgstr "Ctrl+O" #: objects/ui_MainWindow.h:737 msgid "&Save" @@ -145,7 +146,7 @@ msgstr "&Uložit" #: objects/ui_MainWindow.h:738 msgid "Ctrl+S" -msgstr "" +msgstr "Ctrl+S" #: objects/ui_MainWindow.h:739 msgid "Save &As..." @@ -153,7 +154,7 @@ msgstr "Uložit &jako..." #: objects/ui_MainWindow.h:740 msgid "Ctrl+Shift+S" -msgstr "" +msgstr "Ctrl+Shift+S" #: objects/ui_MainWindow.h:741 msgid "&Reload" @@ -161,7 +162,7 @@ msgstr "&Znovu načíst" #: objects/ui_MainWindow.h:742 msgid "Ctrl+R" -msgstr "" +msgstr "Ctrl+R" #: objects/ui_MainWindow.h:743 msgid "&Quit" @@ -169,7 +170,7 @@ msgstr "U&končit" #: objects/ui_MainWindow.h:744 msgid "Ctrl+Q" -msgstr "" +msgstr "Ctrl+Q" #: objects/ui_MainWindow.h:745 msgid "&Undo" @@ -177,7 +178,7 @@ msgstr "&Zpět" #: objects/ui_MainWindow.h:746 msgid "Ctrl+Z" -msgstr "" +msgstr "Ctrl+Z" #: objects/ui_MainWindow.h:747 msgid "&Redo" @@ -185,7 +186,7 @@ msgstr "Zn&ovu" #: objects/ui_MainWindow.h:748 msgid "Ctrl+Shift+Z" -msgstr "" +msgstr "Ctrl+Shift+Z" #: objects/ui_MainWindow.h:749 msgid "Cu&t" @@ -193,7 +194,7 @@ msgstr "&Vyjmout" #: objects/ui_MainWindow.h:750 msgid "Ctrl+X" -msgstr "" +msgstr "Ctrl+X" #: objects/ui_MainWindow.h:751 msgid "&Copy" @@ -201,7 +202,7 @@ msgstr "&Kopírovat" #: objects/ui_MainWindow.h:752 msgid "Ctrl+C" -msgstr "" +msgstr "Ctrl+C" #: objects/ui_MainWindow.h:753 msgid "&Paste" @@ -209,7 +210,7 @@ msgstr "V&ložit" #: objects/ui_MainWindow.h:754 msgid "Ctrl+V" -msgstr "" +msgstr "Ctrl+V" #: objects/ui_MainWindow.h:755 msgid "&Indent" @@ -217,7 +218,7 @@ msgstr "Odsad&it" #: objects/ui_MainWindow.h:756 msgid "Ctrl+I" -msgstr "" +msgstr "Ctrl+I" #: objects/ui_MainWindow.h:757 msgid "U&nindent" @@ -225,7 +226,7 @@ msgstr "Z&rušit odsazení" #: objects/ui_MainWindow.h:758 msgid "Ctrl+Shift+I" -msgstr "" +msgstr "Ctrl+Shift+I" #: objects/ui_MainWindow.h:759 msgid "C&omment" @@ -233,7 +234,7 @@ msgstr "&Zakomentovat" #: objects/ui_MainWindow.h:760 msgid "Ctrl+D" -msgstr "" +msgstr "Ctrl+D" #: objects/ui_MainWindow.h:761 msgid "Unco&mment" @@ -241,7 +242,7 @@ msgstr "&Odkomentovat" #: objects/ui_MainWindow.h:762 msgid "Ctrl+Shift+D" -msgstr "" +msgstr "Ctrl+Shift+D" #: objects/ui_MainWindow.h:763 msgid "Paste viewport translation" @@ -249,7 +250,7 @@ msgstr "Vložit posun pohledu" #: objects/ui_MainWindow.h:764 msgid "Ctrl+T" -msgstr "" +msgstr "Ctrl+T" #: objects/ui_MainWindow.h:765 msgid "Paste viewport rotation" @@ -261,7 +262,7 @@ msgstr "Přiblížit" #: objects/ui_MainWindow.h:767 msgid "Ctrl++" -msgstr "" +msgstr "Ctrl++" #: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 msgid "Zoom Out" @@ -269,40 +270,39 @@ msgstr "Oddálit" #: objects/ui_MainWindow.h:769 msgid "Ctrl+-" -msgstr "" +msgstr "Ctrl+-" #: objects/ui_MainWindow.h:770 msgid "Hide editor" msgstr "Skrýt editor" #: objects/ui_MainWindow.h:771 -#, fuzzy msgid "&Reload and Preview" -msgstr "Znovu &načíst a zkompilovat" +msgstr "Znovu &načíst a zobrazit" #: objects/ui_MainWindow.h:772 msgid "F4" -msgstr "" +msgstr "F4" #: objects/ui_MainWindow.h:773 msgid "&Preview" -msgstr "" +msgstr "&Zobrazit" #: objects/ui_MainWindow.h:774 msgid "F5" -msgstr "" +msgstr "F5" #: objects/ui_MainWindow.h:775 msgid "&Render" -msgstr "" +msgstr "Vy&renderovat" #: objects/ui_MainWindow.h:776 msgid "F6" -msgstr "" +msgstr "F6" #: objects/ui_MainWindow.h:777 msgid "Check Validity" -msgstr "" +msgstr "Zkontrolovat správnost" #: objects/ui_MainWindow.h:778 msgid "Display &AST..." @@ -326,28 +326,27 @@ msgstr "Exportovat jako &OFF..." #: objects/ui_MainWindow.h:783 msgid "Preview" -msgstr "" +msgstr "Náhled" #: objects/ui_MainWindow.h:784 msgid "F9" -msgstr "" +msgstr "F9" #: objects/ui_MainWindow.h:785 -#, fuzzy msgid "Surfaces" -msgstr "CGAL povrch" +msgstr "Povrchy" #: objects/ui_MainWindow.h:786 msgid "F10" -msgstr "" +msgstr "F10" #: objects/ui_MainWindow.h:787 msgid "Wireframe" -msgstr "" +msgstr "Drátové zobrazení" #: objects/ui_MainWindow.h:788 msgid "F11" -msgstr "" +msgstr "F11" #: objects/ui_MainWindow.h:789 msgid "Thrown Together" @@ -355,7 +354,7 @@ msgstr "Vše společně" #: objects/ui_MainWindow.h:790 msgid "F12" -msgstr "" +msgstr "F12" #: objects/ui_MainWindow.h:791 msgid "Show Edges" @@ -363,7 +362,7 @@ msgstr "Zobrazit hrany" #: objects/ui_MainWindow.h:792 msgid "Ctrl+1" -msgstr "" +msgstr "Ctrl+1" #: objects/ui_MainWindow.h:793 msgid "Show Axes" @@ -371,7 +370,7 @@ msgstr "Zobrazit osy" #: objects/ui_MainWindow.h:794 msgid "Ctrl+2" -msgstr "" +msgstr "Ctrl+2" #: objects/ui_MainWindow.h:795 msgid "Show Crosshairs" @@ -379,7 +378,7 @@ msgstr "Zobrazit zaměřovač" #: objects/ui_MainWindow.h:796 msgid "Ctrl+3" -msgstr "" +msgstr "Ctrl+3" #: objects/ui_MainWindow.h:797 msgid "Animate" @@ -391,7 +390,7 @@ msgstr "Shora" #: objects/ui_MainWindow.h:799 msgid "Ctrl+4" -msgstr "" +msgstr "Ctrl+4" #: objects/ui_MainWindow.h:800 msgid "Bottom" @@ -399,7 +398,7 @@ msgstr "Zespoda" #: objects/ui_MainWindow.h:801 msgid "Ctrl+5" -msgstr "" +msgstr "Ctrl+5" #: objects/ui_MainWindow.h:802 msgid "Left" @@ -407,7 +406,7 @@ msgstr "Zleva" #: objects/ui_MainWindow.h:803 msgid "Ctrl+6" -msgstr "" +msgstr "Ctrl+6" #: objects/ui_MainWindow.h:804 msgid "Right" @@ -415,7 +414,7 @@ msgstr "Zprava" #: objects/ui_MainWindow.h:805 msgid "Ctrl+7" -msgstr "" +msgstr "Ctrl+7" #: objects/ui_MainWindow.h:806 msgid "Front" @@ -423,7 +422,7 @@ msgstr "Zepředu" #: objects/ui_MainWindow.h:807 msgid "Ctrl+8" -msgstr "" +msgstr "Ctrl+8" #: objects/ui_MainWindow.h:808 msgid "Back" @@ -431,7 +430,7 @@ msgstr "Zezadu" #: objects/ui_MainWindow.h:809 msgid "Ctrl+9" -msgstr "" +msgstr "Ctrl+9" #: objects/ui_MainWindow.h:810 msgid "Diagonal" @@ -439,7 +438,7 @@ msgstr "Diagonálně" #: objects/ui_MainWindow.h:811 msgid "Ctrl+0" -msgstr "" +msgstr "Ctrl+0" #: objects/ui_MainWindow.h:812 msgid "Center" @@ -463,7 +462,7 @@ msgstr "O aplikaci" #: objects/ui_MainWindow.h:817 msgid "Documentation" -msgstr "" +msgstr "Dokumentace" #: objects/ui_MainWindow.h:818 msgid "Clear Recent" @@ -479,7 +478,7 @@ msgstr "Zavřít" #: objects/ui_MainWindow.h:821 msgid "Ctrl+W" -msgstr "" +msgstr "Ctrl+W" #: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 msgid "Preferences" @@ -487,43 +486,43 @@ msgstr "Předvolby" #: objects/ui_MainWindow.h:823 msgid "Find..." -msgstr "" +msgstr "Najít..." #: objects/ui_MainWindow.h:824 msgid "Ctrl+F" -msgstr "" +msgstr "Ctrl+F" #: objects/ui_MainWindow.h:825 msgid "Find and Replace..." -msgstr "" +msgstr "Najít a nahradit..." #: objects/ui_MainWindow.h:826 msgid "Ctrl+Alt+F" -msgstr "" +msgstr "Ctrl+Alt+F" #: objects/ui_MainWindow.h:827 msgid "Find Next" -msgstr "" +msgstr "Najít další" #: objects/ui_MainWindow.h:828 msgid "Ctrl+G" -msgstr "" +msgstr "Ctrl+G" #: objects/ui_MainWindow.h:829 msgid "Find Previous" -msgstr "" +msgstr "Najít předchozí" #: objects/ui_MainWindow.h:830 msgid "Ctrl+Shift+G" -msgstr "" +msgstr "Ctrl+Shift+G" #: objects/ui_MainWindow.h:831 msgid "Use Selection for Find" -msgstr "" +msgstr "Hledat vybraný řetězec" #: objects/ui_MainWindow.h:832 msgid "Ctrl+E" -msgstr "" +msgstr "Ctrl+E" #: objects/ui_MainWindow.h:833 msgid "Flush Caches" @@ -534,9 +533,8 @@ msgid "OpenSCAD Homepage" msgstr "Domovská stránka OpenSCADu" #: objects/ui_MainWindow.h:835 -#, fuzzy msgid "Automatic Reload and Preview" -msgstr "Automaticky načítat a kompilovat" +msgstr "Automaticky načítat a zobrazit" #: objects/ui_MainWindow.h:836 msgid "Export as Image..." @@ -552,52 +550,47 @@ msgstr "Informace o knihovnách" #: objects/ui_MainWindow.h:839 msgid "Check for Update.." -msgstr "" +msgstr "Zkontrolovat aktualizaci..." #: objects/ui_MainWindow.h:840 msgid "Show Library Folder..." -msgstr "" +msgstr "Adresář s knihovnami..." #: objects/ui_MainWindow.h:841 msgid "Reset View" -msgstr "" +msgstr "Výchozí pohled" #: objects/ui_MainWindow.h:842 -#, fuzzy msgid "Font List" -msgstr "Písmo" +msgstr "Seznam písem" #: objects/ui_MainWindow.h:843 -#, fuzzy msgid "Export as SVG..." -msgstr "Exportovat jako CSG..." +msgstr "Exportovat jako SVG..." #: objects/ui_MainWindow.h:844 -#, fuzzy msgid "Export as AMF..." -msgstr "Exportovat jako &DXF" +msgstr "Exportovat jako AMF..." #: objects/ui_MainWindow.h:846 msgid "Ctrl+]" -msgstr "" +msgstr "Ctrl+]" #: objects/ui_MainWindow.h:848 msgid "Ctrl+[" -msgstr "" +msgstr "Ctrl+[" #: objects/ui_MainWindow.h:849 -#, fuzzy msgid "View All" -msgstr "&Zobrazit" +msgstr "Zobrazit vše" #: objects/ui_MainWindow.h:850 msgid "Convert Tabs to Spaces" -msgstr "" +msgstr "Převést tabulátory na mezery" #: objects/ui_MainWindow.h:851 -#, fuzzy msgid "Hide toolbars" -msgstr "Skrýt editor" +msgstr "Skrýt nástrojové lišty" #: objects/ui_MainWindow.h:852 msgid "Time:" @@ -621,11 +614,11 @@ msgstr "&Soubor" #: objects/ui_MainWindow.h:857 msgid "Recent Files" -msgstr "" +msgstr "Nedávné soubory" #: objects/ui_MainWindow.h:859 msgid "Export" -msgstr "" +msgstr "Exportovat" #: objects/ui_MainWindow.h:860 msgid "&Edit" @@ -645,40 +638,39 @@ msgstr "&Nápověda" #: objects/ui_MainWindow.h:866 msgid "Find" -msgstr "" +msgstr "Najít" #: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 msgid "Replace" -msgstr "" +msgstr "Nahradit" #: objects/ui_MainWindow.h:869 msgid "Search string" -msgstr "" +msgstr "Hledaný řetězec" #: objects/ui_MainWindow.h:870 msgid "<" -msgstr "" +msgstr "<" #: objects/ui_MainWindow.h:871 msgid ">" -msgstr "" +msgstr ">" #: objects/ui_MainWindow.h:872 msgid "Done" -msgstr "" +msgstr "Hotovo" #: objects/ui_MainWindow.h:873 -#, fuzzy msgid "Replacement string" -msgstr "prvcích" +msgstr "Nahradit za" #: objects/ui_MainWindow.h:875 msgid "All" -msgstr "" +msgstr "Vše" #: objects/ui_OpenCSGWarningDialog.h:86 msgid "OpenGL Warning" -msgstr "" +msgstr "OpenGL varování" #: objects/ui_OpenCSGWarningDialog.h:87 msgid "" @@ -695,13 +687,12 @@ msgid "" msgstr "" #: objects/ui_OpenCSGWarningDialog.h:92 -#, fuzzy msgid "Enable OpenCSG" -msgstr "Povolit pro OpenGL 1.x" +msgstr "Povolit OpenCSG" #: objects/ui_OpenCSGWarningDialog.h:93 msgid "Show this message again" -msgstr "" +msgstr "Zobrazit tuto zprávu znovu" #: objects/ui_Preferences.h:609 msgid "3D View" @@ -717,37 +708,35 @@ msgstr "Editor" #: objects/ui_Preferences.h:612 msgid "Update" -msgstr "" +msgstr "Aktualizace" #: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 msgid "Features" -msgstr "" +msgstr "Funkce" #: objects/ui_Preferences.h:615 msgid "Enable/Disable experimental features" -msgstr "" +msgstr "Povolit/Zakázat experimentální funkce" #: objects/ui_Preferences.h:617 msgid "Color scheme:" msgstr "Barevné téma:" #: objects/ui_Preferences.h:618 -#, fuzzy msgid "Editor Type" -msgstr "Editor" +msgstr "Varianta editoru" #: objects/ui_Preferences.h:621 -#, fuzzy msgid "Simple Editor" -msgstr "Skrýt editor" +msgstr "Jednoduchý editor" #: objects/ui_Preferences.h:622 msgid "QScintilla Editor" -msgstr "" +msgstr "Editor QScintilla" #: objects/ui_Preferences.h:624 msgid "(requires restart)" -msgstr "" +msgstr "(vyžaduje restart aplikace)" #: objects/ui_Preferences.h:625 msgid "Font" @@ -755,27 +744,27 @@ msgstr "Písmo" #: objects/ui_Preferences.h:626 msgid "Color syntax highlighting" -msgstr "" +msgstr "Barva zvýrazňování syntaxe" #: objects/ui_Preferences.h:627 msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" -msgstr "" +msgstr "Použít Ctrl/Cmd a kolečko myši k změně velikosti písma" #: objects/ui_Preferences.h:629 msgid "Automatically check for updates" -msgstr "" +msgstr "Automaticky vyhledávat aktualizace" #: objects/ui_Preferences.h:630 msgid "Include development snapshots" -msgstr "" +msgstr "Včetně nestabilních verzí" #: objects/ui_Preferences.h:631 msgid "Check Now" -msgstr "" +msgstr "Zkontrolovat nyní" #: objects/ui_Preferences.h:632 msgid "Last checked: " -msgstr "" +msgstr "Poslední kontrola:" #: objects/ui_Preferences.h:634 msgid "OpenCSG" @@ -799,7 +788,7 @@ msgstr "prvcích" #: objects/ui_Preferences.h:639 msgid "Force Goldfeather" -msgstr "Vynutit Goldfeathera" +msgstr "Vynutit zobrazení Goldfeather" #: objects/ui_Preferences.h:640 msgid "CGAL Cache size" @@ -815,23 +804,23 @@ msgstr "Velikost PolySet cache" #: objects/ui_Preferences.h:644 msgid "Allow to open multiple documents" -msgstr "" +msgstr "Povolit současné otevření více dokumentů" #: objects/ui_Preferences.h:645 msgid "Enable docking of Editor and Console in different places" -msgstr "" +msgstr "Povolit zaparkování editoru a konzole na různá místa" #: objects/ui_Preferences.h:646 msgid "Enable undocking of Editor and Console to separate windows" -msgstr "" +msgstr "Povolit plovoucí editor a konzoli" #: objects/ui_Preferences.h:647 msgid "Show Welcome Screen" -msgstr "" +msgstr "Zobrazovat uvítací obrazovku" #: objects/ui_Preferences.h:648 msgid "Enable user interface localization (requires restart of OpenSCAD)" -msgstr "" +msgstr "Povolit lokalizaci rozhraní OpenSCADu (vyžaduje restart aplikace)" #: objects/ui_Preferences.h:649 msgid "toolBar" @@ -843,89 +832,91 @@ msgstr "" #: objects/ui_ProgressWidget.h:73 msgid "%v / %m" -msgstr "" +msgstr "%v / %m" #: src/AboutDialog.h:15 -#, fuzzy msgid "About OpenSCAD " -msgstr "Manuál k OpenSCADu (anglicky)" +msgstr "O OpenSCADu" #: src/mainwin.cc:773 src/mainwin.cc:1315 msgid "Untitled.scad" -msgstr "" +msgstr "Bezejmenný.scad" #: src/mainwin.cc:1314 msgid "Save File" -msgstr "" +msgstr "Uložit soubor" #: src/mainwin.cc:1316 msgid "OpenSCAD Designs (*.scad)" -msgstr "" +msgstr "OpenSCAD designy(*.scad)" #: src/mainwin.cc:1326 msgid "" "%1 already exists.\n" "Do you want to replace it?" msgstr "" +"%1 již existuje.\n" +"Chcete jej nahradit?" #: src/mainwin.cc:1654 msgid "Application" -msgstr "" +msgstr "Aplikace" #: src/mainwin.cc:1655 msgid "" "The document has been modified.\n" "Do you really want to reload the file?" msgstr "" +"Dokument byl pozměněn.\n" +"Opravdu jej chcete znovu načíst?" #: src/mainwin.cc:1966 src/mainwin.cc:2023 -#, fuzzy msgid "Export %1 File" -msgstr "Exportovat STL soubor" +msgstr "Exportovat %s soubor(ů)" #: src/mainwin.cc:1967 src/mainwin.cc:2027 msgid "%1 Files (*%2)" -msgstr "" +msgstr "%1 Soubor(ů) (*%2)" #: src/mainwin.cc:1968 msgid "Untitled" -msgstr "" +msgstr "Bezejmenný" #: src/mainwin.cc:2025 msgid "Untitled%1" -msgstr "" +msgstr "Bezejmenný%1" #: src/mainwin.cc:2076 msgid "Export CSG File" -msgstr "" +msgstr "Exportovat CSG soubor" #: src/mainwin.cc:2077 msgid "Untitled.csg" -msgstr "" +msgstr "Bezejmenný.csg" #: src/mainwin.cc:2078 msgid "CSG Files (*.csg)" -msgstr "" +msgstr "CSG soubory (*.csg)" #: src/mainwin.cc:2104 msgid "Export Image" -msgstr "" +msgstr "Exportovat obrázek" #: src/mainwin.cc:2104 msgid "PNG Files (*.png)" -msgstr "" +msgstr "PNG Soubory (*.png)" #: src/mainwin.cc:2344 msgid "Console" -msgstr "Terminál" +msgstr "Konzole" #: src/mainwin.cc:2471 msgid "The document has been modified." -msgstr "" +msgstr "Dokument byl pozměněn." #: src/mainwin.cc:2472 msgid "Do you want to save your changes?" -msgstr "" +msgstr "Chcete uložit změny?" #: src/QGLView.cc:114 msgid "" @@ -933,12 +924,17 @@ msgid "" "Using QGLWidget\n" "\n" msgstr "" +"\n" +"Používám QGLWidget\n" +"\n" #: src/QGLView.cc:131 msgid "" "Warning: You may experience OpenCSG rendering errors.\n" "\n" msgstr "" +"Varování: Můžete zaznamenat chyby zobrazení pomocí OpenCSG.\n" +"\n" #: src/QGLView.cc:134 msgid "" @@ -946,6 +942,8 @@ msgid "" "disabled.\n" "\n" msgstr "" +"Varování: Chybí OpenGL funkce pro OpenCSG - OpenCSG bylo vypnuto.\n" +"\n" #: src/QGLView.cc:137 msgid "" @@ -953,6 +951,8 @@ msgid "" "later.\n" "Your renderer information is as follows:\n" msgstr "" +"Vysoce doporučujeme používat OpenSCAD na systému s OpenGL 2.0 nebo novější.\n" +"Zde je informace o vašem vykreslovacím systému:\n" #: src/QGLView.cc:141 #, c-format @@ -961,6 +961,9 @@ msgid "" "%s (%s)\n" "OpenGL version %s\n" msgstr "" +"GLEW verze %s\n" +"%s (%s)\n" +"OpenGL verze %s\n" #: src/QGLView.cc:171 #, c-format @@ -968,18 +971,20 @@ msgid "" "Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " "distance = %.2f" msgstr "" +"Pohled: posun = [ %.2f %.2f %.2f ], rotace = [ %.2f %.2f %.2f ], vzdálenost " +"= %.2f" #: src/UIUtils.cc:85 msgid "Basics" -msgstr "" +msgstr "Základy" #: src/UIUtils.cc:85 msgid "Shapes" -msgstr "" +msgstr "Tvary" #: src/UIUtils.cc:85 msgid "Extrusion" -msgstr "" +msgstr "Vytažení" #~ msgid "Cornfield" #~ msgstr "Kukuřice" From 594f548b20206666881997768a8df3d1ec422db8 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 22 Dec 2014 02:25:48 +0100 Subject: [PATCH 176/263] Add color schemes "Tomorrow" and "Tomorrow Night". See https://github.com/chriskempson/tomorrow-theme --- color-schemes/editor/tomorrow-night.json | 37 ++++++++++++++++++++ color-schemes/editor/tomorrow.json | 37 ++++++++++++++++++++ color-schemes/render/tomorrow-night.json | 18 ++++++++++ color-schemes/render/tomorrow.json | 18 ++++++++++ readme.txt | 44 ++++++++++++++++++++++++ 5 files changed, 154 insertions(+) create mode 100644 color-schemes/editor/tomorrow-night.json create mode 100644 color-schemes/editor/tomorrow.json create mode 100644 color-schemes/render/tomorrow-night.json create mode 100644 color-schemes/render/tomorrow.json create mode 100644 readme.txt diff --git a/color-schemes/editor/tomorrow-night.json b/color-schemes/editor/tomorrow-night.json new file mode 100644 index 00000000..529fc910 --- /dev/null +++ b/color-schemes/editor/tomorrow-night.json @@ -0,0 +1,37 @@ +{ + "name" : "Tomorrow Night", + "index" : 1600, + "paper" : "#1d1f21", + "text" : "#c5c8c6", + "caret" : { + "width" : 2, + "foreground" : "#ffffff", + "line-background" : "#282a2e" + }, + "colors" : { + "keyword1" : "#de935f", + "keyword2" : "#b294bb", + "keyword3" : "#81a2be", + "comment" : "#969896", + "commentline" : "#969896", + "commentdoc" : "#969896", + "commentdockeyword" : "#f0c674", + "number" : "#cc6666", + "string" : "#b5bd68", + "operator" : "#8abeb7", + "whitespace-background" : "#1d1f21", + "whitespace-foreground" : "#c5c8c6", + "selection-foreground" : "#373b41", + "selection-background" : "#c5c8c6", + "margin-background" : "#1d1f21", + "margin-foreground" : "#969896", + "matched-brace-background" : "#50545c", + "matched-brace-foreground" : "#e2e6e3", + "unmatched-brace-background" : "#8a1111", + "unmatched-brace-foreground" : "#e2e6e3", + "error-marker" : "#ff0000", + "error-indicator" : "#80ff0000", + "error-indicator-outline" : "#ff000000", + "edge" : "#d33682" + } +} diff --git a/color-schemes/editor/tomorrow.json b/color-schemes/editor/tomorrow.json new file mode 100644 index 00000000..072e1f99 --- /dev/null +++ b/color-schemes/editor/tomorrow.json @@ -0,0 +1,37 @@ +{ + "name" : "Tomorrow", + "index" : 1500, + "paper" : "#f0f0f0", + "text" : "#4d4d4c", + "caret" : { + "width" : 2, + "foreground" : "#000000", + "line-background" : "#efefef" + }, + "colors" : { + "keyword1" : "#f5871f", + "keyword2" : "#8959a8", + "keyword3" : "#4271ae", + "comment" : "#8e908c", + "commentline" : "#8e908c", + "commentdoc" : "#8e908c", + "commentdockeyword" : "#eab700", + "number" : "#c82829", + "string" : "#718c00", + "operator" : "#3e999f", + "whitespace-background" : "#f0f0f0", + "whitespace-foreground" : "#4d4d4c", + "selection-foreground" : "#4d4d4c", + "selection-background" : "#d6d6d6", + "margin-background" : "#f0f0f0", + "margin-foreground" : "#4d4d4c", + "matched-brace-background" : "#d4d4d4", + "matched-brace-foreground" : "#4d4d4c", + "unmatched-brace-background" : "#ffcdcc", + "unmatched-brace-foreground" : "#4d4d4c", + "error-marker" : "#ff0000", + "error-indicator" : "#80ff0000", + "error-indicator-outline" : "#ff000000", + "edge" : "#d33682" + } +} diff --git a/color-schemes/render/tomorrow-night.json b/color-schemes/render/tomorrow-night.json new file mode 100644 index 00000000..991755f2 --- /dev/null +++ b/color-schemes/render/tomorrow-night.json @@ -0,0 +1,18 @@ +{ + "name" : "Tomorrow Night", + "index" : 1900, + "show-in-gui" : true, + + "colors" : { + "background" : "#1d1f21", + "opencsg-face-front" : "#81a2be", + "opencsg-face-back" : "#de935f", + "cgal-face-front" : "#8abeb7", + "cgal-face-back" : "#f0c674", + "cgal-face-2d" : "#b5bd68", + "cgal-edge-front" : "#c5c8c6", + "cgal-edge-back" : "#c5c8c6", + "cgal-edge-2d" : "#cc6666", + "crosshair" : "#b294bb" + } +} diff --git a/color-schemes/render/tomorrow.json b/color-schemes/render/tomorrow.json new file mode 100644 index 00000000..b76f9e10 --- /dev/null +++ b/color-schemes/render/tomorrow.json @@ -0,0 +1,18 @@ +{ + "name" : "Tomorrow", + "index" : 1800, + "show-in-gui" : true, + + "colors" : { + "background" : "#f0f0f0", + "opencsg-face-front" : "#4271ae", + "opencsg-face-back" : "#f5871f", + "cgal-face-front" : "#3e999f", + "cgal-face-back" : "#eab700", + "cgal-face-2d" : "#718c00", + "cgal-edge-front" : "#4d4d4c", + "cgal-edge-back" : "#4d4d4c", + "cgal-edge-2d" : "#c82829", + "crosshair" : "#8959a8" + } +} diff --git a/readme.txt b/readme.txt new file mode 100644 index 00000000..ebe45b95 --- /dev/null +++ b/readme.txt @@ -0,0 +1,44 @@ +Color Schemes +============= + +Solarized +--------- + +http://ethanschoonover.com/solarized + +Monokai +------- + +http://www.monokai.nl/blog/2006/07/15/textmate-color-theme/ + +Tomorrow / Tomorrow Night +------------------------- + +https://github.com/chriskempson/tomorrow-theme + +Editor: + +keyword1 Orange +keyword2 Purple +keyword3 Blue +comment Comment +commentline Comment +commentdoc Comment +commentdockeyword Yellow +number Red +string Green +operator Aqua +selection-foreground Foreground +selection-background Selection + +Render: + +opencsg-face-front Blue +opencsg-face-back Orange +cgal-face-front Aqua +cgal-face-back Yellow +cgal-face-2d Green +cgal-edge-front Foreground +cgal-edge-back Foreground +cgal-edge-2d Red +crosshair Purple From 781ec4d7bf709ca99b4eb866539ecff37957bcb2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 22 Dec 2014 16:58:03 -0500 Subject: [PATCH 177/263] Minor doc clarification --- src/offset.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/offset.cc b/src/offset.cc index d54da806..d8be76e6 100644 --- a/src/offset.cc +++ b/src/offset.cc @@ -64,7 +64,7 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti node->fs = c.lookup_variable("$fs")->toDouble(); node->fa = c.lookup_variable("$fa")->toDouble(); - // default with no argument at all is round / delta = 1 + // default with no argument at all is (r = 1, chamfer = false) // radius takes precedence if both r and delta are given. node->delta = 1; node->chamfer = false; From f945ce3ad823c4a22e3755f4c155a1cb1fe807b7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 22 Dec 2014 16:58:22 -0500 Subject: [PATCH 178/263] Correctly calculate arc_tolerance for Clipper --- src/GeometryEvaluator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 24118c1f..bb9a5573 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -391,7 +391,7 @@ Response GeometryEvaluator::visit(State &state, const OffsetNode &node) const Polygon2d *polygon = dynamic_cast(geometry); // ClipperLib documentation: The formula for the number of steps in a full // circular arc is ... Pi / acos(1 - arc_tolerance / abs(delta)) - double n = Calc::get_fragments_from_r(10, node.fn, node.fs, node.fa); + double n = Calc::get_fragments_from_r(std::abs(node.delta), node.fn, node.fs, node.fa); double arc_tolerance = std::abs(node.delta) * (1 - cos(M_PI / n)); const Polygon2d *result = ClipperUtils::applyOffset(*polygon, node.delta, node.join_type, node.miter_limit, arc_tolerance); assert(result); From b5f5ffd142d2cd46ddc826ae43ed3bd900cef59c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 22 Dec 2014 23:37:42 +0100 Subject: [PATCH 179/263] Update German translation and merge new template. --- locale/cs.po | 341 ++++--- locale/de.po | 378 ++++---- locale/fr.po | 1972 +++++++++++++++++++++-------------------- locale/openscad.pot | 334 ++++--- locale/ru.po | 335 ++++--- src/AboutDialog.h | 2 +- src/FontListDialog.ui | 3 - 7 files changed, 1694 insertions(+), 1671 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index 7e1d08ca..50bf6243 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSCAD 2013.02.24\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-11-13 00:22+0100\n" +"POT-Creation-Date: 2014-12-22 23:28+0100\n" "PO-Revision-Date: 2014-12-21 23:22+0100\n" "Last-Translator: Miro Hrončok \n" "Language-Team: Czech \n" @@ -19,7 +19,7 @@ msgstr "" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>=2 && n<=4 ? 1 : 2;\n" "X-Poedit-SourceCharset: UTF-8\n" -#: objects/ui_AboutDialog.h:51 +#: objects/ui_AboutDialog.h:51 src/AboutDialog.h:15 msgid "About OpenSCAD" msgstr "O OpenSCADu" @@ -31,19 +31,15 @@ msgstr "Seznam OpenSCAD písem" msgid "&OK" msgstr "&OK" -#: objects/ui_FontListDialog.h:105 -msgid "Paste font selector to Editor Window" -msgstr "Vložit výběr písma do zdrojového kódu" - -#: objects/ui_FontListDialog.h:107 +#: objects/ui_FontListDialog.h:104 msgid "Copy to Clipboard" msgstr "Kopírovat do schránky" -#: objects/ui_FontListDialog.h:108 +#: objects/ui_FontListDialog.h:105 msgid "Filter:" msgstr "Filtr:" -#: objects/ui_FontListDialog.h:109 +#: objects/ui_FontListDialog.h:106 msgid "" "

This list shows the fonts currently registered with " "OpenSCAD.

Example:

"
 msgstr ">"
 
-#: objects/ui_MainWindow.h:872
+#: objects/ui_MainWindow.h:869
 msgid "Done"
 msgstr "Hotovo"
 
-#: objects/ui_MainWindow.h:873
+#: objects/ui_MainWindow.h:870
 msgid "Replacement string"
 msgstr "Nahradit za"
 
-#: objects/ui_MainWindow.h:875
+#: objects/ui_MainWindow.h:872
 msgid "All"
 msgstr "Vše"
 
@@ -702,7 +694,7 @@ msgstr "3D zobrazení"
 msgid "Advanced"
 msgstr "Pokročilé"
 
-#: objects/ui_Preferences.h:611 src/mainwin.cc:2339
+#: objects/ui_Preferences.h:611 src/mainwin.cc:2315
 msgid "Editor"
 msgstr "Editor"
 
@@ -834,23 +826,19 @@ msgstr ""
 msgid "%v / %m"
 msgstr "%v / %m"
 
-#: src/AboutDialog.h:15
-msgid "About OpenSCAD "
-msgstr "O OpenSCADu"
-
-#: src/mainwin.cc:773 src/mainwin.cc:1315
+#: src/mainwin.cc:768 src/mainwin.cc:1300
 msgid "Untitled.scad"
 msgstr "Bezejmenný.scad"
 
-#: src/mainwin.cc:1314
+#: src/mainwin.cc:1299
 msgid "Save File"
 msgstr "Uložit soubor"
 
-#: src/mainwin.cc:1316
+#: src/mainwin.cc:1301
 msgid "OpenSCAD Designs (*.scad)"
 msgstr "OpenSCAD designy(*.scad)"
 
-#: src/mainwin.cc:1326
+#: src/mainwin.cc:1311
 msgid ""
 "%1 already exists.\n"
 "Do you want to replace it?"
@@ -858,11 +846,11 @@ msgstr ""
 "%1 již existuje.\n"
 "Chcete jej nahradit?"
 
-#: src/mainwin.cc:1654
+#: src/mainwin.cc:1630
 msgid "Application"
 msgstr "Aplikace"
 
-#: src/mainwin.cc:1655
+#: src/mainwin.cc:1631
 msgid ""
 "The document has been modified.\n"
 "Do you really want to reload the file?"
@@ -870,51 +858,51 @@ msgstr ""
 "Dokument byl pozměněn.\n"
 "Opravdu jej chcete znovu načíst?"
 
-#: src/mainwin.cc:1966 src/mainwin.cc:2023
+#: src/mainwin.cc:1942 src/mainwin.cc:1999
 msgid "Export %1 File"
 msgstr "Exportovat %s soubor(ů)"
 
-#: src/mainwin.cc:1967 src/mainwin.cc:2027
+#: src/mainwin.cc:1943 src/mainwin.cc:2003
 msgid "%1 Files (*%2)"
 msgstr "%1 Soubor(ů) (*%2)"
 
-#: src/mainwin.cc:1968
+#: src/mainwin.cc:1944
 msgid "Untitled"
 msgstr "Bezejmenný"
 
-#: src/mainwin.cc:2025
+#: src/mainwin.cc:2001
 msgid "Untitled%1"
 msgstr "Bezejmenný%1"
 
-#: src/mainwin.cc:2076
+#: src/mainwin.cc:2052
 msgid "Export CSG File"
 msgstr "Exportovat CSG soubor"
 
-#: src/mainwin.cc:2077
+#: src/mainwin.cc:2053
 msgid "Untitled.csg"
 msgstr "Bezejmenný.csg"
 
-#: src/mainwin.cc:2078
+#: src/mainwin.cc:2054
 msgid "CSG Files (*.csg)"
 msgstr "CSG soubory (*.csg)"
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "Export Image"
 msgstr "Exportovat obrázek"
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "PNG Files (*.png)"
 msgstr "PNG Soubory (*.png)"
 
-#: src/mainwin.cc:2344
+#: src/mainwin.cc:2320
 msgid "Console"
 msgstr "Konzole"
 
-#: src/mainwin.cc:2471
+#: src/mainwin.cc:2447
 msgid "The document has been modified."
 msgstr "Dokument byl pozměněn."
 
-#: src/mainwin.cc:2472
+#: src/mainwin.cc:2448
 msgid "Do you want to save your changes?"
 msgstr "Chcete uložit změny?"
 
@@ -986,6 +974,15 @@ msgstr "Tvary"
 msgid "Extrusion"
 msgstr "Vytažení"
 
+#~ msgid "Paste font selector to Editor Window"
+#~ msgstr "Vložit výběr písma do zdrojového kódu"
+
+#~ msgid "About OpenSCAD "
+#~ msgstr "O OpenSCADu"
+
+#~ msgid "Check for Update.."
+#~ msgstr "Zkontrolovat aktualizaci..."
+
 #~ msgid "Cornfield"
 #~ msgstr "Kukuřice"
 
diff --git a/locale/de.po b/locale/de.po
index 1e2d77e4..df48ce1c 100644
--- a/locale/de.po
+++ b/locale/de.po
@@ -7,42 +7,38 @@ msgid ""
 msgstr ""
 "Project-Id-Version: OpenSCAD 2014.01.05\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-11-13 00:22+0100\n"
-"PO-Revision-Date: 2014-10-21 00:00+0100\n"
+"POT-Creation-Date: 2014-12-22 23:28+0100\n"
+"PO-Revision-Date: 2014-12-22 23:12+0100\n"
 "Last-Translator: Torsten Paul \n"
 "Language-Team: German\n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.5.4\n"
+"X-Generator: Poedit 1.6.10\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 
-#: objects/ui_AboutDialog.h:51
+#: objects/ui_AboutDialog.h:51 src/AboutDialog.h:15
 msgid "About OpenSCAD"
 msgstr "Über OpenSCAD"
 
 #: objects/ui_FontListDialog.h:102
 msgid "OpenSCAD Font List"
-msgstr "OpenSCAD Font Liste"
+msgstr "OpenSCAD Fontliste"
 
 #: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77
 msgid "&OK"
 msgstr "OK"
 
-#: objects/ui_FontListDialog.h:105
-msgid "Paste font selector to Editor Window"
-msgstr "Font Auswahl in Editor kopieren"
-
-#: objects/ui_FontListDialog.h:107
+#: objects/ui_FontListDialog.h:104
 msgid "Copy to Clipboard"
 msgstr "Kopieren"
 
-#: objects/ui_FontListDialog.h:108
+#: objects/ui_FontListDialog.h:105
 msgid "Filter:"
 msgstr "Filter:"
 
-#: objects/ui_FontListDialog.h:109
+#: objects/ui_FontListDialog.h:106
 msgid ""
 "

This list shows the fonts currently registered with " "OpenSCAD.

Example:

"
 msgstr ">"
 
-#: objects/ui_MainWindow.h:872
+#: objects/ui_MainWindow.h:869
 msgid "Done"
 msgstr "Fertig"
 
-#: objects/ui_MainWindow.h:873
+#: objects/ui_MainWindow.h:870
 msgid "Replacement string"
 msgstr "Ersetzen mit"
 
-#: objects/ui_MainWindow.h:875
+#: objects/ui_MainWindow.h:872
 msgid "All"
 msgstr "Alles"
 
 #: objects/ui_OpenCSGWarningDialog.h:86
 msgid "OpenGL Warning"
-msgstr "OpenGL Warning"
+msgstr "OpenGL Warnung"
 
 #: objects/ui_OpenCSGWarningDialog.h:87
 msgid ""
@@ -721,7 +713,7 @@ msgstr "3D Ansicht"
 msgid "Advanced"
 msgstr "Erweitert"
 
-#: objects/ui_Preferences.h:611 src/mainwin.cc:2339
+#: objects/ui_Preferences.h:611 src/mainwin.cc:2315
 msgid "Editor"
 msgstr "Editor"
 
@@ -826,12 +818,10 @@ msgid "Allow to open multiple documents"
 msgstr "Öffnen von mehreren Dokumenten erlauben"
 
 #: objects/ui_Preferences.h:645
-#, fuzzy
 msgid "Enable docking of Editor and Console in different places"
-msgstr "Separate Editor und Konsole Fenster erlauben"
+msgstr "Verschieben des Editor und Konsole Fensters erlauben"
 
 #: objects/ui_Preferences.h:646
-#, fuzzy
 msgid "Enable undocking of Editor and Console to separate windows"
 msgstr "Separate Editor und Konsole Fenster erlauben"
 
@@ -856,23 +846,19 @@ msgstr "Form"
 msgid "%v / %m"
 msgstr "%v / %m"
 
-#: src/AboutDialog.h:15
-msgid "About OpenSCAD "
-msgstr "Über OpenSCAD"
-
-#: src/mainwin.cc:773 src/mainwin.cc:1315
+#: src/mainwin.cc:768 src/mainwin.cc:1300
 msgid "Untitled.scad"
 msgstr "Unbenannt.scad"
 
-#: src/mainwin.cc:1314
+#: src/mainwin.cc:1299
 msgid "Save File"
-msgstr "Save File"
+msgstr "Datei speichern"
 
-#: src/mainwin.cc:1316
+#: src/mainwin.cc:1301
 msgid "OpenSCAD Designs (*.scad)"
 msgstr "OpenSCAD Designs (*.scad)"
 
-#: src/mainwin.cc:1326
+#: src/mainwin.cc:1311
 msgid ""
 "%1 already exists.\n"
 "Do you want to replace it?"
@@ -880,11 +866,11 @@ msgstr ""
 "%1 existiert bereits.\n"
 "Mochten Sie die Datei ersetzen?"
 
-#: src/mainwin.cc:1654
+#: src/mainwin.cc:1630
 msgid "Application"
 msgstr "Application"
 
-#: src/mainwin.cc:1655
+#: src/mainwin.cc:1631
 msgid ""
 "The document has been modified.\n"
 "Do you really want to reload the file?"
@@ -892,51 +878,51 @@ msgstr ""
 "Das Dokument ist verändert.\n"
 "Möchten Sie die Datei wirklich neu laden?"
 
-#: src/mainwin.cc:1966 src/mainwin.cc:2023
+#: src/mainwin.cc:1942 src/mainwin.cc:1999
 msgid "Export %1 File"
 msgstr "%1 Datei exportieren"
 
-#: src/mainwin.cc:1967 src/mainwin.cc:2027
+#: src/mainwin.cc:1943 src/mainwin.cc:2003
 msgid "%1 Files (*%2)"
 msgstr "%1 Dateien (*%2)"
 
-#: src/mainwin.cc:1968
+#: src/mainwin.cc:1944
 msgid "Untitled"
 msgstr "Unbenannt"
 
-#: src/mainwin.cc:2025
+#: src/mainwin.cc:2001
 msgid "Untitled%1"
 msgstr "Unbenannt%1"
 
-#: src/mainwin.cc:2076
+#: src/mainwin.cc:2052
 msgid "Export CSG File"
 msgstr "Export CSG File"
 
-#: src/mainwin.cc:2077
+#: src/mainwin.cc:2053
 msgid "Untitled.csg"
 msgstr "Unbenannt.csg"
 
-#: src/mainwin.cc:2078
+#: src/mainwin.cc:2054
 msgid "CSG Files (*.csg)"
 msgstr "CSG Dateien (*.csg)"
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "Export Image"
 msgstr "Image exportieren"
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "PNG Files (*.png)"
 msgstr "PNG Dateien (*.png)"
 
-#: src/mainwin.cc:2344
+#: src/mainwin.cc:2320
 msgid "Console"
 msgstr "Konsole"
 
-#: src/mainwin.cc:2471
+#: src/mainwin.cc:2447
 msgid "The document has been modified."
 msgstr "Das Dokument ist verändert."
 
-#: src/mainwin.cc:2472
+#: src/mainwin.cc:2448
 msgid "Do you want to save your changes?"
 msgstr "Möchten Sie die Änderungen speichern?"
 
@@ -946,12 +932,17 @@ msgid ""
 "Using QGLWidget\n"
 "\n"
 msgstr ""
+"\n"
+"Benutze QGLWidget\n"
+"\n"
 
 #: src/QGLView.cc:131
 msgid ""
 "Warning: You may experience OpenCSG rendering errors.\n"
 "\n"
 msgstr ""
+"Achtung: Es können Darstellungsfehler beim Anzeigen der Vorschau auftreten.\n"
+"\n"
 
 #: src/QGLView.cc:134
 msgid ""
@@ -959,6 +950,9 @@ msgid ""
 "disabled.\n"
 "\n"
 msgstr ""
+"Achtung: Der Funktionsumfang des OpenGL Treibers reicht für die Vorschau "
+"nicht aus - OpenCSG wurde deaktiviert.\n"
+"\n"
 
 #: src/QGLView.cc:137
 msgid ""
@@ -966,6 +960,9 @@ msgid ""
 "later.\n"
 "Your renderer information is as follows:\n"
 msgstr ""
+"Für die korrekte Anzeige der Vorschau benötigt OpenSCAD mindestens OpenGL "
+"2.0.\n"
+"Informationen zum OpenGL Treiber:\n"
 
 #: src/QGLView.cc:141
 #, c-format
@@ -999,6 +996,15 @@ msgstr "Formen"
 msgid "Extrusion"
 msgstr "Extrusion"
 
+#~ msgid "Paste font selector to Editor Window"
+#~ msgstr "Font Selektor in Editor kopieren"
+
+#~ msgid "About OpenSCAD "
+#~ msgstr "Über OpenSCAD"
+
+#~ msgid "Check for Update.."
+#~ msgstr "Neue Version suchen..."
+
 #~ msgid "Cornfield"
 #~ msgstr "Cornfield"
 
diff --git a/locale/fr.po b/locale/fr.po
index 0a25b954..b3b892a5 100644
--- a/locale/fr.po
+++ b/locale/fr.po
@@ -2,967 +2,1011 @@
 # Copyright (C) 2013 THE OpenSCAD'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the OpenSCAD package.
 # don , 2013.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: OpenSCAD 2013.02.07\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-11-13 00:22+0100\n"
-"PO-Revision-Date: 2014-12-14 10:20-0500\n"
-"Last-Translator: Keven Villeneuve \n"
-"Language-Team: French\n"
-"Language: fr\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Poedit-SourceCharset: utf-8\n"
-"X-Generator: Poedit 1.7.1\n"
-
-#: objects/ui_AboutDialog.h:51
-msgid "About OpenSCAD"
-msgstr "À propos de OpenSCAD"
-
-#: objects/ui_FontListDialog.h:102
-msgid "OpenSCAD Font List"
-msgstr "Liste des polices OpenSCAD"
-
-#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77
-msgid "&OK"
-msgstr "&OK"
-
-#: objects/ui_FontListDialog.h:105
-msgid "Paste font selector to Editor Window"
-msgstr "Coller le sélecteur de polices dans l'éditeur de fenêtres"
-
-#: objects/ui_FontListDialog.h:107
-msgid "Copy to Clipboard"
-msgstr "Coller dans le presse-papier"
-
-#: objects/ui_FontListDialog.h:108
-msgid "Filter:"
-msgstr "Filtre:"
-
-#: objects/ui_FontListDialog.h:109
-msgid "

This list shows the fonts currently registered with OpenSCAD.

Example:

  text(t = "OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "Liberation Sans:style=Italic");
" -msgstr "

Cette liste affiche les polices présentement chargées avec OpenSCAD

Example:

  text(t = "OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "Liberation Sans:style=Italic");
" - -#: objects/ui_launchingscreen.h:276 -msgid "Welcome to OpenSCAD" -msgstr "Bienvenue dans OpenSCAD" - -#: objects/ui_launchingscreen.h:277 -msgid "New" -msgstr "Nouveau" - -#: objects/ui_launchingscreen.h:278 -msgid "Open" -msgstr "Ouvrir..." - -#: objects/ui_launchingscreen.h:279 -msgid "Help" -msgstr "Aide" - -#: objects/ui_launchingscreen.h:280 -msgid "Recents" -msgstr "Récents" - -#: objects/ui_launchingscreen.h:281 -msgid "Open Recent" -msgstr "Ouvrir un fichier récent" - -#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 -#: objects/ui_MainWindow.h:858 -msgid "Examples" -msgstr "Exemples" - -#: objects/ui_launchingscreen.h:285 -msgid "Open Example" -msgstr "&Ouvrir un example" - -#: objects/ui_launchingscreen.h:287 -msgid "" -"\n" -"

OpenSCAD

\n" -"

The Programmers Solid 3D CAD Modeller

\n" -"\n" -"\n" -"\n" -msgstr "" -"\n" -"

OpenSCAD

\n" -"

Le modeleur CAD 3D des programmeurs

\n" -"\n" -"\n" -"\n" - -#: objects/ui_launchingscreen.h:294 -msgid "Don't show again" -msgstr "Ne plus afficher" - -#: objects/ui_LibraryInfoDialog.h:75 -msgid "Lib & Build Info" -msgstr "Bibliothèques et Infos de la version" - -#: objects/ui_LibraryInfoDialog.h:76 -msgid "OpenSCAD Detailed Library and Build Information" -msgstr "Informations détaillées des bibliothèques et de la version d'OpenSCAD" - -#: objects/ui_MainWindow.h:733 -msgid "&New" -msgstr "&Nouveau" - -#: objects/ui_MainWindow.h:734 -msgid "Ctrl+N" -msgstr "Ctrl+N" - -#: objects/ui_MainWindow.h:735 -msgid "&Open..." -msgstr "&Ouvrir..." - -#: objects/ui_MainWindow.h:736 -msgid "Ctrl+O" -msgstr "Ctrl+O" - -#: objects/ui_MainWindow.h:737 -msgid "&Save" -msgstr "Enregi&strer" - -#: objects/ui_MainWindow.h:738 -msgid "Ctrl+S" -msgstr "Ctrl+S" - -#: objects/ui_MainWindow.h:739 -msgid "Save &As..." -msgstr "Enregistrer &sous..." - -#: objects/ui_MainWindow.h:740 -msgid "Ctrl+Shift+S" -msgstr "Ctrl+Shift+S" - -#: objects/ui_MainWindow.h:741 -msgid "&Reload" -msgstr "&Recharger" - -#: objects/ui_MainWindow.h:742 -msgid "Ctrl+R" -msgstr "Ctrl+R" - -#: objects/ui_MainWindow.h:743 -msgid "&Quit" -msgstr "&Quitter" - -#: objects/ui_MainWindow.h:744 -msgid "Ctrl+Q" -msgstr "Ctrl+Q" - -#: objects/ui_MainWindow.h:745 -msgid "&Undo" -msgstr "Ann&uler" - -#: objects/ui_MainWindow.h:746 -msgid "Ctrl+Z" -msgstr "Ctrl+Z" - -#: objects/ui_MainWindow.h:747 -msgid "&Redo" -msgstr "&Répéter" - -#: objects/ui_MainWindow.h:748 -msgid "Ctrl+Shift+Z" -msgstr "Ctrl+Shift+Z" - -#: objects/ui_MainWindow.h:749 -msgid "Cu&t" -msgstr "Co&uper" - -#: objects/ui_MainWindow.h:750 -msgid "Ctrl+X" -msgstr "Ctrl+X" - -#: objects/ui_MainWindow.h:751 -msgid "&Copy" -msgstr "&Copier" - -#: objects/ui_MainWindow.h:752 -msgid "Ctrl+C" -msgstr "Ctrl+C" - -#: objects/ui_MainWindow.h:753 -msgid "&Paste" -msgstr "&Coller" - -#: objects/ui_MainWindow.h:754 -msgid "Ctrl+V" -msgstr "Ctrl+V" - -#: objects/ui_MainWindow.h:755 -msgid "&Indent" -msgstr "&Indenter" - -#: objects/ui_MainWindow.h:756 -msgid "Ctrl+I" -msgstr "Ctrl+I" - -#: objects/ui_MainWindow.h:757 -msgid "U&nindent" -msgstr "Dési&ndenter" - -#: objects/ui_MainWindow.h:758 -msgid "Ctrl+Shift+I" -msgstr "Ctrl+Shift+I" - -#: objects/ui_MainWindow.h:759 -msgid "C&omment" -msgstr "C&ommenter" - -#: objects/ui_MainWindow.h:760 -msgid "Ctrl+D" -msgstr "Ctrl+D" - -#: objects/ui_MainWindow.h:761 -msgid "Unco&mment" -msgstr "Déco&mmenter" - -#: objects/ui_MainWindow.h:762 -msgid "Ctrl+Shift+D" -msgstr "Ctrl+Shift+D" - -#: objects/ui_MainWindow.h:763 -msgid "Paste viewport translation" -msgstr "Coller la translation de la fenêtre de rendu" - -#: objects/ui_MainWindow.h:764 -msgid "Ctrl+T" -msgstr "Ctrl+T" - -#: objects/ui_MainWindow.h:765 -msgid "Paste viewport rotation" -msgstr "Coller la rotation de la fenêtre de rendu" - -#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:845 -msgid "Zoom In" -msgstr "Zoom Avant" - -#: objects/ui_MainWindow.h:767 -msgid "Ctrl++" -msgstr "Ctrl++" - -#: objects/ui_MainWindow.h:768 objects/ui_MainWindow.h:847 -msgid "Zoom Out" -msgstr "Zoom Arrière" - -#: objects/ui_MainWindow.h:769 -msgid "Ctrl+-" -msgstr "Ctrl+-" - -#: objects/ui_MainWindow.h:770 -msgid "Hide editor" -msgstr "Cacher l'éditeur" - -#: objects/ui_MainWindow.h:771 -msgid "&Reload and Preview" -msgstr "&Recharger et Aperçu" - -#: objects/ui_MainWindow.h:772 -msgid "F4" -msgstr "F4" - -#: objects/ui_MainWindow.h:773 -msgid "&Preview" -msgstr "&Aperçu" - -#: objects/ui_MainWindow.h:774 -msgid "F5" -msgstr "F5" - -#: objects/ui_MainWindow.h:775 -msgid "&Render" -msgstr "&Rendu" - -#: objects/ui_MainWindow.h:776 -msgid "F6" -msgstr "F6" - -#: objects/ui_MainWindow.h:777 -msgid "Check Validity" -msgstr "Vérifier la Validité" - -#: objects/ui_MainWindow.h:778 -msgid "Display &AST..." -msgstr "Afficher &AST..." - -#: objects/ui_MainWindow.h:779 -msgid "Display CSG &Tree..." -msgstr "Afficher CSG &Arbre" - -#: objects/ui_MainWindow.h:780 -msgid "Display CSG &Products..." -msgstr "Afficher CSG &Produits" - -#: objects/ui_MainWindow.h:781 -msgid "Export as &STL..." -msgstr "Exporter comme &STL..." - -#: objects/ui_MainWindow.h:782 -msgid "Export as &OFF..." -msgstr "Exporter comme &OFF..." - -#: objects/ui_MainWindow.h:783 -msgid "Preview" -msgstr "Aperçu" - -#: objects/ui_MainWindow.h:784 -msgid "F9" -msgstr "F9" - -#: objects/ui_MainWindow.h:785 -msgid "Surfaces" -msgstr "Surfaces" - -#: objects/ui_MainWindow.h:786 -msgid "F10" -msgstr "F10" - -#: objects/ui_MainWindow.h:787 -msgid "Wireframe" -msgstr "Wireframe" - -#: objects/ui_MainWindow.h:788 -msgid "F11" -msgstr "F11" - -#: objects/ui_MainWindow.h:789 -msgid "Thrown Together" -msgstr "Jeté ensemble" - -#: objects/ui_MainWindow.h:790 -msgid "F12" -msgstr "F12" - -#: objects/ui_MainWindow.h:791 -msgid "Show Edges" -msgstr "Afficher les Arêtes" - -#: objects/ui_MainWindow.h:792 -msgid "Ctrl+1" -msgstr "Ctrl+1" - -#: objects/ui_MainWindow.h:793 -msgid "Show Axes" -msgstr "Afficher les Axes" - -#: objects/ui_MainWindow.h:794 -msgid "Ctrl+2" -msgstr "Ctrl+2" - -#: objects/ui_MainWindow.h:795 -msgid "Show Crosshairs" -msgstr "Afficher la Mire" - -#: objects/ui_MainWindow.h:796 -msgid "Ctrl+3" -msgstr "Ctrl+3" - -#: objects/ui_MainWindow.h:797 -msgid "Animate" -msgstr "Animer" - -#: objects/ui_MainWindow.h:798 -msgid "Top" -msgstr "Dessus" - -#: objects/ui_MainWindow.h:799 -msgid "Ctrl+4" -msgstr "Ctrl+4" - -#: objects/ui_MainWindow.h:800 -msgid "Bottom" -msgstr "Dessous" - -#: objects/ui_MainWindow.h:801 -msgid "Ctrl+5" -msgstr "Ctrl+5" - -#: objects/ui_MainWindow.h:802 -msgid "Left" -msgstr "Gauche" - -#: objects/ui_MainWindow.h:803 -msgid "Ctrl+6" -msgstr "Ctrl+6" - -#: objects/ui_MainWindow.h:804 -msgid "Right" -msgstr "Droite" - -#: objects/ui_MainWindow.h:805 -msgid "Ctrl+7" -msgstr "Ctrl+7" - -#: objects/ui_MainWindow.h:806 -msgid "Front" -msgstr "Face" - -#: objects/ui_MainWindow.h:807 -msgid "Ctrl+8" -msgstr "Ctrl+8" - -#: objects/ui_MainWindow.h:808 -msgid "Back" -msgstr "Arrière" - -#: objects/ui_MainWindow.h:809 -msgid "Ctrl+9" -msgstr "Ctrl+9" - -#: objects/ui_MainWindow.h:810 -msgid "Diagonal" -msgstr "Diagonale" - -#: objects/ui_MainWindow.h:811 -msgid "Ctrl+0" -msgstr "Ctrl+0" - -#: objects/ui_MainWindow.h:812 -msgid "Center" -msgstr "Centre" - -#: objects/ui_MainWindow.h:813 -msgid "Perspective" -msgstr "Perspective" - -#: objects/ui_MainWindow.h:814 -msgid "Orthogonal" -msgstr "Orthogonale" - -#: objects/ui_MainWindow.h:815 -msgid "Hide console" -msgstr "Cache la console" - -#: objects/ui_MainWindow.h:816 -msgid "About" -msgstr "À propos" - -#: objects/ui_MainWindow.h:817 -msgid "Documentation" -msgstr "Documentation" - -#: objects/ui_MainWindow.h:818 -msgid "Clear Recent" -msgstr "Effacer Récents" - -#: objects/ui_MainWindow.h:819 -msgid "Export as DXF..." -msgstr "Exporter comme DXF..." - -#: objects/ui_MainWindow.h:820 objects/ui_OpenCSGWarningDialog.h:94 -msgid "Close" -msgstr "Fermer" - -#: objects/ui_MainWindow.h:821 -msgid "Ctrl+W" -msgstr "Ctrl+W" - -#: objects/ui_MainWindow.h:822 objects/ui_Preferences.h:608 -msgid "Preferences" -msgstr "Préférences" - -#: objects/ui_MainWindow.h:823 -msgid "Find..." -msgstr "Rechercher..." - -#: objects/ui_MainWindow.h:824 -msgid "Ctrl+F" -msgstr "Ctrl+F" - -#: objects/ui_MainWindow.h:825 -msgid "Find and Replace..." -msgstr "Rechercher et remplacer..." - -#: objects/ui_MainWindow.h:826 -msgid "Ctrl+Alt+F" -msgstr "Ctrl+Alt+F" - -#: objects/ui_MainWindow.h:827 -msgid "Find Next" -msgstr "Rechercher Suivant" - -#: objects/ui_MainWindow.h:828 -msgid "Ctrl+G" -msgstr "Ctrl+G" - -#: objects/ui_MainWindow.h:829 -msgid "Find Previous" -msgstr "Rechercher Précédent" - -#: objects/ui_MainWindow.h:830 -msgid "Ctrl+Shift+G" -msgstr "Ctrl+Shift+G" - -#: objects/ui_MainWindow.h:831 -msgid "Use Selection for Find" -msgstr "Utiliser la sélection pour Rechercher" - -#: objects/ui_MainWindow.h:832 -msgid "Ctrl+E" -msgstr "Ctrl+E" - -#: objects/ui_MainWindow.h:833 -msgid "Flush Caches" -msgstr "Vider les caches" - -#: objects/ui_MainWindow.h:834 -msgid "OpenSCAD Homepage" -msgstr "Page d'accueil OpenSCAD" - -#: objects/ui_MainWindow.h:835 -msgid "Automatic Reload and Preview" -msgstr "Recharger et Aperçu Automatique" - -#: objects/ui_MainWindow.h:836 -msgid "Export as Image..." -msgstr "Exporter comme Image..." - -#: objects/ui_MainWindow.h:837 -msgid "Export as CSG..." -msgstr "Exporter comme CSG..." - -#: objects/ui_MainWindow.h:838 -msgid "Library info" -msgstr "Informations Bibliothèques" - -#: objects/ui_MainWindow.h:839 -msgid "Check for Update.." -msgstr "Vérifier les mises à jours" - -#: objects/ui_MainWindow.h:840 -msgid "Show Library Folder..." -msgstr "Afficher le dossier des bibliothèques" - -#: objects/ui_MainWindow.h:841 -msgid "Reset View" -msgstr "Réinitialiser la vue" - -#: objects/ui_MainWindow.h:842 -msgid "Font List" -msgstr "Liste des polices" - -#: objects/ui_MainWindow.h:843 -msgid "Export as SVG..." -msgstr "Exporter comme SVG..." - -#: objects/ui_MainWindow.h:844 -msgid "Export as AMF..." -msgstr "Exporter comme AMF..." - -#: objects/ui_MainWindow.h:846 -msgid "Ctrl+]" -msgstr "Ctrl+]" - -#: objects/ui_MainWindow.h:848 -msgid "Ctrl+[" -msgstr "Ctrl+[" - -#: objects/ui_MainWindow.h:849 -msgid "View All" -msgstr "&Voir Tout" - -#: objects/ui_MainWindow.h:850 -msgid "Convert Tabs to Spaces" -msgstr "Convertir les tabulations par des espaces" - -#: objects/ui_MainWindow.h:851 -msgid "Hide toolbars" -msgstr "Cacher les boîtes à outils" - -#: objects/ui_MainWindow.h:852 -msgid "Time:" -msgstr "Temps:" - -#: objects/ui_MainWindow.h:853 -msgid "FPS:" -msgstr "FPS:" - -#: objects/ui_MainWindow.h:854 -msgid "Steps:" -msgstr "Étapes:" - -#: objects/ui_MainWindow.h:855 -msgid "Dump Pictures" -msgstr "Vider les photos" - -#: objects/ui_MainWindow.h:856 -msgid "&File" -msgstr "&Fichier" - -#: objects/ui_MainWindow.h:857 -msgid "Recent Files" -msgstr "Fichiers Récents" - -#: objects/ui_MainWindow.h:859 -msgid "Export" -msgstr "Exporter" - -#: objects/ui_MainWindow.h:860 -msgid "&Edit" -msgstr "&Édition" - -#: objects/ui_MainWindow.h:861 -msgid "&Design" -msgstr "Conception" - -#: objects/ui_MainWindow.h:862 -msgid "&View" -msgstr "&Vue" - -#: objects/ui_MainWindow.h:863 -msgid "&Help" -msgstr "&Aide" - -#: objects/ui_MainWindow.h:866 -msgid "Find" -msgstr "Rechercher" - -#: objects/ui_MainWindow.h:867 objects/ui_MainWindow.h:874 -msgid "Replace" -msgstr "Remplacer" - -#: objects/ui_MainWindow.h:869 -msgid "Search string" -msgstr "Rechercher une chaîne de caractères" - -#: objects/ui_MainWindow.h:870 -msgid "<" -msgstr "<" - -#: objects/ui_MainWindow.h:871 -msgid ">" -msgstr ">" - -#: objects/ui_MainWindow.h:872 -msgid "Done" -msgstr "Terminer" - -#: objects/ui_MainWindow.h:873 -msgid "Replacement string" -msgstr "Remplacer une chaîne de caractères" - -#: objects/ui_MainWindow.h:875 -msgid "All" -msgstr "Tout" - -#: objects/ui_OpenCSGWarningDialog.h:86 -msgid "OpenGL Warning" -msgstr "Avertissements OpenGL" - -#: objects/ui_OpenCSGWarningDialog.h:87 -msgid "" -"\n" -"\n" -"

" -msgstr "" -"\n" -"\n" -"

" - -#: objects/ui_OpenCSGWarningDialog.h:92 -msgid "Enable OpenCSG" -msgstr "Activer OpenCSG" - -#: objects/ui_OpenCSGWarningDialog.h:93 -msgid "Show this message again" -msgstr "Affiche ce message à nouveau" - -#: objects/ui_Preferences.h:609 -msgid "3D View" -msgstr "&Vue 3D" - -#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 -msgid "Advanced" -msgstr "Avancé" - -#: objects/ui_Preferences.h:611 src/mainwin.cc:2339 -msgid "Editor" -msgstr "Éditeur" - -#: objects/ui_Preferences.h:612 -msgid "Update" -msgstr "Mettre à jour" - -#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 -msgid "Features" -msgstr "Fonctionnalités" - -#: objects/ui_Preferences.h:615 -msgid "Enable/Disable experimental features" -msgstr "Activer/Désactiver les fonctionnalités expérimentales" - -#: objects/ui_Preferences.h:617 -msgid "Color scheme:" -msgstr "Palette de couleurs:" - -#: objects/ui_Preferences.h:618 -msgid "Editor Type" -msgstr "Type d'éditeur" - -#: objects/ui_Preferences.h:621 -msgid "Simple Editor" -msgstr "Éditeur Simple" - -#: objects/ui_Preferences.h:622 -msgid "QScintilla Editor" -msgstr "Éditeur QScintilla" - -#: objects/ui_Preferences.h:624 -msgid "(requires restart)" -msgstr "(nécessite un redémarrage)" - -#: objects/ui_Preferences.h:625 -msgid "Font" -msgstr "Police" - -#: objects/ui_Preferences.h:626 -msgid "Color syntax highlighting" -msgstr "Colorer la coloration syntaxique" - -#: objects/ui_Preferences.h:627 -msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" -msgstr "Utiliser Ctrl/Cmd-Roulette-Souris pour agrandir le texte" - -#: objects/ui_Preferences.h:629 -msgid "Automatically check for updates" -msgstr "Vérifier les mises à jour automatiquement" - -#: objects/ui_Preferences.h:630 -msgid "Include development snapshots" -msgstr "Inclure les versions de développement" - -#: objects/ui_Preferences.h:631 -msgid "Check Now" -msgstr "Vérifier Maintenant" - -#: objects/ui_Preferences.h:632 -msgid "Last checked: " -msgstr "Dernière vérification:" - -#: objects/ui_Preferences.h:634 -msgid "OpenCSG" -msgstr "OpenCSG" - -#: objects/ui_Preferences.h:635 -msgid "Show capability warning" -msgstr "Afficher les avertissements de capacité" - -#: objects/ui_Preferences.h:636 -msgid "Enable for OpenGL 1.x" -msgstr "Activer pour OpenGL 1.x" - -#: objects/ui_Preferences.h:637 -msgid "Turn off rendering at " -msgstr "Désactiver le rendu à" - -#: objects/ui_Preferences.h:638 -msgid "elements" -msgstr "éléments" - -#: objects/ui_Preferences.h:639 -msgid "Force Goldfeather" -msgstr "Forcer Goldfeather" - -#: objects/ui_Preferences.h:640 -msgid "CGAL Cache size" -msgstr "Taille du Cache de CGAL" - -#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 -msgid "bytes" -msgstr "octets" - -#: objects/ui_Preferences.h:642 -msgid "PolySet Cache size" -msgstr "Taille du Cache PolySet" - -#: objects/ui_Preferences.h:644 -msgid "Allow to open multiple documents" -msgstr "Autoriser l'ouverture de plusieurs documents" - -#: objects/ui_Preferences.h:645 -msgid "Enable docking of Editor and Console in different places" -msgstr "Activer l'ancrage de l'Éditeur et de la Console à différents endroits" - -#: objects/ui_Preferences.h:646 -msgid "Enable undocking of Editor and Console to separate windows" -msgstr "Activer désancrage de l'Éditeur et de la Console dans des fenêtres séparés" - -#: objects/ui_Preferences.h:647 -msgid "Show Welcome Screen" -msgstr "Affiche l'écran d'accueil" - -#: objects/ui_Preferences.h:648 -msgid "Enable user interface localization (requires restart of OpenSCAD)" -msgstr "Activer la localisation de l'interface utilisateur (Nécessite un redémarrage d'OpenSCAD)" - -#: objects/ui_Preferences.h:649 -msgid "toolBar" -msgstr "boîte à outils" - -#: objects/ui_ProgressWidget.h:72 -msgid "Form" -msgstr "Formulaire" - -#: objects/ui_ProgressWidget.h:73 -msgid "%v / %m" -msgstr "%v / %m" - -#: src/AboutDialog.h:15 -msgid "About OpenSCAD " -msgstr "À propos de OpenSCAD" - -#: src/mainwin.cc:773 src/mainwin.cc:1315 -msgid "Untitled.scad" -msgstr "Untitled.scad" - -#: src/mainwin.cc:1314 -msgid "Save File" -msgstr "Enregistrer le Fichier" - -#: src/mainwin.cc:1316 -msgid "OpenSCAD Designs (*.scad)" -msgstr "OpenSCAD Designs (*.scad)" - -#: src/mainwin.cc:1326 -msgid "" -"%1 already exists.\n" -"Do you want to replace it?" -msgstr "" -"%1 existe déjà.\n" -"Voulez-vous le remplacer?" - -#: src/mainwin.cc:1654 -msgid "Application" -msgstr "Application" - -#: src/mainwin.cc:1655 -msgid "" -"The document has been modified.\n" -"Do you really want to reload the file?" -msgstr "" -"Ce document a été modifié.\n" -"Voulez-vous vraiment recharger le fichier?" - -#: src/mainwin.cc:1966 src/mainwin.cc:2023 -msgid "Export %1 File" -msgstr "Exporter %1 Fichier" - -#: src/mainwin.cc:1967 src/mainwin.cc:2027 -msgid "%1 Files (*%2)" -msgstr "%1 Fichiers (*%2)" - -#: src/mainwin.cc:1968 -msgid "Untitled" -msgstr "Sans Titre" - -#: src/mainwin.cc:2025 -msgid "Untitled%1" -msgstr "Sans Titre%1" - -#: src/mainwin.cc:2076 -msgid "Export CSG File" -msgstr "Exporter un fichier CSG" - -#: src/mainwin.cc:2077 -msgid "Untitled.csg" -msgstr "SansTitre.csg" - -#: src/mainwin.cc:2078 -msgid "CSG Files (*.csg)" -msgstr "Fichiers CSG (*.csg)" - -#: src/mainwin.cc:2104 -msgid "Export Image" -msgstr "Exporter une Image" - -#: src/mainwin.cc:2104 -msgid "PNG Files (*.png)" -msgstr "Fichiers PNG (*.png)" - -#: src/mainwin.cc:2344 -msgid "Console" -msgstr "Console" - -#: src/mainwin.cc:2471 -msgid "The document has been modified." -msgstr "Ce document a été modifié" - -#: src/mainwin.cc:2472 -msgid "Do you want to save your changes?" -msgstr "Voulez-vous enregistrer vos changements?" - -#: src/QGLView.cc:114 -msgid "" -"\n" -"Using QGLWidget\n" -"\n" -msgstr "" -"\n" -"Utilise QGLWidget\n" -"\n" - -#: src/QGLView.cc:131 -msgid "" -"Warning: You may experience OpenCSG rendering errors.\n" -"\n" -msgstr "" -"Avertissement: Vous pourriez avoir des erreurs de rendu OpenCSG\n" -"\n" - -#: src/QGLView.cc:134 -msgid "" -"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been disabled.\n" -"\n" -msgstr "" -"Avertissement: Capacités OpenGL manquantes pour OpenCSG - OpenCSG a été désactivé.\n" -"\n" - -#: src/QGLView.cc:137 -msgid "" -"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or later.\n" -"Your renderer information is as follows:\n" -msgstr "" -"Il est hautement recommandé d'utiliser OpenSCAD sur un système compatible OpenGL 2.0 ou ultérieur.\n" -"Voici les informations de votre moteur de rendu:\n" - -#: src/QGLView.cc:141 -#, c-format -msgid "" -"GLEW version %s\n" -"%s (%s)\n" -"OpenGL version %s\n" -msgstr "" -"Version GLEW %s\n" -"%s (%s)\n" -"Version OpenGL %s\n" - -#: src/QGLView.cc:171 -#, c-format -msgid "Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f" -msgstr "Fenêtre de rendu: translation = [ %.2f %.2f %.2f ], rotation = [ %.2f %.2f %.2f ], distance = %.2f" - -#: src/UIUtils.cc:85 -msgid "Basics" -msgstr "Bases" - -#: src/UIUtils.cc:85 -msgid "Shapes" -msgstr "Formes" - -#: src/UIUtils.cc:85 -msgid "Extrusion" -msgstr "Extrusion" - -#~ msgid "OpenGL Info" -#~ msgstr "Information OpenGL" +# +msgid "" +msgstr "" +"Project-Id-Version: OpenSCAD 2013.02.07\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-12-22 23:28+0100\n" +"PO-Revision-Date: 2014-12-14 10:20-0500\n" +"Last-Translator: Keven Villeneuve \n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 1.7.1\n" + +#: objects/ui_AboutDialog.h:51 src/AboutDialog.h:15 +msgid "About OpenSCAD" +msgstr "À propos de OpenSCAD" + +#: objects/ui_FontListDialog.h:102 +msgid "OpenSCAD Font List" +msgstr "Liste des polices OpenSCAD" + +#: objects/ui_FontListDialog.h:103 objects/ui_LibraryInfoDialog.h:77 +msgid "&OK" +msgstr "&OK" + +#: objects/ui_FontListDialog.h:104 +msgid "Copy to Clipboard" +msgstr "Coller dans le presse-papier" + +#: objects/ui_FontListDialog.h:105 +msgid "Filter:" +msgstr "Filtre:" + +#: objects/ui_FontListDialog.h:106 +msgid "" +"

This list shows the fonts currently registered with " +"OpenSCAD.

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" +msgstr "" +"

Cette liste affiche les polices présentement chargées " +"avec OpenSCAD

Example:

  text(t = "
+""OpenSCAD", font = "DejaVu Sans");
  text(t = "OpenSCAD", font = "
+""Liberation Sans:style=Italic");
" + +#: objects/ui_launchingscreen.h:276 +msgid "Welcome to OpenSCAD" +msgstr "Bienvenue dans OpenSCAD" + +#: objects/ui_launchingscreen.h:277 +msgid "New" +msgstr "Nouveau" + +#: objects/ui_launchingscreen.h:278 +msgid "Open" +msgstr "Ouvrir..." + +#: objects/ui_launchingscreen.h:279 +msgid "Help" +msgstr "Aide" + +#: objects/ui_launchingscreen.h:280 +msgid "Recents" +msgstr "Récents" + +#: objects/ui_launchingscreen.h:281 +msgid "Open Recent" +msgstr "Ouvrir un fichier récent" + +#: objects/ui_launchingscreen.h:282 objects/ui_launchingscreen.h:284 +#: objects/ui_MainWindow.h:855 +msgid "Examples" +msgstr "Exemples" + +#: objects/ui_launchingscreen.h:285 +msgid "Open Example" +msgstr "&Ouvrir un example" + +#: objects/ui_launchingscreen.h:287 +msgid "" +"\n" +"

OpenSCAD

\n" +"

The Programmers Solid 3D CAD Modeller

\n" +"\n" +"\n" +"\n" +msgstr "" +"\n" +"

OpenSCAD

\n" +"

Le modeleur CAD 3D des programmeurs

\n" +"\n" +"\n" +"\n" + +#: objects/ui_launchingscreen.h:294 +msgid "Don't show again" +msgstr "Ne plus afficher" + +#: objects/ui_LibraryInfoDialog.h:75 +msgid "Lib & Build Info" +msgstr "Bibliothèques et Infos de la version" + +#: objects/ui_LibraryInfoDialog.h:76 +msgid "OpenSCAD Detailed Library and Build Information" +msgstr "Informations détaillées des bibliothèques et de la version d'OpenSCAD" + +#: objects/ui_MainWindow.h:731 +msgid "&New" +msgstr "&Nouveau" + +#: objects/ui_MainWindow.h:732 +msgid "Ctrl+N" +msgstr "Ctrl+N" + +#: objects/ui_MainWindow.h:733 +msgid "&Open..." +msgstr "&Ouvrir..." + +#: objects/ui_MainWindow.h:734 +msgid "Ctrl+O" +msgstr "Ctrl+O" + +#: objects/ui_MainWindow.h:735 +msgid "&Save" +msgstr "Enregi&strer" + +#: objects/ui_MainWindow.h:736 +msgid "Ctrl+S" +msgstr "Ctrl+S" + +#: objects/ui_MainWindow.h:737 +msgid "Save &As..." +msgstr "Enregistrer &sous..." + +#: objects/ui_MainWindow.h:738 +msgid "Ctrl+Shift+S" +msgstr "Ctrl+Shift+S" + +#: objects/ui_MainWindow.h:739 +msgid "&Reload" +msgstr "&Recharger" + +#: objects/ui_MainWindow.h:740 +msgid "Ctrl+R" +msgstr "Ctrl+R" + +#: objects/ui_MainWindow.h:741 +msgid "&Quit" +msgstr "&Quitter" + +#: objects/ui_MainWindow.h:742 +msgid "Ctrl+Q" +msgstr "Ctrl+Q" + +#: objects/ui_MainWindow.h:743 +msgid "&Undo" +msgstr "Ann&uler" + +#: objects/ui_MainWindow.h:744 +msgid "Ctrl+Z" +msgstr "Ctrl+Z" + +#: objects/ui_MainWindow.h:745 +msgid "&Redo" +msgstr "&Répéter" + +#: objects/ui_MainWindow.h:746 +msgid "Ctrl+Shift+Z" +msgstr "Ctrl+Shift+Z" + +#: objects/ui_MainWindow.h:747 +msgid "Cu&t" +msgstr "Co&uper" + +#: objects/ui_MainWindow.h:748 +msgid "Ctrl+X" +msgstr "Ctrl+X" + +#: objects/ui_MainWindow.h:749 +msgid "&Copy" +msgstr "&Copier" + +#: objects/ui_MainWindow.h:750 +msgid "Ctrl+C" +msgstr "Ctrl+C" + +#: objects/ui_MainWindow.h:751 +msgid "&Paste" +msgstr "&Coller" + +#: objects/ui_MainWindow.h:752 +msgid "Ctrl+V" +msgstr "Ctrl+V" + +#: objects/ui_MainWindow.h:753 +msgid "&Indent" +msgstr "&Indenter" + +#: objects/ui_MainWindow.h:754 +msgid "Ctrl+I" +msgstr "Ctrl+I" + +#: objects/ui_MainWindow.h:755 +msgid "U&nindent" +msgstr "Dési&ndenter" + +#: objects/ui_MainWindow.h:756 +msgid "Ctrl+Shift+I" +msgstr "Ctrl+Shift+I" + +#: objects/ui_MainWindow.h:757 +msgid "C&omment" +msgstr "C&ommenter" + +#: objects/ui_MainWindow.h:758 +msgid "Ctrl+D" +msgstr "Ctrl+D" + +#: objects/ui_MainWindow.h:759 +msgid "Unco&mment" +msgstr "Déco&mmenter" + +#: objects/ui_MainWindow.h:760 +msgid "Ctrl+Shift+D" +msgstr "Ctrl+Shift+D" + +#: objects/ui_MainWindow.h:761 +msgid "Paste viewport translation" +msgstr "Coller la translation de la fenêtre de rendu" + +#: objects/ui_MainWindow.h:762 +msgid "Ctrl+T" +msgstr "Ctrl+T" + +#: objects/ui_MainWindow.h:763 +msgid "Paste viewport rotation" +msgstr "Coller la rotation de la fenêtre de rendu" + +#: objects/ui_MainWindow.h:764 objects/ui_MainWindow.h:842 +msgid "Zoom In" +msgstr "Zoom Avant" + +#: objects/ui_MainWindow.h:765 +msgid "Ctrl++" +msgstr "Ctrl++" + +#: objects/ui_MainWindow.h:766 objects/ui_MainWindow.h:844 +msgid "Zoom Out" +msgstr "Zoom Arrière" + +#: objects/ui_MainWindow.h:767 +msgid "Ctrl+-" +msgstr "Ctrl+-" + +#: objects/ui_MainWindow.h:768 +msgid "Hide editor" +msgstr "Cacher l'éditeur" + +#: objects/ui_MainWindow.h:769 +msgid "&Reload and Preview" +msgstr "&Recharger et Aperçu" + +#: objects/ui_MainWindow.h:770 +msgid "F4" +msgstr "F4" + +#: objects/ui_MainWindow.h:771 +msgid "&Preview" +msgstr "&Aperçu" + +#: objects/ui_MainWindow.h:772 +msgid "F5" +msgstr "F5" + +#: objects/ui_MainWindow.h:773 +msgid "&Render" +msgstr "&Rendu" + +#: objects/ui_MainWindow.h:774 +msgid "F6" +msgstr "F6" + +#: objects/ui_MainWindow.h:775 +msgid "Check Validity" +msgstr "Vérifier la Validité" + +#: objects/ui_MainWindow.h:776 +msgid "Display &AST..." +msgstr "Afficher &AST..." + +#: objects/ui_MainWindow.h:777 +msgid "Display CSG &Tree..." +msgstr "Afficher CSG &Arbre" + +#: objects/ui_MainWindow.h:778 +msgid "Display CSG &Products..." +msgstr "Afficher CSG &Produits" + +#: objects/ui_MainWindow.h:779 +msgid "Export as &STL..." +msgstr "Exporter comme &STL..." + +#: objects/ui_MainWindow.h:780 +msgid "Export as &OFF..." +msgstr "Exporter comme &OFF..." + +#: objects/ui_MainWindow.h:781 +msgid "Preview" +msgstr "Aperçu" + +#: objects/ui_MainWindow.h:782 +msgid "F9" +msgstr "F9" + +#: objects/ui_MainWindow.h:783 +msgid "Surfaces" +msgstr "Surfaces" + +#: objects/ui_MainWindow.h:784 +msgid "F10" +msgstr "F10" + +#: objects/ui_MainWindow.h:785 +msgid "Wireframe" +msgstr "Wireframe" + +#: objects/ui_MainWindow.h:786 +msgid "F11" +msgstr "F11" + +#: objects/ui_MainWindow.h:787 +msgid "Thrown Together" +msgstr "Jeté ensemble" + +#: objects/ui_MainWindow.h:788 +msgid "F12" +msgstr "F12" + +#: objects/ui_MainWindow.h:789 +msgid "Show Edges" +msgstr "Afficher les Arêtes" + +#: objects/ui_MainWindow.h:790 +msgid "Ctrl+1" +msgstr "Ctrl+1" + +#: objects/ui_MainWindow.h:791 +msgid "Show Axes" +msgstr "Afficher les Axes" + +#: objects/ui_MainWindow.h:792 +msgid "Ctrl+2" +msgstr "Ctrl+2" + +#: objects/ui_MainWindow.h:793 +msgid "Show Crosshairs" +msgstr "Afficher la Mire" + +#: objects/ui_MainWindow.h:794 +msgid "Ctrl+3" +msgstr "Ctrl+3" + +#: objects/ui_MainWindow.h:795 +msgid "Animate" +msgstr "Animer" + +#: objects/ui_MainWindow.h:796 +msgid "Top" +msgstr "Dessus" + +#: objects/ui_MainWindow.h:797 +msgid "Ctrl+4" +msgstr "Ctrl+4" + +#: objects/ui_MainWindow.h:798 +msgid "Bottom" +msgstr "Dessous" + +#: objects/ui_MainWindow.h:799 +msgid "Ctrl+5" +msgstr "Ctrl+5" + +#: objects/ui_MainWindow.h:800 +msgid "Left" +msgstr "Gauche" + +#: objects/ui_MainWindow.h:801 +msgid "Ctrl+6" +msgstr "Ctrl+6" + +#: objects/ui_MainWindow.h:802 +msgid "Right" +msgstr "Droite" + +#: objects/ui_MainWindow.h:803 +msgid "Ctrl+7" +msgstr "Ctrl+7" + +#: objects/ui_MainWindow.h:804 +msgid "Front" +msgstr "Face" + +#: objects/ui_MainWindow.h:805 +msgid "Ctrl+8" +msgstr "Ctrl+8" + +#: objects/ui_MainWindow.h:806 +msgid "Back" +msgstr "Arrière" + +#: objects/ui_MainWindow.h:807 +msgid "Ctrl+9" +msgstr "Ctrl+9" + +#: objects/ui_MainWindow.h:808 +msgid "Diagonal" +msgstr "Diagonale" + +#: objects/ui_MainWindow.h:809 +msgid "Ctrl+0" +msgstr "Ctrl+0" + +#: objects/ui_MainWindow.h:810 +msgid "Center" +msgstr "Centre" + +#: objects/ui_MainWindow.h:811 +msgid "Perspective" +msgstr "Perspective" + +#: objects/ui_MainWindow.h:812 +msgid "Orthogonal" +msgstr "Orthogonale" + +#: objects/ui_MainWindow.h:813 +msgid "Hide console" +msgstr "Cache la console" + +#: objects/ui_MainWindow.h:814 +msgid "About" +msgstr "À propos" + +#: objects/ui_MainWindow.h:815 +msgid "Documentation" +msgstr "Documentation" + +#: objects/ui_MainWindow.h:816 +msgid "Clear Recent" +msgstr "Effacer Récents" + +#: objects/ui_MainWindow.h:817 +msgid "Export as DXF..." +msgstr "Exporter comme DXF..." + +#: objects/ui_MainWindow.h:818 objects/ui_OpenCSGWarningDialog.h:94 +msgid "Close" +msgstr "Fermer" + +#: objects/ui_MainWindow.h:819 +msgid "Ctrl+W" +msgstr "Ctrl+W" + +#: objects/ui_MainWindow.h:820 objects/ui_Preferences.h:608 +msgid "Preferences" +msgstr "Préférences" + +#: objects/ui_MainWindow.h:821 +msgid "Find..." +msgstr "Rechercher..." + +#: objects/ui_MainWindow.h:822 +msgid "Ctrl+F" +msgstr "Ctrl+F" + +#: objects/ui_MainWindow.h:823 +msgid "Find and Replace..." +msgstr "Rechercher et remplacer..." + +#: objects/ui_MainWindow.h:824 +msgid "Ctrl+Alt+F" +msgstr "Ctrl+Alt+F" + +#: objects/ui_MainWindow.h:825 +msgid "Find Next" +msgstr "Rechercher Suivant" + +#: objects/ui_MainWindow.h:826 +msgid "Ctrl+G" +msgstr "Ctrl+G" + +#: objects/ui_MainWindow.h:827 +msgid "Find Previous" +msgstr "Rechercher Précédent" + +#: objects/ui_MainWindow.h:828 +msgid "Ctrl+Shift+G" +msgstr "Ctrl+Shift+G" + +#: objects/ui_MainWindow.h:829 +msgid "Use Selection for Find" +msgstr "Utiliser la sélection pour Rechercher" + +#: objects/ui_MainWindow.h:830 +msgid "Ctrl+E" +msgstr "Ctrl+E" + +#: objects/ui_MainWindow.h:831 +msgid "Flush Caches" +msgstr "Vider les caches" + +#: objects/ui_MainWindow.h:832 +msgid "OpenSCAD Homepage" +msgstr "Page d'accueil OpenSCAD" + +#: objects/ui_MainWindow.h:833 +msgid "Automatic Reload and Preview" +msgstr "Recharger et Aperçu Automatique" + +#: objects/ui_MainWindow.h:834 +msgid "Export as Image..." +msgstr "Exporter comme Image..." + +#: objects/ui_MainWindow.h:835 +msgid "Export as CSG..." +msgstr "Exporter comme CSG..." + +#: objects/ui_MainWindow.h:836 +msgid "Library info" +msgstr "Informations Bibliothèques" + +#: objects/ui_MainWindow.h:837 +msgid "Show Library Folder..." +msgstr "Afficher le dossier des bibliothèques" + +#: objects/ui_MainWindow.h:838 +msgid "Reset View" +msgstr "Réinitialiser la vue" + +#: objects/ui_MainWindow.h:839 +msgid "Font List" +msgstr "Liste des polices" + +#: objects/ui_MainWindow.h:840 +msgid "Export as SVG..." +msgstr "Exporter comme SVG..." + +#: objects/ui_MainWindow.h:841 +msgid "Export as AMF..." +msgstr "Exporter comme AMF..." + +#: objects/ui_MainWindow.h:843 +msgid "Ctrl+]" +msgstr "Ctrl+]" + +#: objects/ui_MainWindow.h:845 +msgid "Ctrl+[" +msgstr "Ctrl+[" + +#: objects/ui_MainWindow.h:846 +msgid "View All" +msgstr "&Voir Tout" + +#: objects/ui_MainWindow.h:847 +msgid "Convert Tabs to Spaces" +msgstr "Convertir les tabulations par des espaces" + +#: objects/ui_MainWindow.h:848 +msgid "Hide toolbars" +msgstr "Cacher les boîtes à outils" + +#: objects/ui_MainWindow.h:849 +msgid "Time:" +msgstr "Temps:" + +#: objects/ui_MainWindow.h:850 +msgid "FPS:" +msgstr "FPS:" + +#: objects/ui_MainWindow.h:851 +msgid "Steps:" +msgstr "Étapes:" + +#: objects/ui_MainWindow.h:852 +msgid "Dump Pictures" +msgstr "Vider les photos" + +#: objects/ui_MainWindow.h:853 +msgid "&File" +msgstr "&Fichier" + +#: objects/ui_MainWindow.h:854 +msgid "Recent Files" +msgstr "Fichiers Récents" + +#: objects/ui_MainWindow.h:856 +msgid "Export" +msgstr "Exporter" + +#: objects/ui_MainWindow.h:857 +msgid "&Edit" +msgstr "&Édition" + +#: objects/ui_MainWindow.h:858 +msgid "&Design" +msgstr "Conception" + +#: objects/ui_MainWindow.h:859 +msgid "&View" +msgstr "&Vue" + +#: objects/ui_MainWindow.h:860 +msgid "&Help" +msgstr "&Aide" + +#: objects/ui_MainWindow.h:863 +msgid "Find" +msgstr "Rechercher" + +#: objects/ui_MainWindow.h:864 objects/ui_MainWindow.h:871 +msgid "Replace" +msgstr "Remplacer" + +#: objects/ui_MainWindow.h:866 +msgid "Search string" +msgstr "Rechercher une chaîne de caractères" + +#: objects/ui_MainWindow.h:867 +msgid "<" +msgstr "<" + +#: objects/ui_MainWindow.h:868 +msgid ">" +msgstr ">" + +#: objects/ui_MainWindow.h:869 +msgid "Done" +msgstr "Terminer" + +#: objects/ui_MainWindow.h:870 +msgid "Replacement string" +msgstr "Remplacer une chaîne de caractères" + +#: objects/ui_MainWindow.h:872 +msgid "All" +msgstr "Tout" + +#: objects/ui_OpenCSGWarningDialog.h:86 +msgid "OpenGL Warning" +msgstr "Avertissements OpenGL" + +#: objects/ui_OpenCSGWarningDialog.h:87 +msgid "" +"\n" +"\n" +"

" +msgstr "" +"\n" +"\n" +"

" + +#: objects/ui_OpenCSGWarningDialog.h:92 +msgid "Enable OpenCSG" +msgstr "Activer OpenCSG" + +#: objects/ui_OpenCSGWarningDialog.h:93 +msgid "Show this message again" +msgstr "Affiche ce message à nouveau" + +#: objects/ui_Preferences.h:609 +msgid "3D View" +msgstr "&Vue 3D" + +#: objects/ui_Preferences.h:610 src/UIUtils.cc:85 +msgid "Advanced" +msgstr "Avancé" + +#: objects/ui_Preferences.h:611 src/mainwin.cc:2315 +msgid "Editor" +msgstr "Éditeur" + +#: objects/ui_Preferences.h:612 +msgid "Update" +msgstr "Mettre à jour" + +#: objects/ui_Preferences.h:613 objects/ui_Preferences.h:633 +msgid "Features" +msgstr "Fonctionnalités" + +#: objects/ui_Preferences.h:615 +msgid "Enable/Disable experimental features" +msgstr "Activer/Désactiver les fonctionnalités expérimentales" + +#: objects/ui_Preferences.h:617 +msgid "Color scheme:" +msgstr "Palette de couleurs:" + +#: objects/ui_Preferences.h:618 +msgid "Editor Type" +msgstr "Type d'éditeur" + +#: objects/ui_Preferences.h:621 +msgid "Simple Editor" +msgstr "Éditeur Simple" + +#: objects/ui_Preferences.h:622 +msgid "QScintilla Editor" +msgstr "Éditeur QScintilla" + +#: objects/ui_Preferences.h:624 +msgid "(requires restart)" +msgstr "(nécessite un redémarrage)" + +#: objects/ui_Preferences.h:625 +msgid "Font" +msgstr "Police" + +#: objects/ui_Preferences.h:626 +msgid "Color syntax highlighting" +msgstr "Colorer la coloration syntaxique" + +#: objects/ui_Preferences.h:627 +msgid "Use Ctrl/Cmd-Mouse-wheel to zoom text" +msgstr "Utiliser Ctrl/Cmd-Roulette-Souris pour agrandir le texte" + +#: objects/ui_Preferences.h:629 +msgid "Automatically check for updates" +msgstr "Vérifier les mises à jour automatiquement" + +#: objects/ui_Preferences.h:630 +msgid "Include development snapshots" +msgstr "Inclure les versions de développement" + +#: objects/ui_Preferences.h:631 +msgid "Check Now" +msgstr "Vérifier Maintenant" + +#: objects/ui_Preferences.h:632 +msgid "Last checked: " +msgstr "Dernière vérification:" + +#: objects/ui_Preferences.h:634 +msgid "OpenCSG" +msgstr "OpenCSG" + +#: objects/ui_Preferences.h:635 +msgid "Show capability warning" +msgstr "Afficher les avertissements de capacité" + +#: objects/ui_Preferences.h:636 +msgid "Enable for OpenGL 1.x" +msgstr "Activer pour OpenGL 1.x" + +#: objects/ui_Preferences.h:637 +msgid "Turn off rendering at " +msgstr "Désactiver le rendu à" + +#: objects/ui_Preferences.h:638 +msgid "elements" +msgstr "éléments" + +#: objects/ui_Preferences.h:639 +msgid "Force Goldfeather" +msgstr "Forcer Goldfeather" + +#: objects/ui_Preferences.h:640 +msgid "CGAL Cache size" +msgstr "Taille du Cache de CGAL" + +#: objects/ui_Preferences.h:641 objects/ui_Preferences.h:643 +msgid "bytes" +msgstr "octets" + +#: objects/ui_Preferences.h:642 +msgid "PolySet Cache size" +msgstr "Taille du Cache PolySet" + +#: objects/ui_Preferences.h:644 +msgid "Allow to open multiple documents" +msgstr "Autoriser l'ouverture de plusieurs documents" + +#: objects/ui_Preferences.h:645 +msgid "Enable docking of Editor and Console in different places" +msgstr "Activer l'ancrage de l'Éditeur et de la Console à différents endroits" + +#: objects/ui_Preferences.h:646 +msgid "Enable undocking of Editor and Console to separate windows" +msgstr "" +"Activer désancrage de l'Éditeur et de la Console dans des fenêtres séparés" + +#: objects/ui_Preferences.h:647 +msgid "Show Welcome Screen" +msgstr "Affiche l'écran d'accueil" + +#: objects/ui_Preferences.h:648 +msgid "Enable user interface localization (requires restart of OpenSCAD)" +msgstr "" +"Activer la localisation de l'interface utilisateur (Nécessite un redémarrage " +"d'OpenSCAD)" + +#: objects/ui_Preferences.h:649 +msgid "toolBar" +msgstr "boîte à outils" + +#: objects/ui_ProgressWidget.h:72 +msgid "Form" +msgstr "Formulaire" + +#: objects/ui_ProgressWidget.h:73 +msgid "%v / %m" +msgstr "%v / %m" + +#: src/mainwin.cc:768 src/mainwin.cc:1300 +msgid "Untitled.scad" +msgstr "Untitled.scad" + +#: src/mainwin.cc:1299 +msgid "Save File" +msgstr "Enregistrer le Fichier" + +#: src/mainwin.cc:1301 +msgid "OpenSCAD Designs (*.scad)" +msgstr "OpenSCAD Designs (*.scad)" + +#: src/mainwin.cc:1311 +msgid "" +"%1 already exists.\n" +"Do you want to replace it?" +msgstr "" +"%1 existe déjà.\n" +"Voulez-vous le remplacer?" + +#: src/mainwin.cc:1630 +msgid "Application" +msgstr "Application" + +#: src/mainwin.cc:1631 +msgid "" +"The document has been modified.\n" +"Do you really want to reload the file?" +msgstr "" +"Ce document a été modifié.\n" +"Voulez-vous vraiment recharger le fichier?" + +#: src/mainwin.cc:1942 src/mainwin.cc:1999 +msgid "Export %1 File" +msgstr "Exporter %1 Fichier" + +#: src/mainwin.cc:1943 src/mainwin.cc:2003 +msgid "%1 Files (*%2)" +msgstr "%1 Fichiers (*%2)" + +#: src/mainwin.cc:1944 +msgid "Untitled" +msgstr "Sans Titre" + +#: src/mainwin.cc:2001 +msgid "Untitled%1" +msgstr "Sans Titre%1" + +#: src/mainwin.cc:2052 +msgid "Export CSG File" +msgstr "Exporter un fichier CSG" + +#: src/mainwin.cc:2053 +msgid "Untitled.csg" +msgstr "SansTitre.csg" + +#: src/mainwin.cc:2054 +msgid "CSG Files (*.csg)" +msgstr "Fichiers CSG (*.csg)" + +#: src/mainwin.cc:2080 +msgid "Export Image" +msgstr "Exporter une Image" + +#: src/mainwin.cc:2080 +msgid "PNG Files (*.png)" +msgstr "Fichiers PNG (*.png)" + +#: src/mainwin.cc:2320 +msgid "Console" +msgstr "Console" + +#: src/mainwin.cc:2447 +msgid "The document has been modified." +msgstr "Ce document a été modifié" + +#: src/mainwin.cc:2448 +msgid "Do you want to save your changes?" +msgstr "Voulez-vous enregistrer vos changements?" + +#: src/QGLView.cc:114 +msgid "" +"\n" +"Using QGLWidget\n" +"\n" +msgstr "" +"\n" +"Utilise QGLWidget\n" +"\n" + +#: src/QGLView.cc:131 +msgid "" +"Warning: You may experience OpenCSG rendering errors.\n" +"\n" +msgstr "" +"Avertissement: Vous pourriez avoir des erreurs de rendu OpenCSG\n" +"\n" + +#: src/QGLView.cc:134 +msgid "" +"Warning: Missing OpenGL capabilities for OpenCSG - OpenCSG has been " +"disabled.\n" +"\n" +msgstr "" +"Avertissement: Capacités OpenGL manquantes pour OpenCSG - OpenCSG a été " +"désactivé.\n" +"\n" + +#: src/QGLView.cc:137 +msgid "" +"It is highly recommended to use OpenSCAD on a system with OpenGL 2.0 or " +"later.\n" +"Your renderer information is as follows:\n" +msgstr "" +"Il est hautement recommandé d'utiliser OpenSCAD sur un système compatible " +"OpenGL 2.0 ou ultérieur.\n" +"Voici les informations de votre moteur de rendu:\n" + +#: src/QGLView.cc:141 +#, c-format +msgid "" +"GLEW version %s\n" +"%s (%s)\n" +"OpenGL version %s\n" +msgstr "" +"Version GLEW %s\n" +"%s (%s)\n" +"Version OpenGL %s\n" + +#: src/QGLView.cc:171 +#, c-format +msgid "" +"Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], " +"distance = %.2f" +msgstr "" +"Fenêtre de rendu: translation = [ %.2f %.2f %.2f ], rotation = [ %.2f %.2f " +"%.2f ], distance = %.2f" + +#: src/UIUtils.cc:85 +msgid "Basics" +msgstr "Bases" + +#: src/UIUtils.cc:85 +msgid "Shapes" +msgstr "Formes" + +#: src/UIUtils.cc:85 +msgid "Extrusion" +msgstr "Extrusion" + +#~ msgid "Paste font selector to Editor Window" +#~ msgstr "Coller le sélecteur de polices dans l'éditeur de fenêtres" + +#~ msgid "About OpenSCAD " +#~ msgstr "À propos de OpenSCAD" + +#~ msgid "Check for Update.." +#~ msgstr "Vérifier les mises à jours" + +#~ msgid "OpenGL Info" +#~ msgstr "Information OpenGL" diff --git a/locale/openscad.pot b/locale/openscad.pot index 4462daad..b3587cc0 100644 --- a/locale/openscad.pot +++ b/locale/openscad.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: OpenSCAD 2014.11.13\n" +"Project-Id-Version: OpenSCAD 2014.12.22\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-11-13 00:22+0100\n" +"POT-Creation-Date: 2014-12-22 23:37+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: objects/ui_AboutDialog.h:51 +#: objects/ui_AboutDialog.h:51 src/AboutDialog.h:15 msgid "About OpenSCAD" msgstr "" @@ -29,19 +29,15 @@ msgstr "" msgid "&OK" msgstr "" -#: objects/ui_FontListDialog.h:105 -msgid "Paste font selector to Editor Window" -msgstr "" - -#: objects/ui_FontListDialog.h:107 +#: objects/ui_FontListDialog.h:104 msgid "Copy to Clipboard" msgstr "" -#: objects/ui_FontListDialog.h:108 +#: objects/ui_FontListDialog.h:105 msgid "Filter:" msgstr "" -#: objects/ui_FontListDialog.h:109 +#: objects/ui_FontListDialog.h:106 msgid "" "

This list shows the fonts currently registered with " "OpenSCAD.

Example:

"
 msgstr ""
 
-#: objects/ui_MainWindow.h:872
+#: objects/ui_MainWindow.h:869
 msgid "Done"
 msgstr ""
 
-#: objects/ui_MainWindow.h:873
+#: objects/ui_MainWindow.h:870
 msgid "Replacement string"
 msgstr ""
 
-#: objects/ui_MainWindow.h:875
+#: objects/ui_MainWindow.h:872
 msgid "All"
 msgstr ""
 
@@ -691,7 +683,7 @@ msgstr ""
 msgid "Advanced"
 msgstr ""
 
-#: objects/ui_Preferences.h:611 src/mainwin.cc:2339
+#: objects/ui_Preferences.h:611 src/mainwin.cc:2315
 msgid "Editor"
 msgstr ""
 
@@ -823,83 +815,79 @@ msgstr ""
 msgid "%v / %m"
 msgstr ""
 
-#: src/AboutDialog.h:15
-msgid "About OpenSCAD "
-msgstr ""
-
-#: src/mainwin.cc:773 src/mainwin.cc:1315
+#: src/mainwin.cc:768 src/mainwin.cc:1300
 msgid "Untitled.scad"
 msgstr ""
 
-#: src/mainwin.cc:1314
+#: src/mainwin.cc:1299
 msgid "Save File"
 msgstr ""
 
-#: src/mainwin.cc:1316
+#: src/mainwin.cc:1301
 msgid "OpenSCAD Designs (*.scad)"
 msgstr ""
 
-#: src/mainwin.cc:1326
+#: src/mainwin.cc:1311
 msgid ""
 "%1 already exists.\n"
 "Do you want to replace it?"
 msgstr ""
 
-#: src/mainwin.cc:1654
+#: src/mainwin.cc:1630
 msgid "Application"
 msgstr ""
 
-#: src/mainwin.cc:1655
+#: src/mainwin.cc:1631
 msgid ""
 "The document has been modified.\n"
 "Do you really want to reload the file?"
 msgstr ""
 
-#: src/mainwin.cc:1966 src/mainwin.cc:2023
+#: src/mainwin.cc:1942 src/mainwin.cc:1999
 msgid "Export %1 File"
 msgstr ""
 
-#: src/mainwin.cc:1967 src/mainwin.cc:2027
+#: src/mainwin.cc:1943 src/mainwin.cc:2003
 msgid "%1 Files (*%2)"
 msgstr ""
 
-#: src/mainwin.cc:1968
+#: src/mainwin.cc:1944
 msgid "Untitled"
 msgstr ""
 
-#: src/mainwin.cc:2025
+#: src/mainwin.cc:2001
 msgid "Untitled%1"
 msgstr ""
 
-#: src/mainwin.cc:2076
+#: src/mainwin.cc:2052
 msgid "Export CSG File"
 msgstr ""
 
-#: src/mainwin.cc:2077
+#: src/mainwin.cc:2053
 msgid "Untitled.csg"
 msgstr ""
 
-#: src/mainwin.cc:2078
+#: src/mainwin.cc:2054
 msgid "CSG Files (*.csg)"
 msgstr ""
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "Export Image"
 msgstr ""
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "PNG Files (*.png)"
 msgstr ""
 
-#: src/mainwin.cc:2344
+#: src/mainwin.cc:2320
 msgid "Console"
 msgstr ""
 
-#: src/mainwin.cc:2471
+#: src/mainwin.cc:2447
 msgid "The document has been modified."
 msgstr ""
 
-#: src/mainwin.cc:2472
+#: src/mainwin.cc:2448
 msgid "Do you want to save your changes?"
 msgstr ""
 
diff --git a/locale/ru.po b/locale/ru.po
index 4f64a3de..8fc11980 100644
--- a/locale/ru.po
+++ b/locale/ru.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: OpenSCAD 2014.01.05\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-11-13 00:22+0100\n"
+"POT-Creation-Date: 2014-12-22 23:28+0100\n"
 "PO-Revision-Date: 2013-02-24 17:50+0100\n"
 "Last-Translator:  \n"
 "Language-Team: Russian\n"
@@ -18,7 +18,7 @@ msgstr ""
 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 
-#: objects/ui_AboutDialog.h:51
+#: objects/ui_AboutDialog.h:51 src/AboutDialog.h:15
 msgid "About OpenSCAD"
 msgstr "О программе OpenSCAD"
 
@@ -31,19 +31,15 @@ msgstr "Шрифт"
 msgid "&OK"
 msgstr ""
 
-#: objects/ui_FontListDialog.h:105
-msgid "Paste font selector to Editor Window"
-msgstr ""
-
-#: objects/ui_FontListDialog.h:107
+#: objects/ui_FontListDialog.h:104
 msgid "Copy to Clipboard"
 msgstr ""
 
-#: objects/ui_FontListDialog.h:108
+#: objects/ui_FontListDialog.h:105
 msgid "Filter:"
 msgstr ""
 
-#: objects/ui_FontListDialog.h:109
+#: objects/ui_FontListDialog.h:106
 msgid ""
 "

This list shows the fonts currently registered with " "OpenSCAD.

Example:

"
 msgstr ""
 
-#: objects/ui_MainWindow.h:872
+#: objects/ui_MainWindow.h:869
 msgid "Done"
 msgstr ""
 
-#: objects/ui_MainWindow.h:873
+#: objects/ui_MainWindow.h:870
 #, fuzzy
 msgid "Replacement string"
 msgstr "элементах"
 
-#: objects/ui_MainWindow.h:875
+#: objects/ui_MainWindow.h:872
 msgid "All"
 msgstr ""
 
@@ -710,7 +702,7 @@ msgstr "3D Вид"
 msgid "Advanced"
 msgstr "Дополнительные"
 
-#: objects/ui_Preferences.h:611 src/mainwin.cc:2339
+#: objects/ui_Preferences.h:611 src/mainwin.cc:2315
 msgid "Editor"
 msgstr "Редактор"
 
@@ -844,89 +836,85 @@ msgstr ""
 msgid "%v / %m"
 msgstr ""
 
-#: src/AboutDialog.h:15
-msgid "About OpenSCAD "
-msgstr ""
-
-#: src/mainwin.cc:773 src/mainwin.cc:1315
+#: src/mainwin.cc:768 src/mainwin.cc:1300
 msgid "Untitled.scad"
 msgstr "Безымянный.scad"
 
-#: src/mainwin.cc:1314
+#: src/mainwin.cc:1299
 msgid "Save File"
 msgstr "Сохранить файл"
 
-#: src/mainwin.cc:1316
+#: src/mainwin.cc:1301
 msgid "OpenSCAD Designs (*.scad)"
 msgstr "Модели OpenSCAD (*.scad)"
 
-#: src/mainwin.cc:1326
+#: src/mainwin.cc:1311
 msgid ""
 "%1 already exists.\n"
 "Do you want to replace it?"
 msgstr ""
 
-#: src/mainwin.cc:1654
+#: src/mainwin.cc:1630
 msgid "Application"
 msgstr ""
 
-#: src/mainwin.cc:1655
+#: src/mainwin.cc:1631
 msgid ""
 "The document has been modified.\n"
 "Do you really want to reload the file?"
 msgstr ""
 
-#: src/mainwin.cc:1966 src/mainwin.cc:2023
+#: src/mainwin.cc:1942 src/mainwin.cc:1999
 #, fuzzy
 msgid "Export %1 File"
 msgstr "Экспортировать в DXF..."
 
-#: src/mainwin.cc:1967 src/mainwin.cc:2027
+#: src/mainwin.cc:1943 src/mainwin.cc:2003
 msgid "%1 Files (*%2)"
 msgstr ""
 
-#: src/mainwin.cc:1968
+#: src/mainwin.cc:1944
 #, fuzzy
 msgid "Untitled"
 msgstr "Безымянный.scad"
 
-#: src/mainwin.cc:2025
+#: src/mainwin.cc:2001
 #, fuzzy
 msgid "Untitled%1"
 msgstr "Безымянный.scad"
 
-#: src/mainwin.cc:2076
+#: src/mainwin.cc:2052
 msgid "Export CSG File"
 msgstr ""
 
-#: src/mainwin.cc:2077
+#: src/mainwin.cc:2053
 msgid "Untitled.csg"
 msgstr ""
 
-#: src/mainwin.cc:2078
+#: src/mainwin.cc:2054
 msgid "CSG Files (*.csg)"
 msgstr ""
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "Export Image"
 msgstr ""
 
-#: src/mainwin.cc:2104
+#: src/mainwin.cc:2080
 msgid "PNG Files (*.png)"
 msgstr ""
 
-#: src/mainwin.cc:2344
+#: src/mainwin.cc:2320
 msgid "Console"
 msgstr ""
 
-#: src/mainwin.cc:2471
+#: src/mainwin.cc:2447
 #, fuzzy
 msgid "The document has been modified."
 msgstr ""
 "Документ был изменен.\n"
 "Сохранить изменения?"
 
-#: src/mainwin.cc:2472
+#: src/mainwin.cc:2448
 #, fuzzy
 msgid "Do you want to save your changes?"
 msgstr ""
@@ -987,6 +975,9 @@ msgstr ""
 msgid "Extrusion"
 msgstr ""
 
+#~ msgid "Check for Update.."
+#~ msgstr "Проверить обновления..."
+
 #~ msgid "Off"
 #~ msgstr "Выключить"
 
diff --git a/src/AboutDialog.h b/src/AboutDialog.h
index 76055b23..a8e28a1e 100644
--- a/src/AboutDialog.h
+++ b/src/AboutDialog.h
@@ -12,7 +12,7 @@ class AboutDialog : public QDialog, public Ui::AboutDialog
 public:
 	AboutDialog(QWidget *) {
 		setupUi(this);
-		this->setWindowTitle( QString(_("About OpenSCAD ")) + QString(TOSTRING( OPENSCAD_VERSION)) );
+		this->setWindowTitle( QString(_("About OpenSCAD")) + " " + QString(TOSTRING( OPENSCAD_VERSION)) );
 		this->aboutText->setOpenExternalLinks(true);
 		QUrl flattr_qurl(":icons/flattr.png" );
 		this->aboutText->loadResource( QTextDocument::ImageResource, flattr_qurl );
diff --git a/src/FontListDialog.ui b/src/FontListDialog.ui
index 7313f3b6..dda5eb1b 100644
--- a/src/FontListDialog.ui
+++ b/src/FontListDialog.ui
@@ -35,9 +35,6 @@
    
    
     
-     
-      Paste font selector to Editor Window
-     
      
       Copy to Clipboard
      

From b2227c719169357a8eb929e04456491697a0b1e2 Mon Sep 17 00:00:00 2001
From: Torsten Paul 
Date: Tue, 23 Dec 2014 00:05:42 +0100
Subject: [PATCH 180/263] Quote special characters when copying the font
 selector.

---
 src/FontListDialog.cc | 27 ++++++++++++++++++++++++++-
 src/FontListDialog.h  |  2 ++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/FontListDialog.cc b/src/FontListDialog.cc
index 0ee7ef59..f515774c 100644
--- a/src/FontListDialog.cc
+++ b/src/FontListDialog.cc
@@ -66,7 +66,7 @@ void FontListDialog::selection_changed(const QItemSelection ¤t, const QIte
 	const QModelIndex &idx = proxy->mapToSource(current.indexes().at(0));
 	const QString name = model->item(idx.row(), 0)->text();
 	const QString style = model->item(idx.row(), 1)->text();
-	selection = QString("\"%1:style=%2\"").arg(name).arg(style);
+	selection = QString("\"%1:style=%2\"").arg(quote(name)).arg(quote(style));
 	copyButton->setEnabled(true);
 }
 
@@ -117,3 +117,28 @@ void FontListDialog::update_font_list()
 
 	delete list;
 }
+
+/**
+ * Quote a string according to the requirements of font-config.
+ * See http://www.freedesktop.org/software/fontconfig/fontconfig-user.html
+ *
+ * The '\', '-', ':' and ',' characters in family names must be preceded
+ * by a '\' character to avoid having them misinterpreted. Similarly, values
+ * containing '\', '=', '_', ':' and ',' must also have them preceded by a
+ * '\' character. The '\' characters are stripped out of the family name and
+ * values as the font name is read.
+ *
+ * @param text unquoted string
+ * @return quoted text
+ */
+QString FontListDialog::quote(const QString& text)
+{
+	QString result = text;
+	result.replace('\\', "\\\\")
+		.replace('-', "\\-")
+		.replace(':', "\\:")
+		.replace(',', "\\,")
+		.replace('=', "\\=")
+		.replace('_', "\\_");
+	return result;
+}
diff --git a/src/FontListDialog.h b/src/FontListDialog.h
index 9f9a2532..5624f833 100644
--- a/src/FontListDialog.h
+++ b/src/FontListDialog.h
@@ -27,6 +27,8 @@ signals:
         void font_selected(const QString font);
 
 private:
+        QString quote(const QString& text);
+
         QString selection;
         QStandardItemModel *model;
         QSortFilterProxyModel *proxy;

From aeba95aa011b400bf065097ca7d62ea30a6b6862 Mon Sep 17 00:00:00 2001
From: Marius Kintel 
Date: Mon, 22 Dec 2014 18:58:25 -0500
Subject: [PATCH 181/263] Windows build fix (msys2)

---
 qscintilla2.prf | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/qscintilla2.prf b/qscintilla2.prf
index 754f5614..0215ac0c 100644
--- a/qscintilla2.prf
+++ b/qscintilla2.prf
@@ -26,9 +26,13 @@ CONFIG(debug, debug|release) {
 	}
     }
 } else {
-    greaterThan(QT_MAJOR_VERSION, 4) {
-	LIBS += -lqt5scintilla2
+    win32: {
+        LIBS += -lqscintilla2
     } else {
-	LIBS += -lqscintilla2
+        greaterThan(QT_MAJOR_VERSION, 4) {
+	    LIBS += -lqt5scintilla2
+        } else {
+	    LIBS += -lqscintilla2
+        }
     }
 }

From 77a568cda081c10d49c8365256de2fdeb4549570 Mon Sep 17 00:00:00 2001
From: Marius Kintel 
Date: Mon, 22 Dec 2014 19:31:40 -0500
Subject: [PATCH 182/263] Less verbose

---
 scripts/translation-make.sh | 2 --
 1 file changed, 2 deletions(-)

diff --git a/scripts/translation-make.sh b/scripts/translation-make.sh
index 89ebd91e..5fadf01d 100755
--- a/scripts/translation-make.sh
+++ b/scripts/translation-make.sh
@@ -11,5 +11,3 @@ cd "$TOPDIR" || exit 1
 
 echo "Compiling language files..."
 ./scripts/translation-update.sh updatemo
-
-echo "Done."

From c4e895a81364a04c36aba74be82223962f916842 Mon Sep 17 00:00:00 2001
From: Torsten Paul 
Date: Tue, 23 Dec 2014 03:07:27 +0100
Subject: [PATCH 183/263] Add drag&drop to the FontListDialog.

---
 openscad.pro             |  2 ++
 src/FontListDialog.cc    |  2 ++
 src/FontListDialog.h     |  3 --
 src/FontListDialog.ui    | 19 +++++++++++-
 src/FontListTableView.cc | 66 ++++++++++++++++++++++++++++++++++++++++
 src/FontListTableView.h  | 18 +++++++++++
 6 files changed, 106 insertions(+), 4 deletions(-)
 create mode 100644 src/FontListTableView.cc
 create mode 100644 src/FontListTableView.h

diff --git a/openscad.pro b/openscad.pro
index c90942ea..92f1b720 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -259,6 +259,7 @@ HEADERS += src/typedefs.h \
            src/OpenCSGWarningDialog.h \
            src/AboutDialog.h \
            src/FontListDialog.h \
+           src/FontListTableView.h \
            src/builtin.h \
            src/calc.h \
            src/context.h \
@@ -428,6 +429,7 @@ SOURCES += src/version_check.cc \
            src/UIUtils.cc \
            src/Dock.cc \
            src/FontListDialog.cc \
+           src/FontListTableView.cc \
            src/launchingscreen.cc \
            src/legacyeditor.cc \
            src/LibraryInfoDialog.cc
diff --git a/src/FontListDialog.cc b/src/FontListDialog.cc
index f515774c..474c2ef3 100644
--- a/src/FontListDialog.cc
+++ b/src/FontListDialog.cc
@@ -60,6 +60,7 @@ void FontListDialog::selection_changed(const QItemSelection ¤t, const QIte
 {
 	if (current.count() == 0) {
 		copyButton->setEnabled(false);
+		tableView->setDragText("");
 		return;
 	}
 	
@@ -68,6 +69,7 @@ void FontListDialog::selection_changed(const QItemSelection ¤t, const QIte
 	const QString style = model->item(idx.row(), 1)->text();
 	selection = QString("\"%1:style=%2\"").arg(quote(name)).arg(quote(style));
 	copyButton->setEnabled(true);
+	tableView->setDragText(selection);
 }
 
 void FontListDialog::update_font_list()
diff --git a/src/FontListDialog.h b/src/FontListDialog.h
index 5624f833..d1927631 100644
--- a/src/FontListDialog.h
+++ b/src/FontListDialog.h
@@ -6,9 +6,6 @@
 #include "qtgettext.h"
 #include "ui_FontListDialog.h"
 
-#define STRINGIFY(x) #x
-#define TOSTRING(x) STRINGIFY(x)
-
 class FontListDialog : public QDialog, public Ui::FontListDialog
 {
 	Q_OBJECT;
diff --git a/src/FontListDialog.ui b/src/FontListDialog.ui
index dda5eb1b..70ff4fff 100644
--- a/src/FontListDialog.ui
+++ b/src/FontListDialog.ui
@@ -67,7 +67,17 @@
     
    
    
-    
+    
+     
+      true
+     
+     
+      QAbstractItemView::DragOnly
+     
+     
+      QAbstractItemView::SelectRows
+     
+    
    
    
     
@@ -100,6 +110,13 @@
    
   
  
+ 
+  
+   FontListTableView
+   QTableView
+   
FontListTableView.h
+
+
diff --git a/src/FontListTableView.cc b/src/FontListTableView.cc new file mode 100644 index 00000000..b013d81f --- /dev/null +++ b/src/FontListTableView.cc @@ -0,0 +1,66 @@ +/* + * 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 +#include +#include +#include + +#include "qtgettext.h" +#include "FontListDialog.h" + +FontListTableView::FontListTableView(QWidget *parent) : QTableView(parent) +{ +} + +void FontListTableView::setDragText(const QString &text) +{ + this->text = text.trimmed(); +} + +void FontListTableView::startDrag(Qt::DropActions supportedActions) +{ + if (text.isEmpty()) { + return; + } + + QMimeData *mimeData = new QMimeData; + mimeData->setText(text); + + QFontMetrics fm(font()); + QRect rect(0, 0, fm.width(text), fm.height()); + QPixmap pixmap(rect.width(), rect.height()); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); + painter.setFont(font()); + painter.drawText(rect, Qt::AlignCenter, text); + + QDrag *drag = new QDrag(this); + drag->setPixmap(pixmap); + drag->setMimeData(mimeData); + drag->setHotSpot(QPoint(-10, rect.height() + 6)); + drag->exec(supportedActions, Qt::CopyAction); +} diff --git a/src/FontListTableView.h b/src/FontListTableView.h new file mode 100644 index 00000000..70348c46 --- /dev/null +++ b/src/FontListTableView.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +class FontListTableView : public QTableView +{ + Q_OBJECT; + +public: + FontListTableView(QWidget *parent = NULL); + void setDragText(const QString &text); + +protected: + void startDrag(Qt::DropActions supportedActions); + +private: + QString text; +}; From 5ad36c82b69e4fecd27f3a861d2284928554cb76 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 03:33:42 +0100 Subject: [PATCH 184/263] Add OpenSCAD version to the status bar. --- src/mainwin.cc | 13 ++++++++++--- src/openscad.cc | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/mainwin.cc b/src/mainwin.cc index 8f399c21..684b9fc9 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -127,12 +127,16 @@ unsigned int GuiLocker::gui_locked = 0; #define QUOTE(x__) # x__ #define QUOTED(x__) QUOTE(x__) -static char helptitle[] = - "OpenSCAD " QUOTED(OPENSCAD_VERSION) +static std::string versionnumber = QUOTED(OPENSCAD_VERSION) #ifdef OPENSCAD_COMMIT " (git " QUOTED(OPENSCAD_COMMIT) ")" #endif - "\nhttp://www.openscad.org\n\n"; +; + +static std::string openscad_version = "OpenSCAD " + versionnumber; + +static std::string helptitle = openscad_version + "\nhttp://www.openscad.org\n\n"; + static char copyrighttext[] = "Copyright (C) 2009-2014 The OpenSCAD Developers\n" "\n" @@ -189,6 +193,9 @@ MainWindow::MainWindow(const QString &filename) this->consoleDock->setConfigKey("view/hideConsole"); this->consoleDock->setAction(this->viewActionHideConsole); + QLabel *versionLabel = new QLabel(openscad_version.c_str()); + this->statusbar->addPermanentWidget(versionLabel); + QSettings settings; editortype = settings.value("editor/editortype").toString(); useScintilla = (editortype != "Simple Editor"); diff --git a/src/openscad.cc b/src/openscad.cc index 89d2bf12..47ff6461 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -616,6 +616,9 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha } #endif QApplication app(argc, argv, true); //useGUI); + // remove ugly frames in the QStatusBar when using additional widgets + app.setStyleSheet("QStatusBar::item { border: 0px solid black }; "); + #ifdef Q_OS_MAC app.installEventFilter(new EventFilter(&app)); #endif From b37b49f4078e22b305e773639f05d74f70f637f8 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 03:56:17 +0100 Subject: [PATCH 185/263] Add version number to launching screen and main windows (fixes #1101). --- src/launchingscreen.cc | 9 ++++++--- src/launchingscreen.ui | 36 +++++++++++++++++++++++++++++------- src/mainwin.cc | 12 +----------- src/openscad.cc | 11 +++++++++++ src/openscad.h | 8 ++++++++ 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/launchingscreen.cc b/src/launchingscreen.cc index 4f08b7d0..3a27f7e4 100644 --- a/src/launchingscreen.cc +++ b/src/launchingscreen.cc @@ -2,6 +2,7 @@ #include #include +#include "openscad.h" #include "launchingscreen.h" #include "ui_launchingscreen.h" @@ -26,7 +27,9 @@ LaunchingScreen::LaunchingScreen(QWidget *parent) : QDialog(parent) setupUi(this); this->setStyleSheet("QDialog {background-image:url(':/icons/background.png')}" "QPushButton {color:white;}"); - + + this->versionNumberLabel->setText(openscad_version.c_str()); + QStringList recentFiles = UIUtils::recentFiles(); for (int a = 0;a < recentFiles.size();a++) { QFileInfo fileInfo(recentFiles[a]); @@ -75,7 +78,7 @@ QString LaunchingScreen::selectedFile() return this->selection; } -void LaunchingScreen::enableRecentButton(const QModelIndex & current, const QModelIndex & previous) +void LaunchingScreen::enableRecentButton(const QModelIndex &, const QModelIndex &) { this->openRecentButton->setEnabled(true); this->openRecentButton->setDefault(true); @@ -91,7 +94,7 @@ void LaunchingScreen::openRecent() checkOpen(item->data(Qt::UserRole)); } -void LaunchingScreen::enableExampleButton(QTreeWidgetItem *current, QTreeWidgetItem *previous) +void LaunchingScreen::enableExampleButton(QTreeWidgetItem *current, QTreeWidgetItem *) { const bool enable = current->childCount() == 0; this->openExampleButton->setEnabled(enable); diff --git a/src/launchingscreen.ui b/src/launchingscreen.ui index 67a7d1ea..cd4c8cd8 100644 --- a/src/launchingscreen.ui +++ b/src/launchingscreen.ui @@ -6,10 +6,16 @@ 0 0 - 618 + 620 418 + + + 600 + 0 + + Welcome to OpenSCAD @@ -331,16 +337,32 @@ QPushButton:pressed { - + + + + + 0 + 0 + + + + Version + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + true - - - 600 - 0 - + + + 0 + 0 + false diff --git a/src/mainwin.cc b/src/mainwin.cc index 684b9fc9..620d9fec 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -24,6 +24,7 @@ * */ #include +#include "openscad.h" #include "GeometryCache.h" #include "ModuleCache.h" #include "MainWindow.h" @@ -124,17 +125,6 @@ QSet *MainWindow::getWindows() // Global application state unsigned int GuiLocker::gui_locked = 0; -#define QUOTE(x__) # x__ -#define QUOTED(x__) QUOTE(x__) - -static std::string versionnumber = QUOTED(OPENSCAD_VERSION) -#ifdef OPENSCAD_COMMIT - " (git " QUOTED(OPENSCAD_COMMIT) ")" -#endif -; - -static std::string openscad_version = "OpenSCAD " + versionnumber; - static std::string helptitle = openscad_version + "\nhttp://www.openscad.org\n\n"; static char copyrighttext[] = diff --git a/src/openscad.cc b/src/openscad.cc index 47ff6461..293918ae 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -90,6 +90,17 @@ std::string currentdir; static bool arg_info = false; static std::string arg_colorscheme; +#define QUOTE(x__) # x__ +#define QUOTED(x__) QUOTE(x__) + +std::string openscad_versionnumber = QUOTED(OPENSCAD_VERSION) +#ifdef OPENSCAD_COMMIT + " (git " QUOTED(OPENSCAD_COMMIT) ")" +#endif +; + +std::string openscad_version = "OpenSCAD " + openscad_versionnumber; + class Echostream : public std::ofstream { public: diff --git a/src/openscad.h b/src/openscad.h index 0e979659..f37f0253 100644 --- a/src/openscad.h +++ b/src/openscad.h @@ -34,3 +34,11 @@ extern std::string commandline_commands; // The CWD when application started. We shouldn't change CWD, but until we stop // doing this, use currentdir to get the original CWD. extern std::string currentdir; + +extern std::string versionnumber; + +// Just the number (might have the git commit as suffix), e.g. 2014.12.23. +extern std::string openscad_versionnumber; + +// The string "OpenSCAD " and the version number. +extern std::string openscad_version; From 4c11d6b62f09a035f24e31811a27a1ea721669bf Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 23 Dec 2014 00:09:05 -0500 Subject: [PATCH 186/263] Updated test results for offset tests --- .../cgalpngtest/offset-tests-expected.png | Bin 4980 -> 8621 bytes .../opencsgtest/offset-tests-expected.png | Bin 3846 -> 7396 bytes .../offset-tests-expected.png | Bin 3869 -> 7424 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/regression/cgalpngtest/offset-tests-expected.png b/tests/regression/cgalpngtest/offset-tests-expected.png index fbcd7248bf689cec8e19ba0c7a47c4dc599965a7..3da4452ba21358a8b6113f2129167febbf922208 100644 GIT binary patch literal 8621 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

u6X6t!8jW8P-a&c{1fL< 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 literal 3846 zcmds4c{r8p7GK}qwt3vdHg8kNkV2V& zmtyG`aa>&MnU#y(9M+0vuA@??g%NUr)M@ReQ89h;;f2`Nt4Wz5{0w$~ypbYT;BeMr zsbQC2*O?REK3_R`dM{kb%?r4oNqA(nnq;o!+0>5TDsp%{%}nmu17Za}aQUv>h#Icr zHqZVJaYVtg5D-eS#AxTJ$ExW)B^97K^hb)l%ewWL-$vx}0`Vz6Zi2Mh@(;$4B@0vlmihYCaq6-mXn zav!s#_6x<2ozG<_hEsf zZ*b%fdB63>s#8%@0{UdW&)Rm8KN-(N28ebcld5xb{Zy`nw9;JxJ5rNtq`SNaW( zk9-XdZDmxcgdnT)Ej2=gLWg0kWO-RZaGnfl^}Tdm{qd~E_W6!w90zPrK6}i3S>gAw z*=9D6mEoHgbEe9sGqBvb*mzY5@n=>B;lRA#Ptb&_K#j&yY)N1+^zq?s+L^M z9-`+V1Q_WGsJN@Qn8UVEVlRj3)ZQxtPI-J0I5g7OpbSwjjgnnmYe`Z>CHV@tA=wlW zi<{`)e9}!sEfrAp<1N8{o>xb*sY3U0BwVz=z@Xh+`wNnrcB1nUP~$D6NP9HUcDXpQ zQ_`$N4_dC@rf-_mw1vfsY=mv{ODdpS0pj?FdL0r3UTEbr;u0{*(Ubqo3X}+(ma_GG z-2)S$Co}q_@~3t@1xn`gM^ARdd`Ka=>E(W}SAZxhS`m|sOY_WVO^IUR6c2VvBbD>5Hzy3H zL+x=dHaKhtEVM9W@fL1X`E9dqt%Zglx?cf~M;_O<8mEizb{Cgf&?t;5TxP)tHxvoF zEEnU!+onuv-q><#8F*!&hz7GeondMd_A^0(I$lK^o^`>gnQY(9+z?W0esnpe<2vQ^ zb(%dCa)T5P> zLV7kASySUFS>Z`N(kj<;eI8pT_3LH3AVqpNC(fmap0Cft!!JHusf9CkE1J1+H7#X( z@o02l&uORrvRFMcAq5U0qeP$kH?BDsU+CW&zBt4;l~D)@+4is|daNvM&4>+Io8cgL zoaGYO;YJ=xXD}wr0??aYz=49! zj*t7h5-Mey(of-Nf|Fsp4dr!4XcSs;ilG)U9Mgy_o^(cr-s2113eg!8S%H7;Bkt2iaRXs1iGp)xUd15CDBQk z|Lt|c=&uQ7uFoH;R|-}X?`U+Qhe}N3M_Y?|jtaczyz!(bTG+>Lg=TPHyuf|9K&MC2 z1y?E!s_orAlOu~7L1k%XSCQm%(f5juzG!afJ7g0+CKD3B9CUit$1PWa9sU?e=A>5z zAN^X?8|`me?d!1+Y~2}nXKvYANvq~r>-&wJ9DtH^nW_Dpyg;+=7h(-%g8k=Q>#i|@ zk$vnW4wXzOtGeNwNOb9=6n*ItZ~@q}Ey8HXIf&Sei?|qqu5~8?cn@N1EQPDWs~%t{3r8lRgK`x7sDxg z)mN;i%pL=2&|QAiokO%!r|O#RyiD~ktrrBr)KT7Aq+InAnpzTbIWtW(aBE}ZJbfVC z_RUWNQ*B3o*6DcL{d3vJ)M-D$^G{dP^BR!(echSj*$(LV2Np&@`KEukbiqH8d$q}v zv)>mMGT(LiD|VKzKWfI!_i93Fz99aYA>-%@1hB^O1N$wAsr&Te50?Cu{@%jBIDmlwl&Vxx*HO? zl6Kmr){m8FrbfK%!H+ym4d{?G>{>adA7p1X_ik4F z%aXP0)jL*8IY`&{(oC}h>$i&6Mr77LzzXM3O>K2*3JqY*o&;*I>%v7+cs@Dp%1RP zpI>5ezR{Cdan?V>?AS+lkQ6hWh;}>XwFCjhAw1OnwHn*n7fd6A@e^oLz<@E#8Kkj)GWvj_e3YsxJ(zOXJ@Z1F$23Yrk9O9{=fLeT2MP2 z@M5q2Kal_53A?Z1=kHYN>;yp1kj94n^=D2om_SeJZ_w$p{ri}bkG!bV;l+l&?HNZu lW-!qNlKKBu!_5!Kc!wenZfVUCc5I#li$gXh`3ERr{{$L-aZvyO diff --git a/tests/regression/throwntogethertest/offset-tests-expected.png b/tests/regression/throwntogethertest/offset-tests-expected.png index cd8450499950c1e7e7bf12d68b1ef68c7d93beb2..2c25d2920837eaacb2bb62a3d95716fba1996dd9 100644 GIT binary patch literal 7424 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 A%>V!Z literal 3869 zcmds4X*AVq7vKNm9P@aRb4K0z(O$nKmsmswd z9P<%H;f4&Au?QJTnTL4)*1Gq@UF&{&*LpwP_tWz{YwzdT`}f;>J$vs+YfBRzP7zK3 z;4wXBWD9^nw-{jGS%O54{0hK3ZfazBA^@4~RY90!ex|{X+XuUlT_V?8)55*het*kF zOAplonlLNyy8_t!|1Ca{RHsEm`Jj@=ed@Lai)AomV-zU{BJg042#}2hep#T&BVfb< zWV3&)C-` zKE+4x=yrC!VkojY|FV%#N;nSd70b)=Li1$EXzpWZ>rUjhbj)`yW4K_G`o(Sb>&h-~ z%N=Hm*qJ^>v1jWoyMk&Q%MDleBL3_K&P~CbyPhk&msuSqC7py!zLgby`)Z+BQwHib zKZZWEgJDrkqj&G2dAC!aQLE3K#fKO?EQUl&?#gF+C$iV6iUng*Og4&C+d)~ys^7-9 zCHXk`Pvyv#-%t)tI>8Xa(zBr=ctt^kf1hIGv5Mq@+RQmSEZ;L7JZ|1%p3Wu{z!{!U z-LA85q$wL>U-)^fF`l+{Y3!!yS;GZGdNx+tKUsLs58}EwU)z)?S8x8#QsXjkZ&gFK zQ3daQ6ai+YJWbsBqS%QYA?W~@@$><|L5CuNNDM8?P_GJ6t&EmgU4NOZK$8$C;e`jr zh*HaH@6GZMZB8%4N>g6UE@?TW?+w5%N!ftY z%;SN|uk>5%2S^Pe+LM;sGS-7vp4=*t(Bc(AJ((I$%^CROg&- zS0_QxvGih3PoU;TB=<@wUMuuYHA^1Q$)_M?IyWZIr-@!@E@FY7y?N40XRTM%3*#GK zRvloW#RT=9aTutI(=j2)a}f-ZyzgGW>R9eEusz~6EHIs23W@o)ur7MCDr4P%16iNt zB6ptS5!~$(IFeK5CHZ_c>JqY8X=_q1wxn!t5ax;)4Q>gjZl4Ro(5a4Kh?@gov_6Kz zC0(8G4|ONjNw>-(^tMM3_+zF`Go|Fx9hS6G1sbo>EWKk7WvigVDMPwIwx^}}c&*6T z=-Bt~OG}dd>aed#7-NnKgiNei1Hya{N0d&{VyLk+RP7 z@ce55Y&~%>sf=k-CeoawJ>B`@rgYWJC#Qs4+unCOdpaFZT-Znt2OD{_4}3;@{bH2D zg7BbBN-)@k0kQ%D@jY3PZys4JK}&lyg;romfL~Ar+JXN4`b`3V=%6+E7+RNPWKm(D z5rLUMZM&}MJRwro(B>G_T|OzJc9g)3544iH^I1DP;T9HB(^S)3VQ~*Il!Sr80km9F z7jFKy>cp{sCssM<-B+y>sx9B$;=l+aO%}&kh`EmmzU982)f*%1?YlzPyDMJeI#Qz5 zD?!0jN`X>GkN4E*qFQiOhRGG=!TFdwWpO<_lmG#B=8#nm4EreKf1>OFj@ExK4@EX;eh`L%EnTJ6090h z%&u@;&5S8Q*(-k7u3n85S(tsVy>laH=SCe)!+u9)usOD-XL;SCOB`A~UmN&ne|Lx* zGf%8KxPNbRb;1;W>ResMue>WHhwmC87v$;5JQ%o;Z-3JD(d`B`b;pmabM=ivvtRY6 zZIzy|pEgMa;*hJ{m@AiPmsb5%t9j{$pW8fyz}Q~SLZn9N11-HG_Hs^!XwdfN<^{%J zgw?Zu4NkY){iN0Ts^_Pw_vtgfxV#TnGK-!g^9Or!#Pd(kCf>0z2go=4Bcw_`J?PUU zPtAQ_Sjc(Z?XS>Pvyt)wGvB8U>BT}UkMx;#D-ggLhxkd1O32}uBfoRApj&MO{StN` z|C5@XM8N}??nM3%0(Wxl&pcWhfYm1FA<Iv}XQDOsp_e7c4>qzIBeul;QT{QN zBOmlHC482fyOz$+NXfx1+zq`w@lRsg(D*5p-}B=*|J0Ti_UCD*Iy6a9H>kur5E)hvqwPbvEuiY z{mbR{U#hzgA3JEz2bs43ZsLIvU9mXLA?+Le1%;CcOxMM7dn;m?ORyY@aAF!6EJjT| z{YW@`09n0}cYAW018%1lvVpZrF$u2r_V?X$t~)1IGU=#$7Hi+4Vc($fAWb{grlXf- zboe@D>f$HSP`t4$_*9%`i*EkNi}B@I$Ik9xqNi3Y+UZV?qc)gUNsLR;VqRIG%vjj` zt?_N}wQFl9>kt~oZVAAH{V$ZGK}6lAS^sT3{tMw!7uwF0#B!kX0Fia=Duqv*pp1YO z`#-t!=lFZ)^F6_{g!d*o`ViUIoZ?(oWCdXI|76(t3*;V Date: Tue, 23 Dec 2014 05:57:34 +0100 Subject: [PATCH 187/263] Fix crash on startup for the MinGW version. --- src/mainwin.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mainwin.cc b/src/mainwin.cc index 620d9fec..8ddfe668 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -125,8 +125,6 @@ QSet *MainWindow::getWindows() // Global application state unsigned int GuiLocker::gui_locked = 0; -static std::string helptitle = openscad_version + "\nhttp://www.openscad.org\n\n"; - static char copyrighttext[] = "Copyright (C) 2009-2014 The OpenSCAD Developers\n" "\n" @@ -404,6 +402,7 @@ MainWindow::MainWindow(const QString &filename) setCurrentOutput(); + std::string helptitle = openscad_version + "\nhttp://www.openscad.org\n\n"; PRINT(helptitle); PRINT(copyrighttext); PRINT(""); @@ -2400,7 +2399,6 @@ void MainWindow::helpAbout() qApp->setWindowIcon(QApplication::windowIcon()); AboutDialog *dialog = new AboutDialog(this); dialog->exec(); - //QMessageBox::information(this, "About OpenSCAD", QString(helptitle) + QString(copyrighttext)); } void MainWindow::helpHomepage() From 5dc88d0eed4d7f4609a68d77b63f36194476b652 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 06:24:57 +0100 Subject: [PATCH 188/263] Switch between progress widget and status label. --- src/MainWindow.h | 2 ++ src/mainwin.cc | 48 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/MainWindow.h b/src/MainWindow.h index 5d415734..50d4bb6d 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -71,6 +71,7 @@ public: QAction *actionRecentFile[UIUtils::maxRecentFiles]; QMap knownFileExtensions; + QLabel *versionLabel; QWidget *editorDockTitleWidget; QWidget *consoleDockTitleWidget; @@ -116,6 +117,7 @@ private: void show_examples(); void setDockWidgetTitle(QDockWidget *dockWidget, QString prefix, bool topLevel); void addKeyboardShortCut(const QList &actions); + void updateStatusBar(class ProgressWidget *progressWidget); EditorInterface *editor; diff --git a/src/mainwin.cc b/src/mainwin.cc index 8ddfe668..8841349a 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -181,8 +181,8 @@ MainWindow::MainWindow(const QString &filename) this->consoleDock->setConfigKey("view/hideConsole"); this->consoleDock->setAction(this->viewActionHideConsole); - QLabel *versionLabel = new QLabel(openscad_version.c_str()); - this->statusbar->addPermanentWidget(versionLabel); + this->versionLabel = NULL; // must be initialized before calling updateStatusBar() + updateStatusBar(NULL); QSettings settings; editortype = settings.value("editor/editortype").toString(); @@ -683,7 +683,7 @@ MainWindow::~MainWindow() void MainWindow::showProgress() { - this->statusBar()->addPermanentWidget(qobject_cast(sender())); + updateStatusBar(qobject_cast(sender())); } void MainWindow::report_func(const class AbstractNode*, void *vp, int mark) @@ -1056,9 +1056,7 @@ void MainWindow::compileCSG(bool procevents) PRINT("CSG generation cancelled."); } progress_report_fin(); - this->statusBar()->removeWidget(this->progresswidget); - delete this->progresswidget; - this->progresswidget = NULL; + updateStatusBar(NULL); PRINT("Compiling design (CSG Products normalization)..."); if (procevents) QApplication::processEvents(); @@ -1796,15 +1794,47 @@ void MainWindow::actionRenderDone(shared_ptr root_geom) PRINT("WARNING: No top level geometry to render"); } - this->statusBar()->removeWidget(this->progresswidget); - delete this->progresswidget; - this->progresswidget = NULL; + updateStatusBar(NULL); + this->contentschanged = false; compileEnded(); } #endif /* ENABLE_CGAL */ +/** + * Switch version label and progress widget. When switching to the progress + * widget, the new instance is passed by the caller. + * In case of resetting back to the version label, NULL will be passed and + * multiple calls can happen. So this method must guard against adding the + * version label multiple times. + * + * @param progressWidget a pointer to the progress widget to show or NULL in + * case the display should switch back to the version label. + */ +void MainWindow::updateStatusBar(ProgressWidget *progressWidget) +{ + QStatusBar *sb = this->statusBar(); + if (progressWidget == NULL) { + if (this->progresswidget != NULL) { + sb->removeWidget(this->progresswidget); + delete this->progresswidget; + this->progresswidget = NULL; + } + if (versionLabel == NULL) { + versionLabel = new QLabel(openscad_version.c_str()); + sb->addPermanentWidget(this->versionLabel); + } + } else { + if (this->versionLabel != NULL) { + sb->removeWidget(this->versionLabel); + delete this->versionLabel; + this->versionLabel = NULL; + } + sb->addPermanentWidget(progressWidget); + } +} + void MainWindow::actionDisplayAST() { setCurrentOutput(); From c5e4715575be48f6cf724510b8908f5290d65768 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 23 Dec 2014 00:37:43 -0500 Subject: [PATCH 189/263] bugfix: highlighted differences didn't render correctly --- src/OpenCSGRenderer.cc | 19 +++++++++++------- src/ThrownTogetherRenderer.cc | 13 +++++------- src/polyset.cc | 4 ++-- .../2D/features/highlight-modifier-2d.scad | 10 +++++++++ .../highlight-modifier-2d-expected.png | Bin 0 -> 6147 bytes .../highlight-modifier-2d-expected.csg | 15 ++++++++++++++ .../opencsgtest/difference-tests-expected.png | Bin 11035 -> 10981 bytes .../highlight-modifier-2d-expected.png | Bin 0 -> 5819 bytes .../difference-tests-expected.png | Bin 11622 -> 11628 bytes .../highlight-modifier-2d-expected.png | Bin 0 -> 5796 bytes 10 files changed, 44 insertions(+), 17 deletions(-) create mode 100644 testdata/scad/2D/features/highlight-modifier-2d.scad create mode 100644 tests/regression/cgalpngtest/highlight-modifier-2d-expected.png create mode 100644 tests/regression/dumptest/highlight-modifier-2d-expected.csg create mode 100644 tests/regression/opencsgtest/highlight-modifier-2d-expected.png create mode 100644 tests/regression/throwntogethertest/highlight-modifier-2d-expected.png diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index 3c6f0b48..aa2d6bbb 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -90,7 +90,12 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, const Color4f &c = j_obj.color; glPushMatrix(); glMultMatrixd(j_obj.matrix.data()); - csgmode_e csgmode = j_obj.type == CSGTerm::TYPE_DIFFERENCE ? CSGMODE_DIFFERENCE : CSGMODE_NORMAL; + csgmode_e csgmode = csgmode_e( + (highlight ? + CSGMODE_HIGHLIGHT : + (background ? CSGMODE_BACKGROUND : CSGMODE_NORMAL)) | + (j_obj.type == CSGTerm::TYPE_DIFFERENCE ? CSGMODE_DIFFERENCE : 0)); + ColorMode colormode = COLORMODE_NONE; if (background) { if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { @@ -99,11 +104,9 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, else { colormode = COLORMODE_BACKGROUND; } - csgmode = csgmode_e(csgmode + 10); } else if (j_obj.type == CSGTerm::TYPE_DIFFERENCE) { if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { colormode = COLORMODE_HIGHLIGHT; - csgmode = csgmode_e(csgmode + 20); } else { colormode = COLORMODE_CUTOUT; @@ -111,7 +114,6 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, } else { if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { colormode = COLORMODE_HIGHLIGHT; - csgmode = csgmode_e(csgmode + 20); } else { colormode = COLORMODE_MATERIAL; @@ -139,9 +141,12 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, prim->geom = i_obj.geom; prim->m = i_obj.matrix; - prim->csgmode = i_obj.type == CSGTerm::TYPE_DIFFERENCE ? CSGMODE_DIFFERENCE : CSGMODE_NORMAL; - if (highlight) prim->csgmode = csgmode_e(prim->csgmode + 20); - else if (background) prim->csgmode = csgmode_e(prim->csgmode + 10); + prim->csgmode = csgmode_e( + (highlight ? + CSGMODE_HIGHLIGHT : + (background ? CSGMODE_BACKGROUND : CSGMODE_NORMAL)) | + (i_obj.type == CSGTerm::TYPE_DIFFERENCE ? CSGMODE_DIFFERENCE : 0)); + primitives.push_back(prim); } } diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 4b114041..dbdf527c 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -74,12 +74,15 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, const Color4f &c = obj.color; glPushMatrix(); glMultMatrixd(m.data()); - csgmode_e csgmode = obj.type == CSGTerm::TYPE_DIFFERENCE ? CSGMODE_DIFFERENCE : CSGMODE_NORMAL; + csgmode_e csgmode = csgmode_e( + (highlight ? + CSGMODE_HIGHLIGHT : + (background ? CSGMODE_BACKGROUND : CSGMODE_NORMAL)) | + (obj.type == CSGTerm::TYPE_DIFFERENCE ? CSGMODE_DIFFERENCE : 0)); ColorMode colormode = COLORMODE_NONE; ColorMode edge_colormode = COLORMODE_NONE; if (highlight) { - csgmode = csgmode_e(csgmode + 20); colormode = COLORMODE_HIGHLIGHT; edge_colormode = COLORMODE_HIGHLIGHT_EDGES; } else if (background) { @@ -89,16 +92,11 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, else { colormode = COLORMODE_BACKGROUND; } - csgmode = csgmode_e(csgmode + 10); edge_colormode = COLORMODE_BACKGROUND_EDGES; } else if (fberror) { - if (highlight) csgmode = csgmode_e(csgmode + 20); - else if (background) csgmode = csgmode_e(csgmode + 10); - else csgmode = csgmode_e(csgmode); } else if (obj.type == CSGTerm::TYPE_DIFFERENCE) { if (obj.flag & CSGTerm::FLAG_HIGHLIGHT) { colormode = COLORMODE_HIGHLIGHT; - csgmode = csgmode_e(csgmode + 20); } else { colormode = COLORMODE_CUTOUT; @@ -107,7 +105,6 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, } else { if (obj.flag & CSGTerm::FLAG_HIGHLIGHT) { colormode = COLORMODE_HIGHLIGHT; - csgmode = csgmode_e(csgmode + 20); } else { colormode = COLORMODE_MATERIAL; diff --git a/src/polyset.cc b/src/polyset.cc index ad6b6e59..00ae963f 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -240,7 +240,7 @@ void PolySet::render_surface(Renderer::csgmode_e csgmode, const Transform3d &m, #endif /* ENABLE_OPENCSG */ if (this->dim == 2) { // Render 2D objects 1mm thick, but differences slightly larger - double zbase = 1 + (csgmode & CSGMODE_DIFFERENCE_FLAG) * 0.1; + double zbase = 1 + ((csgmode & CSGMODE_DIFFERENCE_FLAG) ? 0.1 : 0); glBegin(GL_TRIANGLES); // Render top+bottom @@ -369,7 +369,7 @@ void PolySet::render_edges(Renderer::csgmode_e csgmode) const } else { // Render 2D objects 1mm thick, but differences slightly larger - double zbase = 1 + (csgmode & CSGMODE_DIFFERENCE_FLAG) * 0.1; + double zbase = 1 + ((csgmode & CSGMODE_DIFFERENCE_FLAG) ? 0.1 : 0); BOOST_FOREACH(const Outline2d &o, polygon.outlines()) { // Render top+bottom outlines diff --git a/testdata/scad/2D/features/highlight-modifier-2d.scad b/testdata/scad/2D/features/highlight-modifier-2d.scad new file mode 100644 index 00000000..7779fd69 --- /dev/null +++ b/testdata/scad/2D/features/highlight-modifier-2d.scad @@ -0,0 +1,10 @@ +difference() { + square(10, center=true); + #circle(3); +} +#if (true) square([11,12]); + +#translate([0,-12]) difference() { + square(10, center = true); + square(5, center = true); +} diff --git a/tests/regression/cgalpngtest/highlight-modifier-2d-expected.png b/tests/regression/cgalpngtest/highlight-modifier-2d-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..9c2cedf1993ca5e4e2887029cc429909e76b5489 GIT binary patch literal 6147 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 z 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 literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/difference-tests-expected.png b/tests/regression/throwntogethertest/difference-tests-expected.png index 4702fbff83a332fbe76956e2bb16c83639f62b06..fb1753c546db9329ceb2ad801d103bbf303fca21 100644 GIT binary patch literal 11628 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

JXfZ%n|GE`q3yic6EiWdvW*dZGiG3v z&ZAlgux$Gx>=GGYFcp;JY^ADTph~D*L84f?njh;Ds9rYFKtL1s4e>rb{4uQWX=!_= z6p2x~x;I%_QdBD(E8%PS8Mp$B$m+7dgxM@t4p2u!d7L$1o3hUr&_Tkx2J>6$()fW-XB0^{T#j35 z{_Fm1qb>2ml)zNYkP-nv*w?)fYXreyE-uU3ePoyyGp~*P-bG6}uLG1eq}wq;#M})A ztVN$&CB5XD^BX=#WGnyiI?jn$!cxlF-llXz>EdX5Uk$8Pi9Ldok-;-G)@3|!(z4*d z(4~AE_i+K=R!7=Mr=8kqVImHsmh9xhKOommDb5Ro3%1Wgf&CiE&nink!&N^y zx{ixr{r)lMD{UX2^jqxOhB~hd^j%<`lcOqMMB}Z=@)ALxgQO-WJ#mk%MJz5{n7e3P z*7ng)2IZ<3$J32-^3W{8N)3r{3X)T+tL&e*Hv zl7;nw$Xpwm-d1Wa+_ZfV!ofQuZ*9T%R0$_pz8N~Ms$~g z0YY3IlUdAn>2fbT%F}xbN_S;J+CW%qVI{d0znTl=;wq+HCNF`8*1yYp@A0ea00>nb zoj#ho99_X)f**7l6ORYLc)&GJXu1{1)v}C$Ysv+V3483qzs!uW@1(nR>atxAr-rR) z>Rvp@z=fkObS1$o(R7a}>LvbzjJkP+rJM@6xYiR}@cz*`c#i+$>soCCgZ!;4Fb)_ZK$GF7&O4o`CD1HCX7r$HrmVLkxkh7mha0 zU`TFDgh%Mo{jDs_2vi}=(AXtwl^t$>*~I{03Gc3lMB~o2Oz)q8{NZ>>cnP4ucUC2A zzF4dIz8yQPqe-EtGriHbi22M&(J3s35muG4S?7rr6>I(umnCzR7X`t3gk0+NMIheM z!25TfV&x7QxKgF&AG_+R?`Y9(L}rKyjRlynZ0S0G+<|vEukGs$gh^Q0$=1uSk{pGH9yU%e-m;9A*Lg+AR+d(0fF9}nj;KPGYWO^WFBX_y^S|E z$lJAlOXurA_lPAmcvn&Ip1`C-+6nTG(#Eo;u6{;yKMz&A-JrtMt0q^k{7&PL_Mblt z@uxDMU7XpK>F^wagoHeFj}d_A;kFKf8vqRYa1(+Ko6QKp%Xu+y^u=8ICUNM01Z*9^ z==9;cLwpYV|J1u}2=+hBm4ayCnfRgqPs585rwxu}9g82|Aoze3H$#LZ3r|5+{INPyli(5yhRNd>tE0- I(s2p-AFi*4=>Px# literal 11622 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 literal 0 HcmV?d00001 From 9b00f693118d429fb2e1bbba51c44435c53c6930 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 23 Dec 2014 00:49:37 -0500 Subject: [PATCH 190/263] #1065 Made font cache progress dialog indeterminate also on Windows --- src/openscad.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/openscad.cc b/src/openscad.cc index 293918ae..7dbffad8 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -600,7 +600,9 @@ void dialogThreadFunc(FontCacheInitializer *initializer) void dialogInitHandler(FontCacheInitializer *initializer, void *) { QProgressDialog dialog; - dialog.setLabelText("Fontconfig needs to update its font cache.\nThis can take up to a couple of minutes."); + dialog.setLabelText(_("Fontconfig needs to update its font cache.\nThis can take up to a couple of minutes.")); + dialog.setMinimum(0); + dialog.setMaximum(0); dialog.setCancelButton(0); QFutureWatcher futureWatcher; From 328cd7f362f28b8e3f4d3637b6b5f43075690b83 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 23 Dec 2014 01:07:35 -0500 Subject: [PATCH 191/263] #1028 Adjusted return values for errors --- src/openscad.cc | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/openscad.cc b/src/openscad.cc index 0fad617f..531ccf15 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -105,7 +105,7 @@ public: } }; -static void help(const char *progname) +static void help(const char *progname, bool failure = false) { int tablen = strlen(progname)+8; char tabstr[tablen+1]; @@ -133,14 +133,14 @@ static void help(const char *progname) #endif "%2%filename\n", progname % (const char *)tabstr); - exit(0); + exit(failure ? 1 : 0); } #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) static void version() { - PRINTB("OpenSCAD version %s\n", TOSTRING(OPENSCAD_VERSION)); + PRINTB("OpenSCAD version %s", TOSTRING(OPENSCAD_VERSION)); exit(0); } @@ -785,7 +785,7 @@ int main(int argc, char **argv) } catch(const std::exception &e) { // Catches e.g. unknown options PRINTB("%s\n", e.what()); - help(argv[0]); + help(argv[0], true); } OpenSCAD::debug = ""; @@ -813,27 +813,25 @@ int main(int argc, char **argv) if (vm.count("o")) { // FIXME: Allow for multiple output files? - if (output_file) help(argv[0]); + if (output_file) help(argv[0], true); output_file = vm["o"].as().c_str(); } if (vm.count("s")) { printDeprecation("DEPRECATED: The -s option is deprecated. Use -o instead.\n"); - if (output_file) help(argv[0]); + if (output_file) help(argv[0], true); output_file = vm["s"].as().c_str(); } if (vm.count("x")) { printDeprecation("DEPRECATED: The -x option is deprecated. Use -o instead.\n"); - if (output_file) help(argv[0]); + if (output_file) help(argv[0], true); output_file = vm["x"].as().c_str(); } if (vm.count("d")) { - if (deps_output_file) - help(argv[0]); + if (deps_output_file) help(argv[0], true); deps_output_file = vm["d"].as().c_str(); } if (vm.count("m")) { - if (make_command) - help(argv[0]); + if (make_command) help(argv[0], true); make_command = vm["m"].as().c_str(); } @@ -870,13 +868,11 @@ int main(int argc, char **argv) bool cmdlinemode = false; if (output_file) { // cmd-line mode cmdlinemode = true; - if (!inputFiles.size()) help(argv[0]); + if (!inputFiles.size()) help(argv[0], true); } if (arg_info || cmdlinemode) { - if (inputFiles.size() > 1) { - help(argv[0]); - } + if (inputFiles.size() > 1) help(argv[0], true); rc = cmdline(deps_output_file, inputFiles[0], camera, output_file, original_path, renderer, argc, argv); } else if (QtUseGUI()) { @@ -884,7 +880,7 @@ int main(int argc, char **argv) } else { PRINT("Requested GUI mode but can't open display!\n"); - help(argv[0]); + help(argv[0], true); } Builtins::instance(true); From bc98089aca6af4ade583d5b0f6c61ead032ed5bd Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 23 Dec 2014 01:18:27 -0500 Subject: [PATCH 192/263] Mac release build fix --- qscintilla2.prf | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qscintilla2.prf b/qscintilla2.prf index 0215ac0c..5daa57e0 100644 --- a/qscintilla2.prf +++ b/qscintilla2.prf @@ -26,13 +26,17 @@ CONFIG(debug, debug|release) { } } } else { - win32: { - LIBS += -lqscintilla2 + mac: { + LIBS += -lqscintilla2 } else { + win32: { + LIBS += -lqscintilla2 + } else { greaterThan(QT_MAJOR_VERSION, 4) { LIBS += -lqt5scintilla2 } else { LIBS += -lqscintilla2 } + } } } From 9445d1297ac7a5d8fcebaa6e58408df981599581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Tue, 23 Dec 2014 12:27:41 +0100 Subject: [PATCH 193/263] Minor corrections to Czech translation --- locale/cs.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index 7e1d08ca..ead6a278 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: OpenSCAD 2013.02.24\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-11-13 00:22+0100\n" -"PO-Revision-Date: 2014-12-21 23:22+0100\n" +"PO-Revision-Date: 2014-12-23 12:24+0100\n" "Last-Translator: Miro Hrončok \n" "Language-Team: Czech \n" "Language: cs\n" @@ -534,7 +534,7 @@ msgstr "Domovská stránka OpenSCADu" #: objects/ui_MainWindow.h:835 msgid "Automatic Reload and Preview" -msgstr "Automaticky načítat a zobrazit" +msgstr "Automaticky načítat a zobrazovat" #: objects/ui_MainWindow.h:836 msgid "Export as Image..." @@ -836,7 +836,7 @@ msgstr "%v / %m" #: src/AboutDialog.h:15 msgid "About OpenSCAD " -msgstr "O OpenSCADu" +msgstr "O OpenSCADu " #: src/mainwin.cc:773 src/mainwin.cc:1315 msgid "Untitled.scad" From c9a234a0792b49e9a535e587d97536a5de156242 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 18:27:39 +0100 Subject: [PATCH 194/263] Add OK button, some Linux window managers do not add a close button to dialogs. --- src/AboutDialog.h | 12 ++--- src/AboutDialog.html | 2 +- src/AboutDialog.ui | 113 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 116 insertions(+), 11 deletions(-) diff --git a/src/AboutDialog.h b/src/AboutDialog.h index a8e28a1e..aca97e70 100644 --- a/src/AboutDialog.h +++ b/src/AboutDialog.h @@ -1,23 +1,23 @@ #pragma once +#include "openscad.h" #include "qtgettext.h" #include "ui_AboutDialog.h" -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - class AboutDialog : public QDialog, public Ui::AboutDialog { Q_OBJECT; public: AboutDialog(QWidget *) { setupUi(this); - this->setWindowTitle( QString(_("About OpenSCAD")) + " " + QString(TOSTRING( OPENSCAD_VERSION)) ); - this->aboutText->setOpenExternalLinks(true); + this->setWindowTitle( QString(_("About OpenSCAD")) + " " + openscad_versionnumber.c_str()); QUrl flattr_qurl(":icons/flattr.png" ); this->aboutText->loadResource( QTextDocument::ImageResource, flattr_qurl ); QString tmp = this->aboutText->toHtml(); - tmp.replace("__VERSION__",QString(TOSTRING(OPENSCAD_VERSION))); + tmp.replace("__VERSION__", openscad_versionnumber.c_str()); this->aboutText->setHtml(tmp); } + +public slots: + void on_okPushButton_clicked() { accept(); } }; diff --git a/src/AboutDialog.html b/src/AboutDialog.html index d138eecb..8eefeecf 100644 --- a/src/AboutDialog.html +++ b/src/AboutDialog.html @@ -19,7 +19,7 @@

-OpenSCAD version __VERSION__ +OpenSCAD version __VERSION__

diff --git a/src/AboutDialog.ui b/src/AboutDialog.ui index 587d27e2..0a3bedf9 100644 --- a/src/AboutDialog.ui +++ b/src/AboutDialog.ui @@ -6,16 +6,98 @@ 0 0 - 567 - 359 + 628 + 419 + + + 0 + 0 + + About OpenSCAD - - + + + 16 + + + 6 + + + + + 0 + + + 6 + + + + + + 96 + 96 + + + + + 96 + 96 + + + + + + + :/icons/openscad.png + + + true + + + + + + + <html><head/><body> +<p style="font-family: 'Open Sans', 'Droid Sans', 'sans-serif'; font-weight: bold; padding-bottom: 0; margin-bottom: 0; font-size: 22pt;"><span style="color: green;">Open</span>SCAD</p> +<p style="font-family: 'Open Sans', 'Droid Sans', 'sans-serif'; font-weight: normal; font-size: 14pt; padding-top: 0; margin-top: 0; margin-left: 2em;">The Programmers Solid 3D CAD Modeller</p> +</body></html> + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 2 + + + + + + + + + + 400 + 200 + + true @@ -24,8 +106,31 @@ qrc:/src/AboutDialog.html + + true + + + + + OK + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + From 481665f8a35c9950b518c8dcf1a7f0436ddee5f3 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 18:28:16 +0100 Subject: [PATCH 195/263] Change layout to allow longer version number text. --- src/launchingscreen.ui | 79 ++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/launchingscreen.ui b/src/launchingscreen.ui index cd4c8cd8..3bb2d0d8 100644 --- a/src/launchingscreen.ui +++ b/src/launchingscreen.ui @@ -337,43 +337,48 @@ QPushButton:pressed { - - - - - 0 - 0 - - - - Version - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - true - - - - 0 - 0 - - - - false - - - Don't show again - - - false - - + + + + + + true + + + false + + + Don't show again + + + false + + + + + + + Qt::Horizontal + + + + 2 + 2 + + + + + + + + Version + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + From 0801fc432d76b2468570d1bb713ec78dc2374b06 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 18:42:16 +0100 Subject: [PATCH 196/263] Add background to the drag&drop pixmap to make it better readable. --- src/FontListTableView.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/FontListTableView.cc b/src/FontListTableView.cc index b013d81f..b6162a24 100644 --- a/src/FontListTableView.cc +++ b/src/FontListTableView.cc @@ -50,13 +50,14 @@ void FontListTableView::startDrag(Qt::DropActions supportedActions) mimeData->setText(text); QFontMetrics fm(font()); - QRect rect(0, 0, fm.width(text), fm.height()); + QRect rect(0, 0, fm.width(text) + 8, fm.height() + 8); QPixmap pixmap(rect.width(), rect.height()); - pixmap.fill(Qt::transparent); + pixmap.fill(QColor(240, 240, 240, 160)); QPainter painter(&pixmap); painter.setFont(font()); painter.drawText(rect, Qt::AlignCenter, text); + painter.drawRect(0, 0, rect.width() - 1, rect.height() - 1); QDrag *drag = new QDrag(this); drag->setPixmap(pixmap); From d296d93ddc9975d55f28200be4c96b00c7d329c1 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 19:05:53 +0100 Subject: [PATCH 197/263] Quit application when last main window is closed (fixes #1079). --- src/mainwin.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mainwin.cc b/src/mainwin.cc index 8841349a..3e51f1f3 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -679,6 +679,11 @@ MainWindow::~MainWindow() #endif delete this->thrownTogetherRenderer; MainWindow::getWindows()->remove(this); + if (MainWindow::getWindows()->size() == 0) { + // Quit application even in case some other windows like + // Preferences are still open. + qApp->quit(); + } } void MainWindow::showProgress() From ef83c5c911b6f657eab32d739e201b51a0757d2d Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 23 Dec 2014 19:15:23 +0100 Subject: [PATCH 198/263] Remove duplicate definition. --- locale/cs.po | 3 --- 1 file changed, 3 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index 72ac3171..d9a8ed71 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -981,9 +981,6 @@ msgstr "Vytažení" #~ msgid "Paste font selector to Editor Window" #~ msgstr "Vložit výběr písma do zdrojového kódu" -#~ msgid "About OpenSCAD " -#~ msgstr "O OpenSCADu" - #~ msgid "Check for Update.." #~ msgstr "Zkontrolovat aktualizaci..." From c2643d82eacbe95ec3409ecb20b40ca700dd0980 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 23 Dec 2014 22:50:38 -0500 Subject: [PATCH 199/263] #1069 Correctly fall back to CGAL minkowski if our convex decomposition-based minkowski fails. Fixes #1069 for now, but our convex-based minkowski should not fail --- src/cgalutils.cc | 108 ++++++++---------- testdata/scad/bugs/issue1069.scad | 14 +++ tests/CMakeLists.txt | 3 +- .../cgalpngtest/issue1069-expected.png | Bin 0 -> 7079 bytes .../monotonepngtest/issue1069-expected.png | Bin 0 -> 7079 bytes .../opencsgtest/issue1069-expected.png | Bin 0 -> 7349 bytes 6 files changed, 62 insertions(+), 63 deletions(-) create mode 100644 testdata/scad/bugs/issue1069.scad create mode 100644 tests/regression/cgalpngtest/issue1069-expected.png create mode 100644 tests/regression/monotonepngtest/issue1069-expected.png create mode 100644 tests/regression/opencsgtest/issue1069-expected.png diff --git a/src/cgalutils.cc b/src/cgalutils.cc index cc8d870f..b7fbafd3 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -606,6 +606,9 @@ namespace CGALUtils { shared_ptr(createNefPolyhedronFromGeometry(ps)))); } CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(fake_children, OPENSCAD_UNION); + // FIXME: This hould really never throw. + // Assert once we figured out what went wrong with issue #1069? + if (!N) throw 0; t.stop(); PRINTDB("Minkowski: Union done: %f s",t.time()); t.reset(); @@ -635,53 +638,46 @@ namespace CGALUtils { */ CGAL_Nef_polyhedron *applyOperator(const Geometry::ChildList &children, OpenSCADOperator op) { - // Speeds up n-ary union operations significantly - CGAL::Nef_nary_union_3 nary_union; - int nary_union_num_inserted = 0; CGAL_Nef_polyhedron *N = NULL; - - BOOST_FOREACH(const Geometry::ChildItem &item, children) { - const shared_ptr &chgeom = item.second; - shared_ptr chN = - dynamic_pointer_cast(chgeom); - if (!chN) { - const PolySet *chps = dynamic_cast(chgeom.get()); - if (chps) chN.reset(createNefPolyhedronFromGeometry(*chps)); - } - - if (op == OPENSCAD_UNION) { - if (!chN->isEmpty()) { - // nary_union.add_polyhedron() can issue assertion errors: - // https://github.com/openscad/openscad/issues/802 - CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); - try { + CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); + try { + // Speeds up n-ary union operations significantly + CGAL::Nef_nary_union_3 nary_union; + int nary_union_num_inserted = 0; + + BOOST_FOREACH(const Geometry::ChildItem &item, children) { + const shared_ptr &chgeom = item.second; + shared_ptr chN = + dynamic_pointer_cast(chgeom); + if (!chN) { + const PolySet *chps = dynamic_cast(chgeom.get()); + if (chps) chN.reset(createNefPolyhedronFromGeometry(*chps)); + } + + if (op == OPENSCAD_UNION) { + if (!chN->isEmpty()) { + // nary_union.add_polyhedron() can issue assertion errors: + // https://github.com/openscad/openscad/issues/802 nary_union.add_polyhedron(*chN->p3); nary_union_num_inserted++; } - catch (const CGAL::Failure_exception &e) { - PRINTB("CGAL error in CGALUtils::applyBinaryOperator union: %s", e.what()); - } - CGAL::set_error_behaviour(old_behaviour); + continue; } - continue; - } - // Initialize N with first expected geometric object - if (!N) { - N = new CGAL_Nef_polyhedron(*chN); - continue; - } - - // Intersecting something with nothing results in nothing - if (chN->isEmpty()) { - if (op == OPENSCAD_INTERSECTION) *N = *chN; - continue; - } - - // empty op => empty - if (N->isEmpty()) continue; - - CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); - try { + // Initialize N with first expected geometric object + if (!N) { + N = new CGAL_Nef_polyhedron(*chN); + continue; + } + + // Intersecting something with nothing results in nothing + if (chN->isEmpty()) { + if (op == OPENSCAD_INTERSECTION) *N = *chN; + continue; + } + + // empty op => empty + if (N->isEmpty()) continue; + switch (op) { case OPENSCAD_INTERSECTION: *N *= *chN; @@ -695,31 +691,19 @@ namespace CGALUtils { default: PRINTB("ERROR: Unsupported CGAL operator: %d", op); } + item.first->progress_report(); } - catch (const CGAL::Failure_exception &e) { - // union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad and testdata/scad/bugs/issue204.scad - std::string opstr = op == OPENSCAD_INTERSECTION ? "intersection" : op == OPENSCAD_DIFFERENCE ? "difference" : op == OPENSCAD_MINKOWSKI ? "minkowski" : "UNKNOWN"; - PRINTB("CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what()); - - // Errors can result in corrupt polyhedrons, so put back the old one - *N = *chN; - } - CGAL::set_error_behaviour(old_behaviour); - item.first->progress_report(); - } - - if (op == OPENSCAD_UNION && nary_union_num_inserted > 0) { - CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); - try { + if (op == OPENSCAD_UNION && nary_union_num_inserted > 0) { N = new CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron3(nary_union.get_union())); - - } catch (const CGAL::Failure_exception &e) { - std::string opstr = "union"; - PRINTB("CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what()); } - CGAL::set_error_behaviour(old_behaviour); } + // union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad and testdata/scad/bugs/issue204.scad + catch (const CGAL::Failure_exception &e) { + std::string opstr = op == OPENSCAD_INTERSECTION ? "intersection" : op == OPENSCAD_DIFFERENCE ? "difference" : op == OPENSCAD_MINKOWSKI ? "minkowski" : "UNKNOWN"; + PRINTB("CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what()); + } + CGAL::set_error_behaviour(old_behaviour); return N; } diff --git a/testdata/scad/bugs/issue1069.scad b/testdata/scad/bugs/issue1069.scad new file mode 100644 index 00000000..b5048e71 --- /dev/null +++ b/testdata/scad/bugs/issue1069.scad @@ -0,0 +1,14 @@ +$fn = 5; + +module object() { + cylinder(r = 1, h = 5); + rotate(45, [1, 0, 0]) cylinder(r = 1, h = 5); +} + +minkowski() { + difference() { + cube(20, center = true); + object(); + } + cube(.5, center = true); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 290d8448..19835d0d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1216,7 +1216,8 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1004.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1069.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(REMOVE_ITEM EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad diff --git a/tests/regression/cgalpngtest/issue1069-expected.png b/tests/regression/cgalpngtest/issue1069-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..677d52ca8bc001554d27e59b4decd40abbad783a GIT binary patch literal 7079 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 XY6R=pD>nQC4zb(nxTRndBl^DpPSBy0 literal 0 HcmV?d00001 diff --git a/tests/regression/monotonepngtest/issue1069-expected.png b/tests/regression/monotonepngtest/issue1069-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..677d52ca8bc001554d27e59b4decd40abbad783a GIT binary patch literal 7079 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 XY6R=pD>nQC4zb(nxTRndBl^DpPSBy0 literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/issue1069-expected.png b/tests/regression/opencsgtest/issue1069-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..989385eeab098d42872e7f5bb7cc356639c5261c GIT binary patch literal 7349 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 literal 0 HcmV?d00001 From 40602c99bca2410e4ce106408fdfdd016a7bb4c8 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 25 Dec 2014 17:50:58 +0100 Subject: [PATCH 200/263] Minor color scheme tweaks, mainly for brace matching colors. --- color-schemes/editor/light-background.json | 14 +++++++------- color-schemes/editor/monokai.json | 8 ++++---- color-schemes/editor/solarized-dark.json | 8 ++++---- color-schemes/editor/solarized-light.json | 8 ++++---- color-schemes/editor/tomorrow.json | 8 ++++---- color-schemes/render/tomorrow.json | 2 +- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/color-schemes/editor/light-background.json b/color-schemes/editor/light-background.json index 535834aa..f80e735e 100644 --- a/color-schemes/editor/light-background.json +++ b/color-schemes/editor/light-background.json @@ -6,7 +6,7 @@ "caret" : { "width" : 2, "foreground" : "#000000", - "line-background" : "#f0f0f0" + "line-background" : "#f8f8f8" }, "colors" : { "keyword1" : "Green", @@ -23,12 +23,12 @@ "whitespace-foreground" : "#272822", "selection-foreground" : "#ffffff", "selection-background" : "#4a90d9", - "margin-background" : "#ccc", - "margin-foreground" : "#111", - "matched-brace-background" : "#333", - "matched-brace-foreground" : "#fff", - "unmatched-brace-background" : "#333", - "unmatched-brace-foreground" : "#fff", + "margin-background" : "#f8f8f8", + "margin-foreground" : "#000000", + "matched-brace-background" : "#c7f6cb", + "matched-brace-foreground" : "Blue", + "unmatched-brace-background" : "#ffcdcc", + "unmatched-brace-foreground" : "Blue", "error-marker" : "#ff0000", "error-indicator" : "#60ff0000", "error-indicator-outline" : "#ff000000", diff --git a/color-schemes/editor/monokai.json b/color-schemes/editor/monokai.json index 4e072594..b4c74451 100644 --- a/color-schemes/editor/monokai.json +++ b/color-schemes/editor/monokai.json @@ -5,7 +5,7 @@ "text" : "#f8f8f2", "caret" : { "width" : 2, - "foreground" : "#f8f8f0", + "foreground" : "#f8f8f2", "line-background" : "#49483e" }, "colors" : { @@ -26,9 +26,9 @@ "margin-background" : "#3e3d32", "margin-foreground" : "#f8f8f2", "matched-brace-background" : "#606060", - "matched-brace-foreground" : "#f8f8f2", - "unmatched-brace-background" : "#dc322f", - "unmatched-brace-foreground" : "#f8f8f2", + "matched-brace-foreground" : "#ffff00", + "unmatched-brace-background" : "#b06060", + "unmatched-brace-foreground" : "#ffff00", "error-marker" : "#ff0000", "error-indicator" : "#80ffe0e0", "error-indicator-outline" : "#ff000000", diff --git a/color-schemes/editor/solarized-dark.json b/color-schemes/editor/solarized-dark.json index b73eff19..e6ad36df 100644 --- a/color-schemes/editor/solarized-dark.json +++ b/color-schemes/editor/solarized-dark.json @@ -25,10 +25,10 @@ "selection-background" : "#657b83", "margin-background" : "#002b36", "margin-foreground" : "#839496", - "matched-brace-background" : "#93a1a1", - "matched-brace-foreground" : "#586e75", - "unmatched-brace-background" : "#dc322f", - "unmatched-brace-foreground" : "#fdf6e3", + "matched-brace-background" : "#0c4e22", + "matched-brace-foreground" : "#fff070", + "unmatched-brace-background" : "#92211f", + "unmatched-brace-foreground" : "#fff070", "error-marker" : "#ff0000", "error-indicator" : "#90ff8080", "error-indicator-outline" : "#ff000000", diff --git a/color-schemes/editor/solarized-light.json b/color-schemes/editor/solarized-light.json index 4033e509..40f5203f 100644 --- a/color-schemes/editor/solarized-light.json +++ b/color-schemes/editor/solarized-light.json @@ -25,10 +25,10 @@ "selection-background" : "#657b83", "margin-background" : "#eee8d5", "margin-foreground" : "#657b83", - "matched-brace-background" : "#93a1a1", - "matched-brace-foreground" : "#586e75", - "unmatched-brace-background" : "#ed8987", - "unmatched-brace-foreground" : "#fdf6e3", + "matched-brace-background" : "#c7f6cb", + "matched-brace-foreground" : "#cb4b16", + "unmatched-brace-background" : "#ffcdcc", + "unmatched-brace-foreground" : "#cb4b16", "error-marker" : "#ff0000", "error-indicator" : "#80ff0000", "error-indicator-outline" : "#ff000000", diff --git a/color-schemes/editor/tomorrow.json b/color-schemes/editor/tomorrow.json index 072e1f99..71d2e4f1 100644 --- a/color-schemes/editor/tomorrow.json +++ b/color-schemes/editor/tomorrow.json @@ -1,7 +1,7 @@ { "name" : "Tomorrow", "index" : 1500, - "paper" : "#f0f0f0", + "paper" : "#f8f8f8", "text" : "#4d4d4c", "caret" : { "width" : 2, @@ -19,13 +19,13 @@ "number" : "#c82829", "string" : "#718c00", "operator" : "#3e999f", - "whitespace-background" : "#f0f0f0", + "whitespace-background" : "#f8f8f8", "whitespace-foreground" : "#4d4d4c", "selection-foreground" : "#4d4d4c", "selection-background" : "#d6d6d6", - "margin-background" : "#f0f0f0", + "margin-background" : "#f8f8f8", "margin-foreground" : "#4d4d4c", - "matched-brace-background" : "#d4d4d4", + "matched-brace-background" : "#c7f6cb", "matched-brace-foreground" : "#4d4d4c", "unmatched-brace-background" : "#ffcdcc", "unmatched-brace-foreground" : "#4d4d4c", diff --git a/color-schemes/render/tomorrow.json b/color-schemes/render/tomorrow.json index b76f9e10..db21d9a7 100644 --- a/color-schemes/render/tomorrow.json +++ b/color-schemes/render/tomorrow.json @@ -4,7 +4,7 @@ "show-in-gui" : true, "colors" : { - "background" : "#f0f0f0", + "background" : "#f8f8f8", "opencsg-face-front" : "#4271ae", "opencsg-face-back" : "#f5871f", "cgal-face-front" : "#3e999f", From fd4fe0816a11dabb164bd239bc576c4378054fcf Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 25 Dec 2014 17:57:13 +0100 Subject: [PATCH 201/263] Fix style sheet to remove borders from QStatusBar items. --- src/openscad.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openscad.cc b/src/openscad.cc index 034eced5..1e8f56c1 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -631,7 +631,7 @@ int gui(vector &inputFiles, const fs::path &original_path, int argc, cha #endif QApplication app(argc, argv, true); //useGUI); // remove ugly frames in the QStatusBar when using additional widgets - app.setStyleSheet("QStatusBar::item { border: 0px solid black }; "); + app.setStyleSheet("QStatusBar::item { border: 0px solid black; }"); #ifdef Q_OS_MAC app.installEventFilter(new EventFilter(&app)); From d2af825640abb6da4f990892fc13ee3e489883a2 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 25 Dec 2014 18:19:26 +0100 Subject: [PATCH 202/263] Enable resource lookup for Windows build (needed for dev and MSYS2 package). --- src/PlatformUtils.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index 329fb8fb..e4d80225 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -25,7 +25,6 @@ static std::string lookupResourcesPath() fs::path resourcedir(applicationpath); PRINTDB("Looking up resource folder with application path '%s'", resourcedir.c_str()); -#ifndef WIN32 #ifdef __APPLE__ const char *searchpath[] = { "../Resources", // Resources can be bundled on Mac. @@ -34,7 +33,15 @@ static std::string lookupResourcesPath() NULL }; #else - const char *searchpath[] = { +#ifdef WIN32 + const char *searchpath[] = { + ".", // Release location + RESOURCE_FOLDER("../share/openscad"), // MSYS2 location + "..", // Dev location + NULL + }; +#else + const char *searchpath[] = { RESOURCE_FOLDER("../share/openscad"), RESOURCE_FOLDER("../../share/openscad"), ".", @@ -43,6 +50,7 @@ static std::string lookupResourcesPath() NULL }; #endif +#endif fs::path tmpdir; for (int a = 0;searchpath[a] != NULL;a++) { @@ -57,7 +65,6 @@ static std::string lookupResourcesPath() break; } } -#endif // !WIN32 // resourcedir defaults to applicationPath std::string result = boosty::stringy(boosty::canonical(resourcedir)); From 4cb7b42fb897439d22c308561993dcf4d3631e23 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 25 Dec 2014 18:52:20 +0100 Subject: [PATCH 203/263] Add defines for MSYS2 build. --- .gitignore | 1 + boost.pri | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 52a67b4a..767c89c4 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ parser_yacc.h /locale/*/*/*.mo /locale/POTFILES /nbproject +/openscad.pro.user /openscad /tests/openscad_nogui testdata/scad/features/import_dxf-tests.scad diff --git a/boost.pri b/boost.pri index 61ebd5e2..46fb7ecc 100644 --- a/boost.pri +++ b/boost.pri @@ -11,14 +11,20 @@ boost { # See https://svn.boost.org/trac/boost/ticket/6219 macx: DEFINES += __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 + + # MXE cross build CONFIG(mingw-cross-env) { DEFINES += BOOST_STATIC DEFINES += BOOST_THREAD_USE_LIB DEFINES += Boost_USE_STATIC_LIBS BOOST_LINK_FLAGS = -lboost_thread_win32-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt -lboost_chrono-mt - } + } - isEmpty(BOOST_LINK_FLAGS):win* { + # MSYS2 + isEmpty(BOOST_LINK_FLAGS):win32-g++ { + DEFINES += BOOST_STATIC + DEFINES += BOOST_THREAD_USE_LIB + DEFINES += Boost_USE_STATIC_LIBS BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt } From 82c8c7405da680b3f6951f9575337175353f7ea6 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 25 Dec 2014 18:54:16 +0100 Subject: [PATCH 204/263] Move readme to color scheme folder. --- readme.txt => color-schemes/readme.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename readme.txt => color-schemes/readme.txt (100%) diff --git a/readme.txt b/color-schemes/readme.txt similarity index 100% rename from readme.txt rename to color-schemes/readme.txt From ec3f735d5ccedd1c4b33f9f7b4ee96dcb531395a Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 25 Dec 2014 18:56:30 +0100 Subject: [PATCH 205/263] Need to specify openscad.pro for qmake now. --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8205b29a..090f60d8 100644 --- a/README.md +++ b/README.md @@ -212,15 +212,16 @@ complete, build OpenSCAD and package it to an installer: If you wish you can only build the openscad.exe binary: cd mingw32 - qmake .. CONFIG+=mingw-cross-env + qmake ../openscad.pro CONFIG+=mingw-cross-env make For a 64-bit Windows cross-build, replace 32 with 64 in the above instructions. ### Compilation -First, run 'qmake' from Qt4 to generate a Makefile. On some systems you need to -run 'qmake4', 'qmake-qt4' or something alike to run the qt4 version of the tool. +First, run 'qmake openscad.pro' from Qt4 to generate a Makefile. On some systems +you need to run 'qmake4', 'qmake-qt4' or something alike to run the qt4 version +of the tool. Then run make. Finally you might run 'make install' as root or simply copy the 'openscad' binary (OpenSCAD.app on Mac OS X) to the bin directory of your choice. From 0bf2d4e286c819e182448cc10e47059eef7b541e Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Thu, 25 Dec 2014 19:18:08 +0100 Subject: [PATCH 206/263] No need to update translation in release-common.sh it's done by the build. --- scripts/release-common.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 709d508a..2da42495 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -280,11 +280,6 @@ if [[ $? != 0 ]]; then exit 1 fi -echo "Updating language files..." - -cd $OPENSCADDIR -./scripts/translation-update.sh - echo "Building test suite..." if [ $BUILD_TESTS ]; then From 641ac4a506cda95c619e7f82c6bfc9e4f4925491 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 25 Dec 2014 17:27:13 -0500 Subject: [PATCH 207/263] #1107 Correctly display validity for objects which didn't yet touch CGAL --- src/mainwin.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mainwin.cc b/src/mainwin.cc index 3e51f1f3..cfb44bda 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -38,6 +38,7 @@ #include "highlighter.h" #include "export.h" #include "builtin.h" +#include "memory.h" #include "expression.h" #include "progress.h" #include "dxfdim.h" @@ -1916,9 +1917,13 @@ void MainWindow::actionCheckValidity() { } bool valid = false; - if (const CGAL_Nef_polyhedron *N = dynamic_cast(this->root_geom.get())) + shared_ptr N; + if (const PolySet *ps = dynamic_cast(this->root_geom.get())) { + N.reset(CGALUtils::createNefPolyhedronFromGeometry(*ps)); + } + if (N || (N = dynamic_pointer_cast(this->root_geom))) { valid = N->p3->is_valid(); - + } PRINTB(" Valid: %6s", (valid ? "yes" : "no")); clearCurrentOutput(); #endif /* ENABLE_CGAL */ From 7ccdb778fcd44b226ffde15a0bde1e2740d75c89 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Fri, 26 Dec 2014 19:20:11 +0100 Subject: [PATCH 208/263] Enable GL_LINE_STIPPLE only for the block where a stipple pattern is used (fixes #1111). --- src/GLView.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GLView.cc b/src/GLView.cc index d52b3c9b..4baa38ab 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -354,7 +354,6 @@ void GLView::initializeGL() glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); - glEnable(GL_LINE_STIPPLE); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); // The following line is reported to fix issue #71 @@ -468,6 +467,7 @@ void GLView::showAxes(const Color4f &col) glEnd(); glPushAttrib(GL_LINE_BIT); + glEnable(GL_LINE_STIPPLE); glLineStipple(3, 0xAAAA); glBegin(GL_LINES); glVertex3d(0, 0, 0); From 3a5ee3a4c607c1e79ec4d7b792fb72b9c22fef22 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 27 Dec 2014 00:12:17 +0100 Subject: [PATCH 209/263] Add GUI controls for editor settings. --- src/Preferences.ui | 255 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 252 insertions(+), 3 deletions(-) diff --git a/src/Preferences.ui b/src/Preferences.ui index eff8da96..cd3b88b7 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -7,7 +7,7 @@ 0 0 852 - 554 + 592 @@ -27,7 +27,7 @@ - 4 + 1 @@ -289,6 +289,255 @@ + + + + Editor settings + + + + 20 + + + + + + None + + + + + Wrap at character boundaries + + + + + Wrap at word boundaries + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 2 + + + + + + + + Show whitespaces + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Never + + + + + Always + + + + + Only after indentation + + + + + + + + + 0 + 0 + + + + + None + + + + + Text + + + + + Border + + + + + Margin + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Start + + + + + + + Line wrap visualization + + + + + + + Line wrap indentation + + + + + + + Tab width + + + + + + + Line wrap + + + + + + + End + + + + + + + + 0 + 0 + + + + + None + + + + + Text + + + + + Border + + + + + Margin + + + + + + + + Indent + + + + + + + + Fixed + + + + + Same + + + + + Indented + + + + + + + + Style + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Indentation width + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + @@ -646,7 +895,7 @@ - + Enable user interface localization (requires restart of OpenSCAD) From dde4575c882a79ac46c9906083d9bfc2a51140a3 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Wed, 24 Sep 2014 22:18:14 +0200 Subject: [PATCH 210/263] Add class to handle settings. --- openscad.pro | 2 ++ src/mainwin.cc | 1 + src/settings.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/settings.h | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 src/settings.cc create mode 100644 src/settings.h diff --git a/openscad.pro b/openscad.pro index d9b99c73..80785f84 100644 --- a/openscad.pro +++ b/openscad.pro @@ -247,6 +247,7 @@ HEADERS += src/typedefs.h \ src/ProgressWidget.h \ src/parsersettings.h \ src/renderer.h \ + src/settings.h \ src/rendersettings.h \ src/colormap.h \ src/ThrownTogetherRenderer.h \ @@ -399,6 +400,7 @@ SOURCES += src/version_check.cc \ src/FreetypeRenderer.cc \ src/FontCache.cc \ \ + src/settings.cc \ src/rendersettings.cc \ src/highlighter.cc \ src/Preferences.cc \ diff --git a/src/mainwin.cc b/src/mainwin.cc index cfb44bda..0bcfb34f 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -43,6 +43,7 @@ #include "progress.h" #include "dxfdim.h" #include "legacyeditor.h" +#include "settings.h" #ifdef USE_SCINTILLA_EDITOR #include "scintillaeditor.h" #endif diff --git a/src/settings.cc b/src/settings.cc new file mode 100644 index 00000000..cf352fdd --- /dev/null +++ b/src/settings.cc @@ -0,0 +1,45 @@ +#include "settings.h" + +template +SettingsEntry::SettingsEntry(const std::string category, const std::string name, T defaultValue) + : category(category), name(name), defaultValue(defaultValue) +{ +} + +template +SettingsEntry::~SettingsEntry() +{ +} + +SettingsEntry Settings::indentationWidth("editor", "indentationWidth", 4); +SettingsEntry Settings::tabWidth("editor", "tabWidth", 8); +SettingsEntry Settings::lineWrap("editor", "lineWrap", LINE_WRAP_WORD); + +Settings *Settings::inst(bool erase) +{ + static Settings *instance = new Settings; + + if (erase) { + delete instance; + instance = NULL; + } + + return instance; +} + +Settings::Settings() +{ +} + +Settings::~Settings() +{ +} + +template +T Settings::defaultValue(const SettingsEntry &entry) +{ + return entry.defaultValue; +} + +template int Settings::defaultValue(const SettingsEntry&); +template SettingsLineWrap Settings::defaultValue(const SettingsEntry&); diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 00000000..18e69c4d --- /dev/null +++ b/src/settings.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +typedef enum { + LINE_WRAP_NONE, + LINE_WRAP_CHARACTER, + LINE_WRAP_WORD, +} SettingsLineWrap; + +template +class SettingsEntry +{ + std::string category; + std::string name; + T value; + T defaultValue; + + SettingsEntry(const std::string category, const std::string name, T defaultValue); + virtual ~SettingsEntry(); + + friend class Settings; +}; + +class Settings +{ +public: + static SettingsEntry indentationWidth; + static SettingsEntry tabWidth; + static SettingsEntry lineWrap; + + static Settings *inst(bool erase = false); + + template T defaultValue(const SettingsEntry &entry); + +private: + Settings(); + virtual ~Settings(); +}; From 0cb6b3267a082a0f0ab6fdfd191d48202a4c8bc5 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 27 Dec 2014 02:17:15 +0100 Subject: [PATCH 211/263] Add editor settings. --- src/Preferences.cc | 69 +++- src/Preferences.h | 12 + src/Preferences.ui | 72 +++-- src/mainwin.cc | 7 + src/scintillaeditor.cpp | 683 ++++++++++++++++++++++------------------ src/scintillaeditor.h | 1 + src/settings.cc | 45 ++- src/settings.h | 38 ++- 8 files changed, 599 insertions(+), 328 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index 9c8f9b59..45afcba9 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -39,6 +39,7 @@ #endif #include "colormap.h" #include "rendersettings.h" +#include "settings.h" Preferences *Preferences::instance = NULL; @@ -400,13 +401,66 @@ void Preferences::on_mouseWheelZoomBox_toggled(bool state) settings.setValue("editor/ctrlmousewheelzoom", state); } -void -Preferences::on_launcherBox_toggled(bool state) +void Preferences::on_launcherBox_toggled(bool state) { QSettings settings; settings.setValue("launcher/showOnStartup", state); } +void Preferences::on_spinBoxIndentationWidth_valueChanged(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::indentationWidth, val); + emit editorConfigChanged(); +} + +void Preferences::on_spinBoxTabWidth_valueChanged(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::tabWidth, val); + emit editorConfigChanged(); +} + +void Preferences::on_comboBoxLineWrap_activated(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::lineWrap, (Settings::LineWrap)val); + emit editorConfigChanged(); +} + +void Preferences::on_comboBoxLineWrapIndentation_activated(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentationStyle, (Settings::LineWrapIndentationStyle)val); + emit editorConfigChanged(); +} + +void Preferences::on_spinBoxLineWrapIndentationIndent_valueChanged(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentation, val); + emit editorConfigChanged(); +} + +void Preferences::on_comboBoxLineWrapVisualizationStart_activated(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::lineWrapVisualizationBegin, (Settings::LineWrapVisualization)val); + emit editorConfigChanged(); +} + +void Preferences::on_comboBoxLineWrapVisualizationEnd_activated(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::lineWrapVisualizationEnd, (Settings::LineWrapVisualization)val); + emit editorConfigChanged(); +} + +void Preferences::on_comboBoxShowWhitespaces_activated(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::showWhitespaces, (Settings::ShowWhitespaces)val); + emit editorConfigChanged(); +} + +void Preferences::on_spinBoxShowWhitespacesSize_valueChanged(int val) +{ + Settings::Settings::inst()->set(Settings::Settings::showWhitespacesSize, val); + emit editorConfigChanged(); +} + void Preferences::keyPressEvent(QKeyEvent *e) { #ifdef Q_OS_MAC @@ -500,6 +554,17 @@ void Preferences::updateGUI() this->undockCheckBox->setChecked(getValue("advanced/undockableWindows").toBool()); this->undockCheckBox->setEnabled(this->reorderCheckBox->isChecked()); this->launcherBox->setChecked(getValue("launcher/showOnStartup").toBool()); + + Settings::Settings *s = Settings::Settings::inst(); + this->spinBoxIndentationWidth->setValue(s->get(Settings::Settings::indentationWidth)); + this->spinBoxTabWidth->setValue(s->get(Settings::Settings::tabWidth)); + this->comboBoxLineWrap->setCurrentIndex(s->get(Settings::Settings::lineWrap)); + this->comboBoxLineWrapIndentation->setCurrentIndex(s->get(Settings::Settings::lineWrapIndentationStyle)); + this->spinBoxLineWrapIndentationIndent->setValue(s->get(Settings::Settings::lineWrapIndentation)); + this->comboBoxLineWrapVisualizationStart->setCurrentIndex(s->get(Settings::Settings::lineWrapVisualizationBegin)); + this->comboBoxLineWrapVisualizationEnd->setCurrentIndex(s->get(Settings::Settings::lineWrapVisualizationEnd)); + this->comboBoxShowWhitespaces->setCurrentIndex(s->get(Settings::Settings::showWhitespaces)); + this->spinBoxShowWhitespacesSize->setValue(s->get(Settings::Settings::showWhitespacesSize)); } void Preferences::apply() const diff --git a/src/Preferences.h b/src/Preferences.h index cd89fa97..e55420f7 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -43,6 +43,17 @@ public slots: void on_launcherBox_toggled(bool); void on_editorType_editTextChanged(const QString &); + // editor settings + void on_spinBoxIndentationWidth_valueChanged(int); + void on_spinBoxTabWidth_valueChanged(int); + void on_comboBoxLineWrap_activated(int); + void on_comboBoxLineWrapIndentation_activated(int); + void on_spinBoxLineWrapIndentationIndent_valueChanged(int); + void on_comboBoxLineWrapVisualizationStart_activated(int); + void on_comboBoxLineWrapVisualizationEnd_activated(int); + void on_comboBoxShowWhitespaces_activated(int); + void on_spinBoxShowWhitespacesSize_valueChanged(int); + signals: void requestRedraw() const; void updateMdiMode(bool mdi) const; @@ -53,6 +64,7 @@ signals: void openCSGSettingsChanged() const; void syntaxHighlightChanged(const QString &s) const; void editorTypeChanged(const QString &type); + void editorConfigChanged() const; private: Preferences(QWidget *parent = NULL); diff --git a/src/Preferences.ui b/src/Preferences.ui index cd3b88b7..f4374141 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -334,9 +334,9 @@ - + - Show whitespaces + Whitespaces @@ -353,25 +353,6 @@ - - - - - Never - - - - - Always - - - - - Only after indentation - - - - @@ -533,6 +514,55 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + 99 + + + + + + + + Never + + + + + Always + + + + + Only after indentation + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 9 + + + + + + + Show + + + + + + + Size + diff --git a/src/mainwin.cc b/src/mainwin.cc index 0bcfb34f..231eeb08 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -193,6 +193,7 @@ MainWindow::MainWindow(const QString &filename) #ifdef USE_SCINTILLA_EDITOR if (useScintilla) { editor = new ScintillaEditor(editorDockContents); + } else #endif @@ -200,6 +201,12 @@ MainWindow::MainWindow(const QString &filename) Preferences::create(editor->colorSchemes()); +#ifdef USE_SCINTILLA_EDITOR + if (useScintilla) { + connect(Preferences::inst(), SIGNAL(editorConfigChanged()), editor, SLOT(applySettings())); + } +#endif + editorDockContents->layout()->addWidget(editor); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 2d0f07d0..309cda34 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -6,489 +6,574 @@ #include #include "Preferences.h" #include "PlatformUtils.h" +#include "settings.h" + +class SettingsConverter { +public: + QsciScintilla::WrapMode fromWrapMode(Settings::LineWrap val); + QsciScintilla::WrapVisualFlag fromLineWrapVisualization(Settings::LineWrapVisualization val); + QsciScintilla::WrapIndentMode fromLineWrapIndentationStyle(Settings::LineWrapIndentationStyle val); + QsciScintilla::WhitespaceVisibility fromShowWhitespaces(Settings::ShowWhitespaces val); +}; + +QsciScintilla::WrapMode SettingsConverter::fromWrapMode(Settings::LineWrap val) +{ + switch (val) { + case Settings::LINE_WRAP_NONE: + return QsciScintilla::WrapNone; + case Settings::LINE_WRAP_CHARACTER: + return QsciScintilla::WrapCharacter; + case Settings::LINE_WRAP_WORD: + return QsciScintilla::WrapWord; + default: + assert(false && "unknown wrap mode setting"); + } +} + +QsciScintilla::WrapVisualFlag SettingsConverter::fromLineWrapVisualization(Settings::LineWrapVisualization val) +{ + switch (val) { + case Settings::LINE_WRAP_VISUALIZATION_NONE: + return QsciScintilla::WrapFlagNone; + case Settings::LINE_WRAP_VISUALIZATION_TEXT: + return QsciScintilla::WrapFlagByText; + case Settings::LINE_WRAP_VISUALIZATION_BORDER: + return QsciScintilla::WrapFlagByBorder; + case Settings::LINE_WRAP_VISUALIZATION_MARGIN: + return QsciScintilla::WrapFlagInMargin; + default: + assert(false && "unknown wrap visualization setting"); + } +} + +QsciScintilla::WrapIndentMode SettingsConverter::fromLineWrapIndentationStyle(Settings::LineWrapIndentationStyle val) +{ + switch (val) { + case Settings::LINE_WRAP_INDENTATION_FIXED: + return QsciScintilla::WrapIndentFixed; + case Settings::LINE_WRAP_INDENTATION_SAME: + return QsciScintilla::WrapIndentSame; + case Settings::LINE_WRAP_INDENTATION_INDENTED: + return QsciScintilla::WrapIndentIndented; + default: + assert(false && "unknown wrap indentation style setting"); + } +} + +QsciScintilla::WhitespaceVisibility SettingsConverter::fromShowWhitespaces(Settings::ShowWhitespaces val) +{ + switch(val) { + case Settings::SHOW_WHITESPACES_NEVER: + return QsciScintilla::WsInvisible; + case Settings::SHOW_WHITESPACES_ALWAYS: + return QsciScintilla::WsVisible; + case Settings::SHOW_WHITESPACES_AFTER_INDENTATION: + return QsciScintilla::WsVisibleAfterIndent; + default: + assert(false && "unknown show whitespace setting"); + } +} EditorColorScheme::EditorColorScheme(fs::path path) : path(path) { - try { - boost::property_tree::read_json(boosty::stringy(path).c_str(), pt); - _name = QString(pt.get("name").c_str()); - _index = pt.get("index"); - } catch (const std::exception & e) { - PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what()); - _name = ""; - _index = 0; - } + try { + boost::property_tree::read_json(boosty::stringy(path).c_str(), pt); + _name = QString(pt.get("name").c_str()); + _index = pt.get("index"); + } catch (const std::exception & e) { + PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what()); + _name = ""; + _index = 0; + } } EditorColorScheme::~EditorColorScheme() { - + } bool EditorColorScheme::valid() const { - return !_name.isEmpty(); + return !_name.isEmpty(); } const QString & EditorColorScheme::name() const { - return _name; + return _name; } int EditorColorScheme::index() const { - return _index; + return _index; } const boost::property_tree::ptree & EditorColorScheme::propertyTree() const { - return pt; + return pt; } ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent) { - scintillaLayout = new QVBoxLayout(this); - qsci = new QsciScintilla(this); + scintillaLayout = new QVBoxLayout(this); + qsci = new QsciScintilla(this); - // Force EOL mode to Unix, since QTextStream will manage local EOL modes. - qsci->setEolMode(QsciScintilla::EolUnix); + // Force EOL mode to Unix, since QTextStream will manage local EOL modes. + qsci->setEolMode(QsciScintilla::EolUnix); - // - // Remapping some scintilla key binding which conflict with OpenSCAD global - // key bindings, as well as some minor scintilla bugs - // - QsciCommand *c; + // + // Remapping some scintilla key binding which conflict with OpenSCAD global + // key bindings, as well as some minor scintilla bugs + // + QsciCommand *c; #ifdef Q_OS_MAC - // Alt-Backspace should delete left word (Alt-Delete already deletes right word) - c= qsci->standardCommands()->find(QsciCommand::DeleteWordLeft); - c->setKey(Qt::Key_Backspace | Qt::ALT); + // Alt-Backspace should delete left word (Alt-Delete already deletes right word) + c = qsci->standardCommands()->find(QsciCommand::DeleteWordLeft); + c->setKey(Qt::Key_Backspace | Qt::ALT); #endif - // Cmd/Ctrl-T is handled by the menu - c = qsci->standardCommands()->boundTo(Qt::Key_T | Qt::CTRL); - c->setKey(0); - // Cmd/Ctrl-D is handled by the menu - c = qsci->standardCommands()->boundTo(Qt::Key_D | Qt::CTRL); - c->setKey(0); - // Ctrl-Shift-Z should redo on all platforms - c= qsci->standardCommands()->find(QsciCommand::Redo); - c->setKey(Qt::Key_Z | Qt::CTRL | Qt::SHIFT); + // Cmd/Ctrl-T is handled by the menu + c = qsci->standardCommands()->boundTo(Qt::Key_T | Qt::CTRL); + c->setKey(0); + // Cmd/Ctrl-D is handled by the menu + c = qsci->standardCommands()->boundTo(Qt::Key_D | Qt::CTRL); + c->setKey(0); + // Ctrl-Shift-Z should redo on all platforms + c = qsci->standardCommands()->find(QsciCommand::Redo); + c->setKey(Qt::Key_Z | Qt::CTRL | Qt::SHIFT); - scintillaLayout->setContentsMargins(0, 0, 0, 0); - scintillaLayout->addWidget(qsci); + scintillaLayout->setContentsMargins(0, 0, 0, 0); + scintillaLayout->addWidget(qsci); - qsci->setBraceMatching (QsciScintilla::SloppyBraceMatch); - qsci->setWrapMode(QsciScintilla::WrapCharacter); - qsci->setWrapVisualFlags(QsciScintilla::WrapFlagByBorder, QsciScintilla::WrapFlagNone, 0); - qsci->setAutoIndent(true); - qsci->indicatorDefine(QsciScintilla::RoundBoxIndicator, indicatorNumber); - qsci->markerDefine(QsciScintilla::Circle, markerNumber); - qsci->setUtf8(true); - qsci->setTabIndents(true); - qsci->setTabWidth(8); - qsci->setIndentationWidth(4); - qsci->setIndentationsUseTabs(false); - - lexer = new ScadLexer(this); - qsci->setLexer(lexer); - initMargin(); - qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4); - qsci->setCaretLineVisible(true); + qsci->indicatorDefine(QsciScintilla::RoundBoxIndicator, indicatorNumber); + qsci->markerDefine(QsciScintilla::Circle, markerNumber); + qsci->setUtf8(true); + applySettings(); - connect(qsci, SIGNAL(textChanged()), this, SIGNAL(contentsChanged())); - connect(qsci, SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool))); + lexer = new ScadLexer(this); + qsci->setLexer(lexer); + initMargin(); + + connect(qsci, SIGNAL(textChanged()), this, SIGNAL(contentsChanged())); + connect(qsci, SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool))); +} + +/** + * Apply the settings that are changeable in the preferences. This is also + * called in the event handler from the preferences. + */ +void ScintillaEditor::applySettings() +{ + SettingsConverter conv; + Settings::Settings *s = Settings::Settings::inst(); + + qsci->setIndentationWidth(s->get(Settings::Settings::indentationWidth)); + qsci->setTabWidth(s->get(Settings::Settings::tabWidth)); + qsci->setWrapMode(conv.fromWrapMode(s->get(Settings::Settings::lineWrap))); + qsci->setWrapIndentMode(conv.fromLineWrapIndentationStyle(s->get(Settings::Settings::lineWrapIndentationStyle))); + qsci->setWrapVisualFlags(conv.fromLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationEnd)), + conv.fromLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationBegin)), + s->get(Settings::Settings::lineWrapIndentation)); + qsci->setWhitespaceVisibility(conv.fromShowWhitespaces(s->get(Settings::Settings::showWhitespaces))); + qsci->setWhitespaceSize(s->get(Settings::Settings::showWhitespacesSize)); + + qsci->setBraceMatching(QsciScintilla::SloppyBraceMatch); + qsci->setAutoIndent(true); + qsci->setTabIndents(true); + qsci->setIndentationsUseTabs(false); + qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4); + qsci->setCaretLineVisible(true); } void ScintillaEditor::setPlainText(const QString &text) -{ - qsci->setText(text); - setContentModified(false); +{ + qsci->setText(text); + setContentModified(false); } QString ScintillaEditor::toPlainText() { - return qsci->text(); + return qsci->text(); } void ScintillaEditor::setContentModified(bool modified) { - // FIXME: Due to an issue with QScintilla, we need to do this on the document itself. + // FIXME: Due to an issue with QScintilla, we need to do this on the document itself. #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - qsci->SCN_SAVEPOINTLEFT(); + qsci->SCN_SAVEPOINTLEFT(); #endif - qsci->setModified(modified); + qsci->setModified(modified); } bool ScintillaEditor::isContentModified() { - return qsci->isModified(); + return qsci->isModified(); } -void ScintillaEditor::highlightError(int error_pos) +void ScintillaEditor::highlightError(int error_pos) { - int line, index; - qsci->lineIndexFromPosition(error_pos, &line, &index); - qsci->fillIndicatorRange(line, index, line, index+1, indicatorNumber); - qsci->markerAdd(line, markerNumber); + int line, index; + qsci->lineIndexFromPosition(error_pos, &line, &index); + qsci->fillIndicatorRange(line, index, line, index + 1, indicatorNumber); + qsci->markerAdd(line, markerNumber); } -void ScintillaEditor::unhighlightLastError() +void ScintillaEditor::unhighlightLastError() { - int totalLength = qsci->text().length(); - int line, index; - qsci->lineIndexFromPosition(totalLength, &line, &index); - qsci->clearIndicatorRange(0, 0, line, index, indicatorNumber); - qsci->markerDeleteAll(markerNumber); + int totalLength = qsci->text().length(); + int line, index; + qsci->lineIndexFromPosition(totalLength, &line, &index); + qsci->clearIndicatorRange(0, 0, line, index, indicatorNumber); + qsci->markerDeleteAll(markerNumber); } QColor ScintillaEditor::readColor(const boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor) { - try { - const std::string val = pt.get(name); - return QColor(val.c_str()); - } catch (std::exception e) { - return defaultColor; - } + try { + const std::string val = pt.get(name); + return QColor(val.c_str()); + } catch (std::exception e) { + return defaultColor; + } } std::string ScintillaEditor::readString(const boost::property_tree::ptree &pt, const std::string name, const std::string defaultValue) { - try { - const std::string val = pt.get(name); - return val; - } catch (std::exception e) { - return defaultValue; - } + try { + const std::string val = pt.get(name); + return val; + } catch (std::exception e) { + return defaultValue; + } } int ScintillaEditor::readInt(const boost::property_tree::ptree &pt, const std::string name, const int defaultValue) { - try { - const int val = pt.get(name); - return val; - } catch (std::exception e) { - return defaultValue; - } + try { + const int val = pt.get(name); + return val; + } catch (std::exception e) { + return defaultValue; + } } void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme) { - const boost::property_tree::ptree & pt = colorScheme->propertyTree(); + const boost::property_tree::ptree & pt = colorScheme->propertyTree(); - try { - QFont font = lexer->font(lexer->defaultStyle()); - const QColor textColor(pt.get("text").c_str()); - const QColor paperColor(pt.get("paper").c_str()); + try { + QFont font = lexer->font(lexer->defaultStyle()); + const QColor textColor(pt.get("text").c_str()); + const QColor paperColor(pt.get("paper").c_str()); - ScadLexer *l = new ScadLexer(this); + ScadLexer *l = new ScadLexer(this); - // Keywords must be set before the lexer is attached to QScintilla - // as they seem to be read and cached at attach time. - boost::optional keywords = pt.get_child_optional("keywords"); - if (keywords.is_initialized()) { - l->setKeywords(1, readString(keywords.get(), "keyword-set1", "")); - l->setKeywords(2, readString(keywords.get(), "keyword-set2", "")); - l->setKeywords(3, readString(keywords.get(), "keyword-set-doc", "")); - l->setKeywords(4, readString(keywords.get(), "keyword-set3", "")); + // Keywords must be set before the lexer is attached to QScintilla + // as they seem to be read and cached at attach time. + boost::optional keywords = pt.get_child_optional("keywords"); + if (keywords.is_initialized()) { + l->setKeywords(1, readString(keywords.get(), "keyword-set1", "")); + l->setKeywords(2, readString(keywords.get(), "keyword-set2", "")); + l->setKeywords(3, readString(keywords.get(), "keyword-set-doc", "")); + l->setKeywords(4, readString(keywords.get(), "keyword-set3", "")); + } + + qsci->setLexer(l); + delete lexer; + lexer = l; + + // All other properties must be set after attaching to QSCintilla so + // the editor gets the change events and updates itself to match + l->setFont(font); + l->setColor(textColor); + l->setPaper(paperColor); + + const boost::property_tree::ptree& colors = pt.get_child("colors"); + l->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword); + l->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2); + l->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass); + l->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number); + l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::SingleQuotedString); + l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString); + l->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator); + l->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::Comment); + l->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine); + l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentDoc); + l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentLineDoc); + l->setColor(readColor(colors, "commentdockeyword", textColor), QsciLexerCPP::CommentDocKeyword); + + const boost::property_tree::ptree& caret = pt.get_child("caret"); + qsci->setCaretWidth(readInt(caret, "width", 1)); + qsci->setCaretForegroundColor(readColor(caret, "foreground", textColor)); + qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor)); + + qsci->setMarkerBackgroundColor(readColor(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber); + qsci->setIndicatorForegroundColor(readColor(colors, "error-indicator", QColor(255, 0, 0, 100)), indicatorNumber); + qsci->setIndicatorOutlineColor(readColor(colors, "error-indicator-outline", QColor(255, 0, 0, 100)), indicatorNumber); + qsci->setWhitespaceBackgroundColor(readColor(colors, "whitespace-background", paperColor)); + qsci->setWhitespaceForegroundColor(readColor(colors, "whitespace-foreground", textColor)); + qsci->setMarginsBackgroundColor(readColor(colors, "margin-background", paperColor)); + qsci->setMarginsForegroundColor(readColor(colors, "margin-foreground", textColor)); + qsci->setMatchedBraceBackgroundColor(readColor(colors, "matched-brace-background", paperColor)); + qsci->setMatchedBraceForegroundColor(readColor(colors, "matched-brace-foreground", textColor)); + qsci->setUnmatchedBraceBackgroundColor(readColor(colors, "unmatched-brace-background", paperColor)); + qsci->setUnmatchedBraceForegroundColor(readColor(colors, "unmatched-brace-foreground", textColor)); + qsci->setSelectionForegroundColor(readColor(colors, "selection-foreground", paperColor)); + qsci->setSelectionBackgroundColor(readColor(colors, "selection-background", textColor)); + qsci->setFoldMarginColors(readColor(colors, "margin-foreground", textColor), + readColor(colors, "margin-background", paperColor)); + qsci->setEdgeColor(readColor(colors, "edge", textColor)); + } catch (std::exception e) { + noColor(); } - - qsci->setLexer(l); - delete lexer; - lexer = l; - - // All other properties must be set after attaching to QSCintilla so - // the editor gets the change events and updates itself to match - l->setFont(font); - l->setColor(textColor); - l->setPaper(paperColor); - - const boost::property_tree::ptree& colors = pt.get_child("colors"); - l->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword); - l->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2); - l->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass); - l->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number); - l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::SingleQuotedString); - l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString); - l->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator); - l->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::Comment); - l->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine); - l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentDoc); - l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentLineDoc); - l->setColor(readColor(colors, "commentdockeyword", textColor), QsciLexerCPP::CommentDocKeyword); - - const boost::property_tree::ptree& caret = pt.get_child("caret"); - qsci->setCaretWidth(readInt(caret, "width", 1)); - qsci->setCaretForegroundColor(readColor(caret, "foreground", textColor)); - qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor)); - - qsci->setMarkerBackgroundColor(readColor(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber); - qsci->setIndicatorForegroundColor(readColor(colors, "error-indicator", QColor(255, 0, 0, 100)), indicatorNumber); - qsci->setIndicatorOutlineColor(readColor(colors, "error-indicator-outline", QColor(255, 0, 0, 100)), indicatorNumber); - qsci->setWhitespaceBackgroundColor(readColor(colors, "whitespace-background", paperColor)); - qsci->setWhitespaceForegroundColor(readColor(colors, "whitespace-foreground", textColor)); - qsci->setMarginsBackgroundColor(readColor(colors, "margin-background", paperColor)); - qsci->setMarginsForegroundColor(readColor(colors, "margin-foreground", textColor)); - qsci->setMatchedBraceBackgroundColor(readColor(colors, "matched-brace-background", paperColor)); - qsci->setMatchedBraceForegroundColor(readColor(colors, "matched-brace-foreground", textColor)); - qsci->setUnmatchedBraceBackgroundColor(readColor(colors, "unmatched-brace-background", paperColor)); - qsci->setUnmatchedBraceForegroundColor(readColor(colors, "unmatched-brace-foreground", textColor)); - qsci->setSelectionForegroundColor(readColor(colors, "selection-foreground", paperColor)); - qsci->setSelectionBackgroundColor(readColor(colors, "selection-background", textColor)); - qsci->setFoldMarginColors(readColor(colors, "margin-foreground", textColor), - readColor(colors, "margin-background", paperColor)); - qsci->setEdgeColor(readColor(colors, "edge", textColor)); - } catch (std::exception e) { - noColor(); - } } void ScintillaEditor::noColor() { - lexer->setPaper(Qt::white); - lexer->setColor(Qt::black); - qsci->setCaretWidth(2); - qsci->setCaretForegroundColor(Qt::black); - qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber); - qsci->setIndicatorForegroundColor(QColor(255, 0, 0, 128), indicatorNumber); - qsci->setIndicatorOutlineColor(QColor(0, 0, 0, 255), indicatorNumber); // only alpha part is used - qsci->setCaretLineBackgroundColor(Qt::white); - qsci->setWhitespaceBackgroundColor(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->setMatchedBraceForegroundColor(Qt::black); - qsci->setUnmatchedBraceBackgroundColor(Qt::white); - qsci->setUnmatchedBraceForegroundColor(Qt::black); - qsci->setMarginsBackgroundColor(Qt::lightGray); - qsci->setMarginsForegroundColor(Qt::black); - qsci->setFoldMarginColors(Qt::black, Qt::lightGray); - qsci->setEdgeColor(Qt::black); + lexer->setPaper(Qt::white); + lexer->setColor(Qt::black); + qsci->setCaretWidth(2); + qsci->setCaretForegroundColor(Qt::black); + qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber); + qsci->setIndicatorForegroundColor(QColor(255, 0, 0, 128), indicatorNumber); + qsci->setIndicatorOutlineColor(QColor(0, 0, 0, 255), indicatorNumber); // only alpha part is used + qsci->setCaretLineBackgroundColor(Qt::white); + qsci->setWhitespaceBackgroundColor(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->setMatchedBraceForegroundColor(Qt::black); + qsci->setUnmatchedBraceBackgroundColor(Qt::white); + qsci->setUnmatchedBraceForegroundColor(Qt::black); + qsci->setMarginsBackgroundColor(Qt::lightGray); + qsci->setMarginsForegroundColor(Qt::black); + qsci->setFoldMarginColors(Qt::black, Qt::lightGray); + qsci->setEdgeColor(Qt::black); } void ScintillaEditor::enumerateColorSchemesInPath(ScintillaEditor::colorscheme_set_t &result_set, const fs::path path) { - const fs::path color_schemes = path / "color-schemes" / "editor"; + const fs::path color_schemes = path / "color-schemes" / "editor"; - fs::directory_iterator end_iter; - - if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) { - for (fs::directory_iterator dir_iter(color_schemes); dir_iter != end_iter; ++dir_iter) { - if (!fs::is_regular_file(dir_iter->status())) { - continue; - } - - const fs::path path = (*dir_iter).path(); - if (!(path.extension().string() == ".json")) { - continue; - } - - EditorColorScheme *colorScheme = new EditorColorScheme(path); - if (colorScheme->valid()) { - result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr(colorScheme))); - } else { - delete colorScheme; - } + fs::directory_iterator end_iter; + + if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) { + for (fs::directory_iterator dir_iter(color_schemes); dir_iter != end_iter; ++dir_iter) { + if (!fs::is_regular_file(dir_iter->status())) { + continue; + } + + const fs::path path = (*dir_iter).path(); + if (!(path.extension().string() == ".json")) { + continue; + } + + EditorColorScheme *colorScheme = new EditorColorScheme(path); + if (colorScheme->valid()) { + result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr(colorScheme))); + } else { + delete colorScheme; + } + } } - } } ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes() { - colorscheme_set_t result_set; + colorscheme_set_t result_set; - enumerateColorSchemesInPath(result_set, PlatformUtils::resourceBasePath()); - enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); - - return result_set; + enumerateColorSchemesInPath(result_set, PlatformUtils::resourceBasePath()); + enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath()); + + return result_set; } QStringList ScintillaEditor::colorSchemes() { - const colorscheme_set_t colorscheme_set = enumerateColorSchemes(); + const colorscheme_set_t colorscheme_set = enumerateColorSchemes(); - QStringList colorSchemes; - for (colorscheme_set_t::const_iterator it = colorscheme_set.begin();it != colorscheme_set.end();it++) { - colorSchemes << (*it).second.get()->name(); - } - colorSchemes << "Off"; - - return colorSchemes; + QStringList colorSchemes; + for (colorscheme_set_t::const_iterator it = colorscheme_set.begin(); it != colorscheme_set.end(); it++) { + colorSchemes << (*it).second.get()->name(); + } + colorSchemes << "Off"; + + return colorSchemes; } void ScintillaEditor::setHighlightScheme(const QString &name) { - const colorscheme_set_t colorscheme_set = enumerateColorSchemes(); + const colorscheme_set_t colorscheme_set = enumerateColorSchemes(); - for (colorscheme_set_t::const_iterator it = colorscheme_set.begin();it != colorscheme_set.end();it++) { - const EditorColorScheme *colorScheme = (*it).second.get(); - if (colorScheme->name() == name) { - setColormap(colorScheme); - return; + for (colorscheme_set_t::const_iterator it = colorscheme_set.begin(); it != colorscheme_set.end(); it++) { + const EditorColorScheme *colorScheme = (*it).second.get(); + if (colorScheme->name() == name) { + setColormap(colorScheme); + return; + } } - } - - noColor(); + + noColor(); } void ScintillaEditor::insert(const QString &text) { - qsci->insert(text); + qsci->insert(text); } void ScintillaEditor::replaceAll(const QString &text) { - qsci->selectAll(true); - qsci->replaceSelectedText(text); + qsci->selectAll(true); + qsci->replaceSelectedText(text); } void ScintillaEditor::undo() { - qsci->undo(); + qsci->undo(); } void ScintillaEditor::redo() { - qsci->redo(); + qsci->redo(); } void ScintillaEditor::cut() { - qsci->cut(); + qsci->cut(); } void ScintillaEditor::copy() { - qsci->copy(); + qsci->copy(); } void ScintillaEditor::paste() -{ - qsci->paste(); +{ + qsci->paste(); } void ScintillaEditor::zoomIn() { - qsci->zoomIn(); + qsci->zoomIn(); } -void ScintillaEditor::zoomOut() +void ScintillaEditor::zoomOut() { - qsci->zoomOut(); + qsci->zoomOut(); } void ScintillaEditor::initFont(const QString& fontName, uint size) { - QFont font(fontName, size); - font.setFixedPitch(true); - lexer->setFont(font); + QFont font(fontName, size); + font.setFixedPitch(true); + lexer->setFont(font); } void ScintillaEditor::initMargin() { - QFontMetrics fontmetrics = QFontMetrics(qsci->font()); - qsci->setMarginsFont(qsci->font()); - qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6); - qsci->setMarginLineNumbers(1, true); - - connect(qsci, SIGNAL(textChanged()), this, SLOT(onTextChanged())); + QFontMetrics fontmetrics = QFontMetrics(qsci->font()); + qsci->setMarginsFont(qsci->font()); + qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6); + qsci->setMarginLineNumbers(1, true); + + connect(qsci, SIGNAL(textChanged()), this, SLOT(onTextChanged())); } void ScintillaEditor::onTextChanged() { - QFontMetrics fontmetrics = qsci->fontMetrics(); - qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6); + QFontMetrics fontmetrics = qsci->fontMetrics(); + qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6); } bool ScintillaEditor::find(const QString &expr, bool findNext, bool findBackwards) { - int startline = -1, startindex = -1; + int startline = -1, startindex = -1; - // If findNext, start from the end of the current selection - if (qsci->hasSelectedText()) { - int lineFrom, indexFrom, lineTo, indexTo; - qsci->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo); - - startline = !(findBackwards xor findNext) ? std::min(lineFrom, lineTo) : std::max(lineFrom, lineTo); - startindex = !(findBackwards xor findNext) ? std::min(indexFrom, indexTo) : std::max(indexFrom, indexTo); - } + // If findNext, start from the end of the current selection + if (qsci->hasSelectedText()) { + int lineFrom, indexFrom, lineTo, indexTo; + qsci->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo); - return qsci->findFirst(expr, false, false, false, true, - !findBackwards, startline, startindex); + startline = !(findBackwards xor findNext) ? std::min(lineFrom, lineTo) : std::max(lineFrom, lineTo); + startindex = !(findBackwards xor findNext) ? std::min(indexFrom, indexTo) : std::max(indexFrom, indexTo); + } + + return qsci->findFirst(expr, false, false, false, true, + !findBackwards, startline, startindex); } void ScintillaEditor::replaceSelectedText(const QString &newText) { - if (qsci->selectedText() != newText) qsci->replaceSelectedText(newText); + if (qsci->selectedText() != newText) qsci->replaceSelectedText(newText); } void ScintillaEditor::getRange(int *lineFrom, int *lineTo) { - int indexFrom, indexTo; - if (qsci->hasSelectedText()) { - qsci->getSelection(lineFrom, &indexFrom, lineTo, &indexTo); - if (indexTo == 0) { - *lineTo = *lineTo - 1; + int indexFrom, indexTo; + if (qsci->hasSelectedText()) { + qsci->getSelection(lineFrom, &indexFrom, lineTo, &indexTo); + if (indexTo == 0) { + *lineTo = *lineTo - 1; + } + } else { + qsci->getCursorPosition(lineFrom, &indexFrom); + *lineTo = *lineFrom; } - } else { - qsci->getCursorPosition(lineFrom, &indexFrom); - *lineTo = *lineFrom; - } } void ScintillaEditor::indentSelection() { - int lineFrom, lineTo; - getRange(&lineFrom, &lineTo); - for (int line = lineFrom;line <= lineTo;line++) { - qsci->indent(line); - } + int lineFrom, lineTo; + getRange(&lineFrom, &lineTo); + for (int line = lineFrom; line <= lineTo; line++) { + qsci->indent(line); + } } void ScintillaEditor::unindentSelection() { - int lineFrom, lineTo; - getRange(&lineFrom, &lineTo); - for (int line = lineFrom;line <= lineTo;line++) { - qsci->unindent(line); - } + int lineFrom, lineTo; + getRange(&lineFrom, &lineTo); + for (int line = lineFrom; line <= lineTo; line++) { + qsci->unindent(line); + } } void ScintillaEditor::commentSelection() { - bool hasSelection = qsci->hasSelectedText(); - - int lineFrom, lineTo; - getRange(&lineFrom, &lineTo); - for (int line = lineFrom;line <= lineTo;line++) { - qsci->insertAt("//", line, 0); - } - - if (hasSelection) { - qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1)); - } + bool hasSelection = qsci->hasSelectedText(); + + int lineFrom, lineTo; + getRange(&lineFrom, &lineTo); + for (int line = lineFrom; line <= lineTo; line++) { + qsci->insertAt("//", line, 0); + } + + if (hasSelection) { + qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1)); + } } void ScintillaEditor::uncommentSelection() { - bool hasSelection = qsci->hasSelectedText(); + bool hasSelection = qsci->hasSelectedText(); - int lineFrom, lineTo; - getRange(&lineFrom, &lineTo); - for (int line = lineFrom;line <= lineTo;line++) { - QString lineText = qsci->text(line); - if (lineText.startsWith("//")) { - qsci->setSelection(line, 0, line, 2); - qsci->removeSelectedText(); + int lineFrom, lineTo; + getRange(&lineFrom, &lineTo); + for (int line = lineFrom; line <= lineTo; line++) { + QString lineText = qsci->text(line); + if (lineText.startsWith("//")) { + qsci->setSelection(line, 0, line, 2); + qsci->removeSelectedText(); + } + } + if (hasSelection) { + qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1)); } - } - if (hasSelection) { - qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1)); - } } QString ScintillaEditor::selectedText() { - return qsci->selectedText(); + return qsci->selectedText(); } diff --git a/src/scintillaeditor.h b/src/scintillaeditor.h index 42fcd274..4a4cdaa0 100644 --- a/src/scintillaeditor.h +++ b/src/scintillaeditor.h @@ -87,6 +87,7 @@ public slots: private slots: void onTextChanged(); + void applySettings(); private: QVBoxLayout *scintillaLayout; diff --git a/src/settings.cc b/src/settings.cc index cf352fdd..823df0e2 100644 --- a/src/settings.cc +++ b/src/settings.cc @@ -1,8 +1,10 @@ #include "settings.h" +namespace Settings { + template SettingsEntry::SettingsEntry(const std::string category, const std::string name, T defaultValue) - : category(category), name(name), defaultValue(defaultValue) + : category(category), name(name), value(defaultValue), defaultValue(defaultValue) { } @@ -13,7 +15,13 @@ SettingsEntry::~SettingsEntry() SettingsEntry Settings::indentationWidth("editor", "indentationWidth", 4); SettingsEntry Settings::tabWidth("editor", "tabWidth", 8); -SettingsEntry Settings::lineWrap("editor", "lineWrap", LINE_WRAP_WORD); +SettingsEntry Settings::lineWrap("editor", "lineWrap", LINE_WRAP_WORD); +SettingsEntry Settings::lineWrapIndentationStyle("editor", "lineWrapIndentationStyle", LINE_WRAP_INDENTATION_FIXED); +SettingsEntry Settings::lineWrapIndentation("editor", "lineWrapIndentation", 4); +SettingsEntry Settings::lineWrapVisualizationBegin("editor", "lineWrapVisualizationBegin", LINE_WRAP_VISUALIZATION_NONE); +SettingsEntry Settings::lineWrapVisualizationEnd("editor", "lineWrapVisualizationEnd", LINE_WRAP_VISUALIZATION_BORDER); +SettingsEntry Settings::showWhitespaces("editor", "showWhitespaces", SHOW_WHITESPACES_NEVER); +SettingsEntry Settings::showWhitespacesSize("editor", "showWhitespacesSize", 2); Settings *Settings::inst(bool erase) { @@ -41,5 +49,36 @@ T Settings::defaultValue(const SettingsEntry &entry) return entry.defaultValue; } +template +T Settings::get(const SettingsEntry &entry) +{ + return entry.value; +} + +template +void Settings::set(SettingsEntry &entry, T val) +{ + entry.value = val; +} + template int Settings::defaultValue(const SettingsEntry&); -template SettingsLineWrap Settings::defaultValue(const SettingsEntry&); +template int Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, int); + +template LineWrap Settings::defaultValue(const SettingsEntry&); +template LineWrap Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, LineWrap); + +template LineWrapVisualization Settings::defaultValue(const SettingsEntry&); +template LineWrapVisualization Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, LineWrapVisualization); + +template LineWrapIndentationStyle Settings::defaultValue(const SettingsEntry&); +template LineWrapIndentationStyle Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, LineWrapIndentationStyle); + +template ShowWhitespaces Settings::defaultValue(const SettingsEntry&); +template ShowWhitespaces Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, ShowWhitespaces); + +} \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index 18e69c4d..b854354e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -3,15 +3,37 @@ #include #include +namespace Settings { + typedef enum { LINE_WRAP_NONE, LINE_WRAP_CHARACTER, LINE_WRAP_WORD, -} SettingsLineWrap; +} LineWrap; + +typedef enum { + LINE_WRAP_INDENTATION_FIXED, + LINE_WRAP_INDENTATION_SAME, + LINE_WRAP_INDENTATION_INDENTED, +} LineWrapIndentationStyle; + +typedef enum { + LINE_WRAP_VISUALIZATION_NONE, + LINE_WRAP_VISUALIZATION_TEXT, + LINE_WRAP_VISUALIZATION_BORDER, + LINE_WRAP_VISUALIZATION_MARGIN, +} LineWrapVisualization; + +typedef enum { + SHOW_WHITESPACES_NEVER, + SHOW_WHITESPACES_ALWAYS, + SHOW_WHITESPACES_AFTER_INDENTATION, +} ShowWhitespaces; template class SettingsEntry { +private: std::string category; std::string name; T value; @@ -28,13 +50,23 @@ class Settings public: static SettingsEntry indentationWidth; static SettingsEntry tabWidth; - static SettingsEntry lineWrap; - + static SettingsEntry lineWrap; + static SettingsEntry lineWrapIndentationStyle; + static SettingsEntry lineWrapIndentation; + static SettingsEntry lineWrapVisualizationBegin; + static SettingsEntry lineWrapVisualizationEnd; + static SettingsEntry showWhitespaces; + static SettingsEntry showWhitespacesSize; + static Settings *inst(bool erase = false); template T defaultValue(const SettingsEntry &entry); + template T get(const SettingsEntry &entry); + template void set(SettingsEntry &entry, T val); private: Settings(); virtual ~Settings(); }; + +} \ No newline at end of file From 6c25d5ccb6a0e263790b9bb8a3c4399abefa2f97 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 27 Dec 2014 02:59:11 +0100 Subject: [PATCH 212/263] Add more settings (AutoIndent / TabIndents / IndentationsUseTabs). --- src/Preferences.cc | 21 + src/Preferences.h | 3 + src/Preferences.ui | 1372 +++++++++++++++++++++------------------ src/scintillaeditor.cpp | 6 +- src/settings.cc | 7 + src/settings.h | 3 + 6 files changed, 776 insertions(+), 636 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index 45afcba9..7265d1a3 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -461,6 +461,24 @@ void Preferences::on_spinBoxShowWhitespacesSize_valueChanged(int val) emit editorConfigChanged(); } +void Preferences::on_checkBoxAutoIndent_toggled(bool val) +{ + Settings::Settings::inst()->set(Settings::Settings::autoIndent, val); + emit editorConfigChanged(); +} + +void Preferences::on_checkBoxTabIndents_toggled(bool val) +{ + Settings::Settings::inst()->set(Settings::Settings::tabIndents, val); + emit editorConfigChanged(); +} + +void Preferences::on_checkBoxIndentationsUseTabs_toggled(bool val) +{ + Settings::Settings::inst()->set(Settings::Settings::indentationsUseTabs, val); + emit editorConfigChanged(); +} + void Preferences::keyPressEvent(QKeyEvent *e) { #ifdef Q_OS_MAC @@ -565,6 +583,9 @@ void Preferences::updateGUI() this->comboBoxLineWrapVisualizationEnd->setCurrentIndex(s->get(Settings::Settings::lineWrapVisualizationEnd)); this->comboBoxShowWhitespaces->setCurrentIndex(s->get(Settings::Settings::showWhitespaces)); this->spinBoxShowWhitespacesSize->setValue(s->get(Settings::Settings::showWhitespacesSize)); + this->checkBoxAutoIndent->setChecked(s->get(Settings::Settings::autoIndent)); + this->checkBoxTabIndents->setChecked(s->get(Settings::Settings::tabIndents)); + this->checkBoxIndentationsUseTabs->setChecked(s->get(Settings::Settings::indentationsUseTabs)); } void Preferences::apply() const diff --git a/src/Preferences.h b/src/Preferences.h index e55420f7..f4122dff 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -53,6 +53,9 @@ public slots: void on_comboBoxLineWrapVisualizationEnd_activated(int); void on_comboBoxShowWhitespaces_activated(int); void on_spinBoxShowWhitespacesSize_valueChanged(int); + void on_checkBoxAutoIndent_toggled(bool); + void on_checkBoxTabIndents_toggled(bool); + void on_checkBoxIndentationsUseTabs_toggled(bool); signals: void requestRedraw() const; diff --git a/src/Preferences.ui b/src/Preferences.ui index f4374141..9c1e0275 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -6,8 +6,8 @@ 0 0 - 852 - 592 + 613 + 349 @@ -27,7 +27,7 @@ - 1 + 0 @@ -75,512 +75,578 @@ - - - - Qt::Vertical - - - - 20 - 645 - - - - + + 0 + + + 0 + - - - - - - 75 - true - - - - Editor Type - - - - - - - - Simple Editor - - - - - QScintilla Editor - - - - - - - - - 10 - 50 - false - - - - (requires restart) - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 30 - 20 - - - - - - - - - - - - - 75 - true - - - - Font - - - false - - - - - - - - Nimbus Sans L - 12 - - - - - - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 + + + QFrame::Plain - - - - - 75 - true - - - - Color syntax highlighting - - - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 30 - 20 - - - - - - - - - - 5 + + Qt::ScrollBarAlwaysOn - - - - - 75 - true - - - - Use Ctrl/Cmd-Mouse-wheel to zoom text - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Editor settings + + true - - - 20 + + + + 0 + 0 + 685 + 609 + - - - - - None + + + 9 + + + 9 + + + + + + + + 75 + true + + + + Editor Type + + + + + + + + Simple Editor + + + + + QScintilla Editor + + + + + + + + + 10 + 50 + false + + + + (requires restart) + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 30 + 20 + + + + + + + + + + + + + 75 + true + + + + Font + + + false + + + + + + + + Nimbus Sans L + 12 + + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 - - - - Wrap at character boundaries + + + + + 75 + true + + + + Color syntax highlighting + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 30 + 20 + + + + + + + + + + 5 - - - - Wrap at word boundaries + + + + + 75 + true + + + + Use Ctrl/Cmd-Mouse-wheel to zoom text + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Editor settings - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 2 - - - - - - - - Whitespaces - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - None + + + 20 + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + None + + + + + Wrap at character boundaries + + + + + Wrap at word boundaries + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 2 + + + + + + + + Whitespaces + + + + + + + + 0 + 0 + + + + + None + + + + + Text + + + + + Border + + + + + Margin + + + + + + + + Start + + + + + + + Line wrap visualization + + + + + + + Line wrap indentation + + + + + + + Tab width + + + + + + + Line wrap + + + + + + + End + + + + + + + + 0 + 0 + + + + + None + + + + + Text + + + + + Border + + + + + Margin + + + + + + + + Indent + + + + + + + + Fixed + + + + + Same + + + + + Indented + + + + + + + + Style + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Indentation width + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 99 + + + + + + + + Never + + + + + Always + + + + + Only after indentation + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 9 + + + + + + + Show + + + + + + + Size + + + + + + + + + + + + + + Auto Indent + + + + + + + Tab Indents + + + + + + + Indentations Use Tabs + + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical - - - - Text + + + 20 + 40 + - - - - Border - - - - - Margin - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Start - - - - - - - Line wrap visualization - - - - - - - Line wrap indentation - - - - - - - Tab width - - - - - - - Line wrap - - - - - - - End - - - - - - - - 0 - 0 - - - - - None - - - - - Text - - - - - Border - - - - - Margin - - - - - - - - Indent - - - - - - - - Fixed - - - - - Same - - - - - Indented - - - - - - - - Style - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Indentation width - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 99 - - - - - - - - Never - - - - - Always - - - - - Only after indentation - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 9 - - - - - - - Show - - - - - - - Size - - - - + + + + - - - - Qt::Vertical - - - - 20 - 723 - - - - @@ -801,153 +867,193 @@ + + 0 + - - - OpenCSG + + + QFrame::Plain - - - - - Show capability warning - - - true - - - - - - - Enable for OpenGL 1.x - - - - - - - - - Turn off rendering at - - - - - - - - - - elements - - - - - - - - - Force Goldfeather - - - - - - - - - - - - CGAL Cache size - - - - - - - - - - bytes - - - - - - - - - - - PolySet Cache size - - - - - - - - - - bytes - - - - - - - - - Allow to open multiple documents + + Qt::ScrollBarAlwaysOn - - - - - - Enable docking of Editor and Console in different places - - - - - - - Enable undocking of Editor and Console to separate windows - - - - - - - Show Welcome Screen - - - - - - - Enable user interface localization (requires restart of OpenSCAD) - - + true + + + + 0 + 0 + 596 + 499 + + + + + 9 + + + 9 + + + 9 + + + + + OpenCSG + + + + + + Show capability warning + + + true + + + + + + + Enable for OpenGL 1.x + + + + + + + + + Turn off rendering at + + + + + + + + + + elements + + + + + + + + + Force Goldfeather + + + + + + + + + + + + CGAL Cache size + + + + + + + + + + bytes + + + + + + + + + 0 + + + + + PolySet Cache size + + + + + + + + + + bytes + + + + + + + + + Allow to open multiple documents + + + + + + + Enable docking of Editor and Console in different places + + + + + + + Enable undocking of Editor and Console to separate windows + + + + + + + Show Welcome Screen + + + + + + + Enable user interface localization (requires restart of OpenSCAD) + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - - - - Qt::Vertical - - - - 20 - 11 - - - - diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 309cda34..7836d6b1 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -174,11 +174,11 @@ void ScintillaEditor::applySettings() s->get(Settings::Settings::lineWrapIndentation)); qsci->setWhitespaceVisibility(conv.fromShowWhitespaces(s->get(Settings::Settings::showWhitespaces))); qsci->setWhitespaceSize(s->get(Settings::Settings::showWhitespacesSize)); + qsci->setAutoIndent(s->get(Settings::Settings::autoIndent)); + qsci->setTabIndents(s->get(Settings::Settings::tabIndents)); + qsci->setIndentationsUseTabs(s->get(Settings::Settings::indentationsUseTabs)); qsci->setBraceMatching(QsciScintilla::SloppyBraceMatch); - qsci->setAutoIndent(true); - qsci->setTabIndents(true); - qsci->setIndentationsUseTabs(false); qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4); qsci->setCaretLineVisible(true); } diff --git a/src/settings.cc b/src/settings.cc index 823df0e2..6c1fe2c8 100644 --- a/src/settings.cc +++ b/src/settings.cc @@ -22,6 +22,9 @@ SettingsEntry Settings::lineWrapVisualizationBegin("edito SettingsEntry Settings::lineWrapVisualizationEnd("editor", "lineWrapVisualizationEnd", LINE_WRAP_VISUALIZATION_BORDER); SettingsEntry Settings::showWhitespaces("editor", "showWhitespaces", SHOW_WHITESPACES_NEVER); SettingsEntry Settings::showWhitespacesSize("editor", "showWhitespacesSize", 2); +SettingsEntry Settings::autoIndent("editor", "autoIndent", true); +SettingsEntry Settings::tabIndents("editor", "tabIndents", true); +SettingsEntry Settings::indentationsUseTabs("editor", "indentationsUseTabs", false); Settings *Settings::inst(bool erase) { @@ -61,6 +64,10 @@ void Settings::set(SettingsEntry &entry, T val) entry.value = val; } +template bool Settings::defaultValue(const SettingsEntry&); +template bool Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, bool); + template int Settings::defaultValue(const SettingsEntry&); template int Settings::get(const SettingsEntry&); template void Settings::set(SettingsEntry&, int); diff --git a/src/settings.h b/src/settings.h index b854354e..4b0dc169 100644 --- a/src/settings.h +++ b/src/settings.h @@ -57,6 +57,9 @@ public: static SettingsEntry lineWrapVisualizationEnd; static SettingsEntry showWhitespaces; static SettingsEntry showWhitespacesSize; + static SettingsEntry autoIndent; + static SettingsEntry tabIndents; + static SettingsEntry indentationsUseTabs; static Settings *inst(bool erase = false); From 3f6a590a2fef198984f46aff83c65370c2864dea Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 27 Dec 2014 17:58:20 -0500 Subject: [PATCH 213/263] Added stand-alone 2D tesselator --- cgal/README.md | 6 ++ cgal/data/quads.polygon | 10 +++ cgal/data/tri.polygon | 3 + cgal/polyhole-tessellator.cpp | 126 ++++++++++++++++++++++++++++++++++ cgal/polyhole-tessellator.pro | 90 ++++++++++++++++++++++++ 5 files changed, 235 insertions(+) create mode 100644 cgal/README.md create mode 100644 cgal/data/quads.polygon create mode 100644 cgal/data/tri.polygon create mode 100644 cgal/polyhole-tessellator.cpp create mode 100644 cgal/polyhole-tessellator.pro diff --git a/cgal/README.md b/cgal/README.md new file mode 100644 index 00000000..6b213744 --- /dev/null +++ b/cgal/README.md @@ -0,0 +1,6 @@ +This folder contains some CGAL test programs to easier develop and debug CGAL-based components. + +## polyhole-tessellator + +Tessellate an almost planar 3D polygon with holes into a vector of double precision 3D triangles. + diff --git a/cgal/data/quads.polygon b/cgal/data/quads.polygon new file mode 100644 index 00000000..a21c6ddb --- /dev/null +++ b/cgal/data/quads.polygon @@ -0,0 +1,10 @@ +0,0,0 +2,0,0 +2,2,0 +0,2,0 + +0.5,0.5,0 +1.5,0.5,0 +1.5,1.5,0 +0.5,1.5,0 + diff --git a/cgal/data/tri.polygon b/cgal/data/tri.polygon new file mode 100644 index 00000000..79d21286 --- /dev/null +++ b/cgal/data/tri.polygon @@ -0,0 +1,3 @@ +0,0,0 +2,0,0 +2,2,0 diff --git a/cgal/polyhole-tessellator.cpp b/cgal/polyhole-tessellator.cpp new file mode 100644 index 00000000..0fba0e36 --- /dev/null +++ b/cgal/polyhole-tessellator.cpp @@ -0,0 +1,126 @@ +#include +#include +#include +#include + +#include "cgalutils.h" + +// Nef polyhedron are using CGAL_Kernel3 (Cartesian) +// Triangulation will use Epick + +static void export_stl(const Polygons &triangles, std::ostream &output) +{ + setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output + output << "solid OpenSCAD_Model\n"; + BOOST_FOREACH(const Polygon &p, triangles) { + assert(p.size() == 3); // STL only allows triangles + std::stringstream stream; + stream << p[0][0] << " " << p[0][1] << " " << p[0][2]; + std::string vs1 = stream.str(); + stream.str(""); + stream << p[1][0] << " " << p[1][1] << " " << p[1][2]; + std::string vs2 = stream.str(); + stream.str(""); + stream << p[2][0] << " " << p[2][1] << " " << p[2][2]; + std::string vs3 = stream.str(); + if (vs1 != vs2 && vs1 != vs3 && vs2 != vs3) { + // The above condition ensures that there are 3 distinct vertices, but + // they may be collinear. If they are, the unit normal is meaningless + // so the default value of "1 0 0" can be used. If the vertices are not + // collinear then the unit normal must be calculated from the + // components. + Vector3d normal = (p[1] - p[0]).cross(p[2] - p[0]); + normal.normalize(); + output << " facet normal " << normal[0] << " " << normal[1] << " " << normal[2] << "\n"; + output << " outer loop\n"; + + BOOST_FOREACH(const Vector3d &v, p) { + output << " vertex " << v[0] << " " << v[1] << " " << v[2] << "\n"; + } + output << " endloop\n"; + output << " endfacet\n"; + } + } + output << "endsolid OpenSCAD_Model\n"; + setlocale(LC_NUMERIC, ""); // Set default locale +} + + +/*! + file format: + 1. polygon coordinates (x,y,z) are comma separated (+/- spaces) and + each coordinate is on a separate line + 2. each polygon is separated by one or more blank lines +*/ +bool import_polygon(PolyholeK &polyhole, const std::string &filename) +{ + std::ifstream ifs(filename.c_str()); + if (!ifs) return false; + + std::string line; + PolygonK polygon; + while (std::getline(ifs, line)) { + std::stringstream ss(line); + double X = 0.0, Y = 0.0, Z = 0.0; + if (!(ss >> X)) { + //ie blank lines => flag start of next polygon + if (polygon.size() > 0) polyhole.push_back(polygon); + polygon.clear(); + continue; + } + char c = ss.peek(); + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces before comma + if (c == ',') {ss.read(&c, 1); c = ss.peek();} //gobble comma + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces after comma + if (!(ss >> Y)) { + std::cerr << "Y error\n"; + return false; + } + c = ss.peek(); + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces before comma + if (c == ',') {ss.read(&c, 1); c = ss.peek();} //gobble comma + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces after comma + if (!(ss >> Z)) { + std::cerr << "Z error\n"; + return false; + } + polygon.push_back(Vertex3K(X, Y, Z)); + } + if (polygon.size() > 0) polyhole.push_back(polygon); + ifs.close(); + return true; +} +//------------------------------------------------------------------------------ + +int main(int argc, char *argv[]) +{ + PolyholeK polyhole; + if (argc == 2) { + if (!import_polygon(polyhole, argv[1])) { + std::cerr << "Error importing polygon" << std::endl; + exit(1); + } + std::cerr << "Imported " << polyhole.size() << " polygons" << std::endl; + } + else { + //construct two non-intersecting nested polygons + PolygonK polygon1; + polygon1.push_back(Vertex3K(0,0,0)); + polygon1.push_back(Vertex3K(2,0,0)); + polygon1.push_back(Vertex3K(2,2,0)); + polygon1.push_back(Vertex3K(0,2,0)); + PolygonK polygon2; + polygon2.push_back(Vertex3K(0.5,0.5,0)); + polygon2.push_back(Vertex3K(1.5,0.5,0)); + polygon2.push_back(Vertex3K(1.5,1.5,0)); + polygon2.push_back(Vertex3K(0.5,1.5,0)); + polyhole.push_back(polygon1); + polyhole.push_back(polygon2); + } + + Polygons triangles; + bool ok = CGALUtils::tessellatePolygonWithHoles(polyhole, triangles); + std::cerr << "Tessellated into " << triangles.size() << " triangles" << std::endl; + + export_stl(triangles, std::cout); +} diff --git a/cgal/polyhole-tessellator.pro b/cgal/polyhole-tessellator.pro new file mode 100644 index 00000000..906d089f --- /dev/null +++ b/cgal/polyhole-tessellator.pro @@ -0,0 +1,90 @@ +debug: DEFINES += DEBUG + +TEMPLATE = app + +INCLUDEPATH += ../src +DEPENDPATH += ../src + +# Handle custom library location. +# Used when manually installing 3rd party libraries +isEmpty(OPENSCAD_LIBDIR) OPENSCAD_LIBDIR = $$(OPENSCAD_LIBRARIES) +macx:isEmpty(OPENSCAD_LIBDIR) { + exists(/opt/local):exists(/usr/local/Cellar) { + error("It seems you might have libraries in both /opt/local and /usr/local. Please specify which one to use with qmake OPENSCAD_LIBDIR=") + } else { + exists(/opt/local) { + #Default to MacPorts on Mac OS X + message("Automatically searching for libraries in /opt/local. To override, use qmake OPENSCAD_LIBDIR=") + OPENSCAD_LIBDIR = /opt/local + } else:exists(/usr/local/Cellar) { + message("Automatically searching for libraries in /usr/local. To override, use qmake OPENSCAD_LIBDIR=") + OPENSCAD_LIBDIR = /usr/local + } + } +} +!isEmpty(OPENSCAD_LIBDIR) { + QMAKE_INCDIR = $$OPENSCAD_LIBDIR/include + QMAKE_LIBDIR = $$OPENSCAD_LIBDIR/lib +} + +TARGET = polyhole-tessellator +mac { + CONFIG -= app_bundle +} + +macx { + # Mac needs special care to link against the correct C++ library + # We attempt to auto-detect it by inspecting Boost + dirs = $${BOOSTDIR} $${QMAKE_LIBDIR} + for(dir, dirs) { + system(grep -q __112basic_string $${dir}/libboost_thread* >& /dev/null) { + message("Detected libc++-linked boost in $${dir}") + CONFIG += libc++ + } + } + + libc++ { + QMAKE_CXXFLAGS += -stdlib=libc++ + QMAKE_LFLAGS += -stdlib=libc++ + QMAKE_OBJECTIVE_CFLAGS += -stdlib=libc++ + # libc++ on requires Mac OS X 10.7+ + QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 + } +} + +# See Dec 2011 OpenSCAD mailing list, re: CGAL/GCC bugs. +*g++* { + QMAKE_CXXFLAGS *= -fno-strict-aliasing + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-local-typedefs # ignored before 4.8 +} + +*clang* { + # http://llvm.org/bugs/show_bug.cgi?id=9182 + QMAKE_CXXFLAGS_WARN_ON += -Wno-overloaded-virtual + # disable enormous amount of warnings about CGAL / boost / etc + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function + QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions + # might want to actually turn this on once in a while + QMAKE_CXXFLAGS_WARN_ON += -Wno-format-security +} + + + +# Application configuration +CONFIG += cgal +CONFIG += boost +CONFIG += eigen +CONFIG += gettext + +include(../common.pri) + +HEADERS += ../src/cgal.h \ + ../src/cgalutils.h \ + ../src/linalg.h \ + ../src/printutils.h + +SOURCES += polyhole-tessellator.cpp \ + ../src/cgalutils-tess.cc \ + ../src/printutils.cc From 06e2fc7d9b01540e61b05a8ebcb69f255dbe0e90 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Dec 2014 15:32:57 -0500 Subject: [PATCH 214/263] #1105 Added example crashing CGAL --- cgal/data/issue1105.polygon | 4 ++++ cgal/polyhole-tessellator.cpp | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 cgal/data/issue1105.polygon diff --git a/cgal/data/issue1105.polygon b/cgal/data/issue1105.polygon new file mode 100644 index 00000000..15809c1f --- /dev/null +++ b/cgal/data/issue1105.polygon @@ -0,0 +1,4 @@ +6, -25, 29.285714285714285 +6, -26.732050855686023, 29.020513307787397 +6, -26.732050855686026, 29.020513307787397 +6, -26, 29.132600433972414 diff --git a/cgal/polyhole-tessellator.cpp b/cgal/polyhole-tessellator.cpp index 0fba0e36..7a433a24 100644 --- a/cgal/polyhole-tessellator.cpp +++ b/cgal/polyhole-tessellator.cpp @@ -1,10 +1,13 @@ #include +#include #include #include #include #include "cgalutils.h" + + // Nef polyhedron are using CGAL_Kernel3 (Cartesian) // Triangulation will use Epick @@ -95,12 +98,23 @@ bool import_polygon(PolyholeK &polyhole, const std::string &filename) int main(int argc, char *argv[]) { PolyholeK polyhole; - if (argc == 2) { + K::Vector_3 *normal = NULL; + if (argc >= 2) { if (!import_polygon(polyhole, argv[1])) { std::cerr << "Error importing polygon" << std::endl; exit(1); } std::cerr << "Imported " << polyhole.size() << " polygons" << std::endl; + + if (argc == 3) { + std::vector strs; + std::vector normalvec; + std::string arg(argv[2]); + boost::split(strs, arg, boost::is_any_of(",")); + assert(strs.size() == 3); + BOOST_FOREACH(const std::string &s, strs) normalvec.push_back(boost::lexical_cast(s)); + normal = new K::Vector_3(normalvec[0], normalvec[1], normalvec[2]); + } } else { //construct two non-intersecting nested polygons @@ -119,7 +133,7 @@ int main(int argc, char *argv[]) } Polygons triangles; - bool ok = CGALUtils::tessellatePolygonWithHoles(polyhole, triangles); + bool ok = CGALUtils::tessellatePolygonWithHoles(polyhole, triangles, normal); std::cerr << "Tessellated into " << triangles.size() << " triangles" << std::endl; export_stl(triangles, std::cout); From 89419f50a1aef778760388d943042f509764b590 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Dec 2014 16:05:33 -0500 Subject: [PATCH 215/263] #1105 Added testcase --- testdata/scad/bugs/issue1105.scad | 12 ++++++++++++ tests/CMakeLists.txt | 3 ++- .../cgalpngtest/issue1105-expected.png | Bin 0 -> 9022 bytes .../monotonepngtest/issue1105-expected.png | Bin 0 -> 9034 bytes .../opencsgtest/issue1105-expected.png | Bin 0 -> 9760 bytes 5 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 testdata/scad/bugs/issue1105.scad create mode 100644 tests/regression/cgalpngtest/issue1105-expected.png create mode 100644 tests/regression/monotonepngtest/issue1105-expected.png create mode 100644 tests/regression/opencsgtest/issue1105-expected.png diff --git a/testdata/scad/bugs/issue1105.scad b/testdata/scad/bugs/issue1105.scad new file mode 100644 index 00000000..6529dc31 --- /dev/null +++ b/testdata/scad/bugs/issue1105.scad @@ -0,0 +1,12 @@ +translate([-31.5, -30, 1]) { + rotate(90) { + translate([2, -51.5, 26]) { + difference() { + cube([4, 14, 4]); + translate([-0.1,-1,2.1]) cube([2.1, 16, 2.1]); + } + } + } +} +translate([3, -25, 1]) rotate_extrude($fn=12) polygon(points = [[0, 20], [0, 30], [7, 26]]); +translate([0, -28, 20]) cube([6, 3, 10]); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 19835d0d..199faf4d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1217,7 +1217,8 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1004.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1069.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1069.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(REMOVE_ITEM EXPORT3D_TEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad diff --git a/tests/regression/cgalpngtest/issue1105-expected.png b/tests/regression/cgalpngtest/issue1105-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..9c8d7cb012bc612e2a5abea709c5b0b8b359f4db GIT binary patch literal 9022 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 y literal 0 HcmV?d00001 diff --git a/tests/regression/monotonepngtest/issue1105-expected.png b/tests/regression/monotonepngtest/issue1105-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..013d85bf141aa73b231f9cee8a59ac09ee3d4a0b GIT binary patch literal 9034 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 b=*HmMWp&h-!QK`S_#8f9vp;7qE#&_Iok~D% literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/issue1105-expected.png b/tests/regression/opencsgtest/issue1105-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..69a4cab7aea6c7d52fac77def60873176881df3c GIT binary patch literal 9760 zcmeHM`9GBJ*S}|seTwucTSY09ifonCj8>8*dnig}i&55Wb5GK4NlMvfWJ`!5J44En zLI`CUl69D|48x3>`?-9d*X#KUp6B&?e)!BUGjre9b*^*Hb>8P(*LgoQH$AgXOim1f zpmj!uCoLcd4Su2_k+rW7xfA&iv}@exq=8isYG%NsY1f6@!n2HVhxie z`$b-zJTH|VEf(%)8faqM6N00U|cWhtNXIQWio?afpL|C9Nim&3Ih8x&seG zq$SKYcS5txIT%8r*%%BQw)XI}AO@cvS$YGF5fOnx)?P)4iNL4D3BNERl9JF8cz}`H zBnd@r9{eCGsi+7|g9jqodlVtLeO1>sD&p}_uK*b8W`&2e?SopB@h}V(3X4c8w!eWP zx8m6sCO|04Swd0~PdSf5wYv@PO9DdCwc8Z&Fg_iPru_KipbLaz;G_R4^sk5hjiG;0 z_Wvvo=|5V_i?)KP{Gq-W@&YMlwPh}1TaMw-(m{JlQqYRxMb9K(s!>MTo-b6;(deOy zr>>Gsy9=4o%r%DB&I13Uc{bo?u#bdOf;BAYaR?(k7~E8+ZR|2N8=K|ZuA5-=A%t( zRXs4($3kH9enm)3J$5o*weWVMnWwLd>ld^c&%NVU%eTAec%1qBNA;GU`t zzEQnITiNCg45_AxjY%q-A8#~!eA7iG@3oMqkMe6j_9|~Nj&IYzGc)&)mM1x^UJk4P_S0&Xu(AjX9I}k%lS^@GWorA za%j2^PrT^4u(VHBcncYwxMyqyV=vvC!9<2yoID4@A{WKsP3G&2oCDE`e8$;ef&tn& z;aWcNd;yP@|DY1Tc;ZGm+JtD#+dIA)y6`gPE`Ap}Nt<_dWPO{m{7LA>Cq@QFOsbtF zzUTB{jtE>eSb3z6OAhTUr7k?{Il9#3wA!p*wGc+84R8V~Dfx-v=*8>Qzp()=g;*aIB8i>6- zD!0R|^Hi;L4XcB9n|g$2i;cJZ1msG!vs-=%skrWdOg{w8=Hb~5xUk9)CbCH2Ef3|i z9Yc8BmRp*blJ;{g)w;Y*&4~*3kTzBDG?dXzPW}0j@7ErPjFcjimGxLdr$?l_g@Xm_ zlEUrdkLc5_b=#WIiZQHVJdEN&B z_-1%Ht@b9}jCQ1lr%*Fp_d`RV!)0J=n%_`XyFgkqQouA*Uby24;F@UujHb}ZGaE!? zJ+`{yIo=ij7$O&?1cY%jD*_6f%weOzfV@d&9wl>MV@$;U{2lUbuIK2?te`E>q}iQq zZ8h9;LCZl2D4volQadr^irT8p<9`$u7QSpg851#BGO5xL$DHO`;)O%PhZE4w+lRt0 z4SwVor}FCuy}eWj+%16!>+dsE>^590%o-Y%3F1T$n61aS)ZN%UVvq^(YMNlJ;hU#s z8zH5%rPX5Jd|dv@Rkm3S84I(Py%Q@! z)S&B~DWPd#`UgZ1sVvvx-*t2dN_tu|b$syCBiyH_?fs{$u z9W^-T%HmOCFQ;=l1~)yEP+Y}jpSXDF(6acI#K%p)QQ|cQibcKGHF)20(s)@YZ-A5Q#(8*(rp{sa)+nn$0Tykt`N&qnZGZdK1cZ0rMWlg- z$ZFXm$tr_Oa$z`kHxBQGPb|paf4eS?IzF=}_OR|R1T7G%JeIEo>T7O_cIrKPYn~vG zaf!%S8IB1lQZTI;hP`TUH&Tm@x zni+G~eqP%aGG^(9%#3yyOcHEfE~s>~+xq&Kqicu}E~Dz0+OM@g>d7~FlRKHjdDnC^ z>xm$Gb*F?=VHPgcil#u=w0sUF`JkL*u2M-1Y|BO(3s3V$F66f9urP_?s;&kRlia?| zC!ia2+|sm)12K56ZYzjz?>NfqEOKx4FNMnIOq>~w{Q2YHGr`*6k^@R$ABD$r4~S~> zB6cvQjl-zLcf{b1J@Y=tiX4#o?F@xYsThA9-p;A-{5qjZPG$}9xm&J^2%P^{J%#N^ zH!CB_3UNJq{P#}&^%_3og>QpEeeyF*N%3MxYJMqB<2d?3Gs2x!X`*5IcVCqt)@%;Yn?SJ4B2x& z(@YY&ARbu0n4R;4I_|5%)JMgda=JpO!9G*BYR;vEtzJz9yP{ymdrIYxEhiK&oeLwf zH%UV)XG6=mZQi^AbO(;U97sewWj7ajK~;Y?mF{0P{-pJS_65&Ae!2bd1XoMfB2#?> zbXaU{8QHx|K2Nhdnv{=L{K)6`1k1Lky#Btkoy}d>-AaP&O1nKv`P$qOVn^6dY?A_1 z-%Ybs(-r6_1Q_S~jCuIuP~dJ{{z{-yLDl3S2W~nq(mm3Dnvf zKlV&Z6I`D1O&<$9lzjEol5=Y}`MU08HBxu>MPscTN~3a-o$Ih$ zpksMNU69k95#d#jrzv!QniE8!d{E<@(uQKb_Sbod5N^)iNj^`}_==(~^rDm>em?UW z{^0xMHM5fH>I{JfQd6_;D-Og&14Ce$rn=B;v|`~RTg_fwpkw#gMKPAIv9MYssRnm4 zK;H-to%>V4{`)i^cT{UOiYT|QgiCX1&Uet#biNGb{a{yq^h5UP3v}#Ezp|#zz??o< zpw257WU{i;K>V@YLf3_Bf9F#jTHm7DQ?9IJ;^kZeu)x$B|3XJR^h9UNFP;l+F}pec zH>dIok>`NpH?|!+CUxZ!6pGx(g$=mGJkkI1Df?#}%Kg=d3!dgwrdG9@u~w;Wjno0X zs1M47i(6r&0LKLNXVT7 zvKl%Nhe2+Q+Xr=&YdQ-1d3%0_YiLX(;at#c>8u(7$suf69?`y@${?F+gVH(r6DzY8 zTjbNG)LTM$y^H>`v16;P>@a?6yc6bwhzNXQ>^tylyUhT#s4N+!BrsIQ&92iD#_PG1 zU=7C~fpfx%horkhwn8Y>tmJJAx|zDe2ym*d1KVs|50obd$0qmy%I5<&Fro$CwlYPM zDLeaDR9sM#SN9~cXz$Eu&LXpnt1?4d89-iog{N`bw)r-TQ)e?nkyU0<8xhANG~cLx zfj0&6KP)wsBJ_`Z?U-aHufY3*tZb}3(S3mGaJ?04==$UR;)Szuz_)({h8yW6itbt*|U(AH3q)u1)cCYv#;Ofx(T0 z^k=d@tMi{Ki3f+j$;O)Q5r{5*bmozi+fk^YitRKRK%`1Mn&A&%3$E8@FpzW=`3TZiQ`sG;?lSi4?cDNly7u@@Zu zFjs5m!`$vlk~SmCvylviE5ZJ;>nf4BQpC1LhcCK<9Gh(}A6+%rprWENpM7Rotxjc8 zzs!+Rt_D9F!1c)^R)t{r{LF`<4JFm<4PWjT3@Ax|>tO1O@^MVVDl9Fj{N#l^I==pF z6Li45>AIVboR?s2T_2K6SnVAAUB#8Yg{Yj5pFMy_D#I4AhFVWiVTZT;{l{%W3m##R zHwG^-$eSHZp^WB#<`3Yh!n%k)C8@dGOfVGNZu`}Mf>*PJ>KWvfDB{}}42805wsLRp z(&1w51hm@EomX+np31$M2D!sFEWh?wws+Ir^?ArEm|HrRzG~azMqF zrE5}V8BQ&I$akW^xs=+ovJ|e_zPsc1MT-5!->5hQslSnoaHXxmrL1#e6W(@Gwg)u|4id!`gZymK9)H1h zuhhsjn;IvmePY_df*KOlj~F8d<*}%jGb*D>VA-Zw{vK7`*WO3 zqCJ&C?HKE8EL36&PV%{`>{gp$v7ymBsa5OWyjcuvdBd6^CWdB~!khq~VLd#Z`Fu;f z@(>vDXbV!;K2^;k*6k8k#8=;7Hom9aS~aL(_4bDX%<+=X4ho*~*s{8mSI z?70W5LZWE)HL4c1n`$3^=<4N}?X5rYOOQi{25^N6!MX4YYX4C+d+oVJn ze+jq37!sp6L=x-XvuOLq*q}wCAA4vSA?Ux__C{4SKoSzI>cB47XNSM*J4QuZkio3dG@pTR^lPB4`6NrXxUg4Xvwxqyf>1W z&f*3>=^GT3`^Bov@!;`V1I=^5`%7h>2il`vuE}Oe9Si-E5sl1VEA^h_pIF!U9F(&1 zNO@_2feCtKU26sL&sQHojmpWupH&Orkd=s3Ut(X-#S7s2d*Nu-XMA8*uZAS#GF4hQ zB4IWhg_zghoI#@%U*G9;p&X%q(&%+!o9#Vs3z1Byv>g>hvtefi@cLb}uL~uq?ukb4 zHE3tlZP~)pjm(4hyJ?n(dY{3NNdDLd>_oPvCeZJ#303_*W9`K&7_v*F7#wK-KJ6$o z{gIn(?No+t>YU>qeR_<^TM7&h9)BgxIkQD_O@v*3Vj38EOGao0gCEPH5gq_&6DwU% z?MeSFshpzr8J{?ZR4u1JAFrO9C5J3!dbxtufc836q1V3Tu%o0iJ@UVs*qHD+EjC|% zt3UxVN;XPo=m?d}@awyY1p(n3dJABpq_VMBrObn4*3tq$(shrfGH8A)eGXM>u%nLC zjD@pn56YpM*TeDUnfj#O0ipMI-|0uBiCk0S#XSN)*&@hITS$8S$H)_Q9?KPyEl zkj+%#bj8nS_u>)%vETB`3D}^~R*8CG74a9R(#~H_UR(@M!hi8bvBjoTrho@h3ccYU;Md0rf z1>~TcSgUwckIrWOdM~nI(4`7jpzEUo??)s-+}SrRa2#@X;w=IB$p6DG74_Z?^fKnX z9}n2AVKddR;D^X>sZsRV31IplqgU7ho8jbJAe6|lv!kmANGI8y2f97l)A*oyZ<(Cx ztP)9wflTm~N}gs*mZ^Yya=$Q$oLcOIeK11-bk@Se%LJ`_!z{7qs7h9?)s)^+#Gd%w z;a7htKx<)CNbd#Li((nr-d~wud`UXCD-KqJFIpY>g6HVWc{n#`*3uP-KP{O&54~~P zG2Xq~ch0XVew%;klp?Tpt5?M20SzSq3%WuaZ%&wB#Jv?Dg*}rLoX0iWv=EB^&*{AP z%iL!f88S*ZAAvkAr1lcI1&a#H+_+jSIM@p0-%H4lSsn~wn6NU*jwy^$Y*{}$Mwl7r zoGFeDLuC4uFxSOJ;9q{vt7hNZZZTz9?M(g#=j0QEUW-d(lxTeE4mwkR;giqBXwhk- z|MaRE?nk@l%_)`WpykDtbm6D%NE790K9##=dA00dO{dewEg1avD1L*Zu#*Ukx>sK< zT88d*I5nO(UT6J@u7Im>e5utx*~99=WK(C(qcI=EmqVam%_*^@=sGHv=xP z2{dm%JUg--ka}N1i}qSq-Cn>4#$LojS5*R!1Ntz2yCU@UO~eJj2`W~?P?Kru%-sT> zUy0@64Jfn@$Rl#O*IR+0H3kwic-M$R5bKnNx39E-Oh6Ulq1W4iNb_{ir+x1+1}IGu zAQ>fLHxVGcOH~o_$V)s7$jLQ&5~C=02k7^IDpohRm2dL$hgGT}#Q<=e&Ohp3gpOMh zu<|W@#lq$)_f9xLdB-^ivn8K{9bMPwR81*MgCFo0mYMly@bi+LwWpps zWszJumof(S#djAWpw6CHlvz3pW(_4jX=E!=7Ma;EY@`5XeEje_o0o96lbyl2?7b+I zxy{jU%4hNPm^kg$XwWc^e%v?FQOsW>pF6={Kdk~)Ydl^3qvn`3;F48~HL`S!@O1L$ z(PoSu&|al$A7!!UBCd#L^`GeW)bK#FnxLd)-Kw!g5 z;8f*1GyF+e7d)ND^Zro#2{81-g1_B@)o2?!I0xV6c1o22{CN8;|4FOWOF-KrCoZ4C zlx&uS9Be7G3yokor=T2@g8vT0Z1vl}wrb^i7i@Uc@UPf^o$zlY h{0oQwk2zr$*?ai(>xl(D4+wmWPMMy3cij2Te*ry9nP30_ literal 0 HcmV?d00001 From 03f63c1c40716f3d99ba63e594244d22d0569e51 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 28 Dec 2014 16:05:54 -0500 Subject: [PATCH 216/263] Minor compile fix --- src/cgal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cgal.h b/src/cgal.h index 75054f91..888bf2bc 100644 --- a/src/cgal.h +++ b/src/cgal.h @@ -27,7 +27,7 @@ using boost::uintmax_t; #include #include #include -#include +#include "CGAL_Nef3_workaround.h" #include #include #include From 6f9c4f7f09d6d4041a851b08a012a2467aa79b80 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 29 Dec 2014 00:29:09 +0100 Subject: [PATCH 217/263] Integrate with QSettings. --- src/Preferences.cc | 57 +++++++++++++++++---- src/Preferences.h | 1 + src/mainwin.cc | 1 + src/scintillaeditor.cpp | 3 +- src/settings.cc | 109 +++++++++++++++++++++++++++++++++++++++- src/settings.h | 47 +++++++++++++++-- 6 files changed, 198 insertions(+), 20 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index 7265d1a3..9969c91f 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -46,6 +46,29 @@ Preferences *Preferences::instance = NULL; const char * Preferences::featurePropertyName = "FeatureProperty"; Q_DECLARE_METATYPE(Feature *); +class SettingsReader : public Settings::Visitor +{ + QSettings settings; + virtual void handle(Settings::SettingsEntryBase * entry) const { + std::string key = entry->category() + "/" + entry->name(); + std::string value = settings.value(QString::fromStdString(key)).toString().toStdString(); + entry->from_string(value); + } +}; + +class SettingsWriter : public Settings::Visitor +{ + virtual void handle(Settings::SettingsEntryBase * entry) const { + QSettings settings; + QString key = QString::fromStdString(entry->category() + "/" + entry->name()); + if (entry->is_default()) { + settings.remove(key); + } else { + settings.setValue(key, QString::fromStdString(entry->to_string())); + } + } +}; + Preferences::Preferences(QWidget *parent) : QMainWindow(parent) { setupUi(this); @@ -141,6 +164,11 @@ void Preferences::init() { #endif this->polysetCacheSizeEdit->setValidator(validator); this->opencsgLimitEdit->setValidator(validator); + + Settings::Settings *s = Settings::Settings::inst(); + SettingsReader settingsReader; + s->visit(&settingsReader); + emit editorConfigChanged(); } Preferences::~Preferences() @@ -410,72 +438,79 @@ void Preferences::on_launcherBox_toggled(bool state) void Preferences::on_spinBoxIndentationWidth_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::indentationWidth, val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_spinBoxTabWidth_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::tabWidth, val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_comboBoxLineWrap_activated(int val) { Settings::Settings::inst()->set(Settings::Settings::lineWrap, (Settings::LineWrap)val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_comboBoxLineWrapIndentation_activated(int val) { Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentationStyle, (Settings::LineWrapIndentationStyle)val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_spinBoxLineWrapIndentationIndent_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentation, val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_comboBoxLineWrapVisualizationStart_activated(int val) { Settings::Settings::inst()->set(Settings::Settings::lineWrapVisualizationBegin, (Settings::LineWrapVisualization)val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_comboBoxLineWrapVisualizationEnd_activated(int val) { Settings::Settings::inst()->set(Settings::Settings::lineWrapVisualizationEnd, (Settings::LineWrapVisualization)val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_comboBoxShowWhitespaces_activated(int val) { Settings::Settings::inst()->set(Settings::Settings::showWhitespaces, (Settings::ShowWhitespaces)val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_spinBoxShowWhitespacesSize_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::showWhitespacesSize, val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_checkBoxAutoIndent_toggled(bool val) { Settings::Settings::inst()->set(Settings::Settings::autoIndent, val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_checkBoxTabIndents_toggled(bool val) { Settings::Settings::inst()->set(Settings::Settings::tabIndents, val); - emit editorConfigChanged(); + fireEditorConfigChanged(); } void Preferences::on_checkBoxIndentationsUseTabs_toggled(bool val) { Settings::Settings::inst()->set(Settings::Settings::indentationsUseTabs, val); + fireEditorConfigChanged(); +} + +void Preferences::fireEditorConfigChanged() const +{ + SettingsWriter settingsWriter; + Settings::Settings::inst()->visit(&settingsWriter); emit editorConfigChanged(); } diff --git a/src/Preferences.h b/src/Preferences.h index f4122dff..e1db37d0 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -75,6 +75,7 @@ private: void updateGUI(); void removeDefaultSettings(); void setupFeaturesPage(); + void fireEditorConfigChanged() const; void addPrefPage(QActionGroup *group, QAction *action, QWidget *widget); QSettings::SettingsMap defaultmap; diff --git a/src/mainwin.cc b/src/mainwin.cc index 231eeb08..e4a01584 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -204,6 +204,7 @@ MainWindow::MainWindow(const QString &filename) #ifdef USE_SCINTILLA_EDITOR if (useScintilla) { connect(Preferences::inst(), SIGNAL(editorConfigChanged()), editor, SLOT(applySettings())); + Preferences::inst()->editorConfigChanged(); } #endif diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 7836d6b1..c284349b 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -146,7 +146,7 @@ ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent) qsci->indicatorDefine(QsciScintilla::RoundBoxIndicator, indicatorNumber); qsci->markerDefine(QsciScintilla::Circle, markerNumber); qsci->setUtf8(true); - applySettings(); + qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4); lexer = new ScadLexer(this); qsci->setLexer(lexer); @@ -179,7 +179,6 @@ void ScintillaEditor::applySettings() qsci->setIndentationsUseTabs(s->get(Settings::Settings::indentationsUseTabs)); qsci->setBraceMatching(QsciScintilla::SloppyBraceMatch); - qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4); qsci->setCaretLineVisible(true); } diff --git a/src/settings.cc b/src/settings.cc index 6c1fe2c8..f2137ce6 100644 --- a/src/settings.cc +++ b/src/settings.cc @@ -1,10 +1,32 @@ #include "settings.h" +#include "value.h" namespace Settings { +std::list SettingsEntryBase::entries; + +SettingsEntryBase::SettingsEntryBase(const std::string category, const std::string name) : _category(category), _name(name) +{ + entries.push_back(this); +} + +SettingsEntryBase::~SettingsEntryBase() +{ +} + +const std::string & SettingsEntryBase::category() const +{ + return _category; +} + +const std::string & SettingsEntryBase::name() const +{ + return _name; +} + template SettingsEntry::SettingsEntry(const std::string category, const std::string name, T defaultValue) - : category(category), name(name), value(defaultValue), defaultValue(defaultValue) + : SettingsEntryBase(category, name), value(defaultValue), defaultValue(defaultValue) { } @@ -13,6 +35,74 @@ SettingsEntry::~SettingsEntry() { } +template +bool SettingsEntry::is_default() const +{ + return defaultValue == value; +} + +template +std::string SettingsEntry::to_string() const +{ + return boost::lexical_cast(value); +} + +template <> +std::string SettingsEntry::to_string() const +{ + return boost::lexical_cast(value); +} + +template +void SettingsEntry::from_string(std::string val) +{ + try { + value = boost::lexical_cast(val); + } catch (const boost::bad_lexical_cast &e) { + value = defaultValue; + } +} + +template <> +void SettingsEntry::from_string(std::string val) +{ + try { + value = (LineWrap)boost::lexical_cast(val); + } catch (const boost::bad_lexical_cast &e) { + value = defaultValue; + } +} + +template <> +void SettingsEntry::from_string(std::string val) +{ + try { + value = (LineWrapIndentationStyle)boost::lexical_cast(val); + } catch (const boost::bad_lexical_cast &e) { + value = defaultValue; + } +} + +template <> +void SettingsEntry::from_string(std::string val) +{ + try { + value = (LineWrapVisualization)boost::lexical_cast(val); + } catch (const boost::bad_lexical_cast &e) { + value = defaultValue; + } +} + +template <> +void SettingsEntry::from_string(std::string val) +{ + try { + value = (ShowWhitespaces)boost::lexical_cast(val); + } catch (const boost::bad_lexical_cast &e) { + value = defaultValue; + } +} + SettingsEntry Settings::indentationWidth("editor", "indentationWidth", 4); SettingsEntry Settings::tabWidth("editor", "tabWidth", 8); SettingsEntry Settings::lineWrap("editor", "lineWrap", LINE_WRAP_WORD); @@ -46,6 +136,13 @@ Settings::~Settings() { } +void Settings::visit(class Visitor *visitor) +{ + for (std::list::iterator it = SettingsEntryBase::entries.begin();it != SettingsEntryBase::entries.end();it++) { + visitor->handle(*it); + } +} + template T Settings::defaultValue(const SettingsEntry &entry) { @@ -88,4 +185,12 @@ template ShowWhitespaces Settings::defaultValue(const SettingsEntry&); template void Settings::set(SettingsEntry&, ShowWhitespaces); -} \ No newline at end of file +Visitor::Visitor() +{ +} + +Visitor::~Visitor() +{ +} + +} diff --git a/src/settings.h b/src/settings.h index 4b0dc169..445a9a8a 100644 --- a/src/settings.h +++ b/src/settings.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace Settings { @@ -30,17 +31,42 @@ typedef enum { SHOW_WHITESPACES_AFTER_INDENTATION, } ShowWhitespaces; -template -class SettingsEntry +class SettingsEntryBase +{ +private: + std::string _category; + std::string _name; + +public: + const std::string & category() const; + const std::string & name() const; + + virtual bool is_default() const = 0; + virtual std::string to_string() const = 0; + virtual void from_string(std::string) = 0; + +protected: + SettingsEntryBase(const std::string category, const std::string name); + ~SettingsEntryBase(); + + static std::list entries; + + friend class Settings; +}; + +template +class SettingsEntry : public SettingsEntryBase { private: - std::string category; - std::string name; T value; T defaultValue; SettingsEntry(const std::string category, const std::string name, T defaultValue); virtual ~SettingsEntry(); + + virtual bool is_default() const; + virtual std::string to_string() const; + virtual void from_string(std::string); friend class Settings; }; @@ -62,7 +88,9 @@ public: static SettingsEntry indentationsUseTabs; static Settings *inst(bool erase = false); - + + void visit(class Visitor *visitor); + template T defaultValue(const SettingsEntry &entry); template T get(const SettingsEntry &entry); template void set(SettingsEntry &entry, T val); @@ -72,4 +100,13 @@ private: virtual ~Settings(); }; +class Visitor +{ +public: + Visitor(); + virtual ~Visitor(); + + virtual void handle(SettingsEntryBase * entry) const = 0; +}; + } \ No newline at end of file From 2c89f562a3eeaa9a166ce9ec3b2910d2a46cb734 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 29 Dec 2014 03:49:45 +0100 Subject: [PATCH 218/263] Update GUI to make options a bit clearer for the user. --- src/Preferences.cc | 31 +- src/Preferences.h | 9 +- src/Preferences.ui | 1295 ++++++++++++++++++++++++--------------- src/scintillaeditor.cpp | 27 +- src/settings.cc | 33 +- src/settings.h | 18 +- 6 files changed, 884 insertions(+), 529 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index 9969c91f..c6287a93 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -477,15 +477,15 @@ void Preferences::on_comboBoxLineWrapVisualizationEnd_activated(int val) fireEditorConfigChanged(); } -void Preferences::on_comboBoxShowWhitespaces_activated(int val) +void Preferences::on_comboBoxShowWhitespace_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::showWhitespaces, (Settings::ShowWhitespaces)val); + Settings::Settings::inst()->set(Settings::Settings::showWhitespace, (Settings::ShowWhitespace)val); fireEditorConfigChanged(); } -void Preferences::on_spinBoxShowWhitespacesSize_valueChanged(int val) +void Preferences::on_spinBoxShowWhitespaceSize_valueChanged(int val) { - Settings::Settings::inst()->set(Settings::Settings::showWhitespacesSize, val); + Settings::Settings::inst()->set(Settings::Settings::showWhitespaceSize, val); fireEditorConfigChanged(); } @@ -495,15 +495,21 @@ void Preferences::on_checkBoxAutoIndent_toggled(bool val) fireEditorConfigChanged(); } -void Preferences::on_checkBoxTabIndents_toggled(bool val) +void Preferences::on_comboBoxIndentUsing_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::tabIndents, val); + Settings::Settings::inst()->set(Settings::Settings::indentStyle, (Settings::IndentStyle)val); fireEditorConfigChanged(); } -void Preferences::on_checkBoxIndentationsUseTabs_toggled(bool val) +void Preferences::on_checkBoxHighlightCurrentLine_toggled(bool val) { - Settings::Settings::inst()->set(Settings::Settings::indentationsUseTabs, val); + Settings::Settings::inst()->set(Settings::Settings::highlightCurrentLine, val); + fireEditorConfigChanged(); +} + +void Preferences::on_checkBoxEnableBraceMatching_toggled(bool val) +{ + Settings::Settings::inst()->set(Settings::Settings::enableBraceMatching, val); fireEditorConfigChanged(); } @@ -616,11 +622,12 @@ void Preferences::updateGUI() this->spinBoxLineWrapIndentationIndent->setValue(s->get(Settings::Settings::lineWrapIndentation)); this->comboBoxLineWrapVisualizationStart->setCurrentIndex(s->get(Settings::Settings::lineWrapVisualizationBegin)); this->comboBoxLineWrapVisualizationEnd->setCurrentIndex(s->get(Settings::Settings::lineWrapVisualizationEnd)); - this->comboBoxShowWhitespaces->setCurrentIndex(s->get(Settings::Settings::showWhitespaces)); - this->spinBoxShowWhitespacesSize->setValue(s->get(Settings::Settings::showWhitespacesSize)); + this->comboBoxShowWhitespace->setCurrentIndex(s->get(Settings::Settings::showWhitespace)); + this->spinBoxShowWhitespaceSize->setValue(s->get(Settings::Settings::showWhitespaceSize)); this->checkBoxAutoIndent->setChecked(s->get(Settings::Settings::autoIndent)); - this->checkBoxTabIndents->setChecked(s->get(Settings::Settings::tabIndents)); - this->checkBoxIndentationsUseTabs->setChecked(s->get(Settings::Settings::indentationsUseTabs)); + this->comboBoxIndentUsing->setCurrentIndex(s->get(Settings::Settings::indentStyle)); + this->checkBoxHighlightCurrentLine->setChecked(s->get(Settings::Settings::highlightCurrentLine)); + this->checkBoxEnableBraceMatching->setChecked(s->get(Settings::Settings::enableBraceMatching)); } void Preferences::apply() const diff --git a/src/Preferences.h b/src/Preferences.h index e1db37d0..4432140f 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -51,11 +51,12 @@ public slots: void on_spinBoxLineWrapIndentationIndent_valueChanged(int); void on_comboBoxLineWrapVisualizationStart_activated(int); void on_comboBoxLineWrapVisualizationEnd_activated(int); - void on_comboBoxShowWhitespaces_activated(int); - void on_spinBoxShowWhitespacesSize_valueChanged(int); + void on_comboBoxShowWhitespace_activated(int); + void on_spinBoxShowWhitespaceSize_valueChanged(int); void on_checkBoxAutoIndent_toggled(bool); - void on_checkBoxTabIndents_toggled(bool); - void on_checkBoxIndentationsUseTabs_toggled(bool); + void on_comboBoxIndentUsing_activated(int); + void on_checkBoxHighlightCurrentLine_toggled(bool); + void on_checkBoxEnableBraceMatching_toggled(bool); signals: void requestRedraw() const; diff --git a/src/Preferences.ui b/src/Preferences.ui index 9c1e0275..f6d26e17 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -6,8 +6,8 @@ 0 0 - 613 - 349 + 607 + 432 @@ -23,7 +23,7 @@ true - + @@ -86,552 +86,589 @@ 0 - - - QFrame::Plain - - - Qt::ScrollBarAlwaysOn - + true - + 0 0 - 685 - 609 + 659 + 769 - - - 9 - - - 9 - - - - - - - - 75 - true - - - - Editor Type - - - - - + + + + + - - Simple Editor - + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 30 + 20 + + + - - QScintilla Editor - + + + Editor Type + + - + - - - - - 10 - 50 - false - - - - (requires restart) - - + + + + + + + Simple Editor + + + + + QScintilla Editor + + + + + + + + + 10 + 50 + false + + + + (requires restart) + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 30 + 20 + + + + + - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 30 - 20 - - - + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 30 + 20 + + + + + + + + Font + + + false + + + + - - - - - - - - - 75 - true - - - - Font - - - false - - + + + + + + + Liberation Sans + 12 + + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - - Nimbus Sans L - 12 - - - + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 30 + 20 + + + + + + + + Color syntax highlighting + + + + - - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - - - - - - 75 - true - - - - Color syntax highlighting - - - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 30 - 20 - - - - - - - - - - 5 - - - - - - 75 - true - - - - Use Ctrl/Cmd-Mouse-wheel to zoom text - - - - - - - - - - - + Qt::Horizontal - 40 + 198 20 + + + + Ctrl/Cmd-Mouse-wheel zooms text + + + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 30 + 20 + + + + + + - - + + - Editor settings + Indentation - - - 20 - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 99 + + + 4 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - - None - - - - - Wrap at character boundaries - - - - - Wrap at word boundaries - - - - - - + + Qt::Horizontal - 40 + 223 20 - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 2 - - - - - - - - Whitespaces - - - - - - - - 0 - 0 - - - - - None - - - - - Text - - - - - Border - - - - - Margin - - - - - - - - Start - - - - - - - Line wrap visualization - - - - - - - Line wrap indentation - - - - - - - Tab width - - - - - - - Line wrap - - - - - - - End - - - - - - - - 0 - 0 - - - - - None - - - - - Text - - - - - Border - - - - - Margin - - - - - - - - Indent - - - - - - - - Fixed - - - - - Same - - - - - Indented - - - - - - - - Style - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Indentation width - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 99 - - - - - - - - Never - - - - - Always - - - - - Only after indentation - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 1 - - - 9 - - - - - - - Show - - - - - - - Size - - - - + - - - - - - - Auto Indent - - + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Indent using + + + + + + + + + + + + Spaces + + + + + Tabs + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Indentation width + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Tab width + + + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 4 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Tab key function + + + + + + + + + + + + Indent + + + + + Insert Tab + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Show whitespace + + + + + + + + + + + + Never + + + + + Always + + + + + Only after indentation + + + + + + + + Size + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + 9 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Display + + + + - Tab Indents + Enable brace matching - - + + - Indentations Use Tabs - - - - - - - - - - - - - - + Highlight current line - - + + Qt::Vertical @@ -643,6 +680,284 @@ + + + + Line wrap + + + + + + + + + None + + + + + Wrap at character boundaries + + + + + Wrap at word boundaries + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Line wrap indentation + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Line wrap visualization + + + + + + + + + + + Style + + + + + + + + Fixed + + + + + Same + + + + + Indented + + + + + + + + Indent + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Start + + + + + + + + 0 + 0 + + + + + None + + + + + Text + + + + + Border + + + + + Margin + + + + + + + + End + + + + + + + + 0 + 0 + + + + + None + + + + + Text + + + + + Border + + + + + Margin + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Line wrap + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -650,7 +965,7 @@ - + @@ -886,7 +1201,7 @@ 0 0 - 596 + 640 499 diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index c284349b..46b54583 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -13,7 +13,7 @@ public: QsciScintilla::WrapMode fromWrapMode(Settings::LineWrap val); QsciScintilla::WrapVisualFlag fromLineWrapVisualization(Settings::LineWrapVisualization val); QsciScintilla::WrapIndentMode fromLineWrapIndentationStyle(Settings::LineWrapIndentationStyle val); - QsciScintilla::WhitespaceVisibility fromShowWhitespaces(Settings::ShowWhitespaces val); + QsciScintilla::WhitespaceVisibility fromShowWhitespaces(Settings::ShowWhitespace val); }; QsciScintilla::WrapMode SettingsConverter::fromWrapMode(Settings::LineWrap val) @@ -60,7 +60,7 @@ QsciScintilla::WrapIndentMode SettingsConverter::fromLineWrapIndentationStyle(Se } } -QsciScintilla::WhitespaceVisibility SettingsConverter::fromShowWhitespaces(Settings::ShowWhitespaces val) +QsciScintilla::WhitespaceVisibility SettingsConverter::fromShowWhitespaces(Settings::ShowWhitespace val) { switch(val) { case Settings::SHOW_WHITESPACES_NEVER: @@ -172,14 +172,25 @@ void ScintillaEditor::applySettings() qsci->setWrapVisualFlags(conv.fromLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationEnd)), conv.fromLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationBegin)), s->get(Settings::Settings::lineWrapIndentation)); - qsci->setWhitespaceVisibility(conv.fromShowWhitespaces(s->get(Settings::Settings::showWhitespaces))); - qsci->setWhitespaceSize(s->get(Settings::Settings::showWhitespacesSize)); + qsci->setWhitespaceVisibility(conv.fromShowWhitespaces(s->get(Settings::Settings::showWhitespace))); + qsci->setWhitespaceSize(s->get(Settings::Settings::showWhitespaceSize)); qsci->setAutoIndent(s->get(Settings::Settings::autoIndent)); - qsci->setTabIndents(s->get(Settings::Settings::tabIndents)); - qsci->setIndentationsUseTabs(s->get(Settings::Settings::indentationsUseTabs)); - qsci->setBraceMatching(QsciScintilla::SloppyBraceMatch); - qsci->setCaretLineVisible(true); + switch (s->get(Settings::Settings::indentStyle)) { + case Settings::INDENT_SPACES: + qsci->setTabIndents(true); + qsci->setIndentationsUseTabs(false); + break; + case Settings::INDENT_TABS: + qsci->setTabIndents(false); + qsci->setIndentationsUseTabs(true); + break; + default: + assert(false && "unknown indent style"); + } + + qsci->setBraceMatching(s->get(Settings::Settings::enableBraceMatching) ? QsciScintilla::SloppyBraceMatch : QsciScintilla::NoBraceMatch); + qsci->setCaretLineVisible(s->get(Settings::Settings::highlightCurrentLine)); } void ScintillaEditor::setPlainText(const QString &text) diff --git a/src/settings.cc b/src/settings.cc index f2137ce6..2888d96c 100644 --- a/src/settings.cc +++ b/src/settings.cc @@ -94,10 +94,20 @@ void SettingsEntry::from_string(std::string val) } template <> -void SettingsEntry::from_string(std::string val) +void SettingsEntry::from_string(std::string val) { try { - value = (ShowWhitespaces)boost::lexical_cast(val); + value = (ShowWhitespace)boost::lexical_cast(val); + } catch (const boost::bad_lexical_cast &e) { + value = defaultValue; + } +} + +template <> +void SettingsEntry::from_string(std::string val) +{ + try { + value = (IndentStyle)boost::lexical_cast(val); } catch (const boost::bad_lexical_cast &e) { value = defaultValue; } @@ -110,11 +120,12 @@ SettingsEntry Settings::lineWrapIndentationStyle("edit SettingsEntry Settings::lineWrapIndentation("editor", "lineWrapIndentation", 4); SettingsEntry Settings::lineWrapVisualizationBegin("editor", "lineWrapVisualizationBegin", LINE_WRAP_VISUALIZATION_NONE); SettingsEntry Settings::lineWrapVisualizationEnd("editor", "lineWrapVisualizationEnd", LINE_WRAP_VISUALIZATION_BORDER); -SettingsEntry Settings::showWhitespaces("editor", "showWhitespaces", SHOW_WHITESPACES_NEVER); -SettingsEntry Settings::showWhitespacesSize("editor", "showWhitespacesSize", 2); +SettingsEntry Settings::showWhitespace("editor", "showWhitespaces", SHOW_WHITESPACES_NEVER); +SettingsEntry Settings::showWhitespaceSize("editor", "showWhitespacesSize", 2); SettingsEntry Settings::autoIndent("editor", "autoIndent", true); -SettingsEntry Settings::tabIndents("editor", "tabIndents", true); -SettingsEntry Settings::indentationsUseTabs("editor", "indentationsUseTabs", false); +SettingsEntry Settings::indentStyle("editor", "indentStyle", INDENT_SPACES); +SettingsEntry Settings::highlightCurrentLine("editor", "highlightCurrentLine", true); +SettingsEntry Settings::enableBraceMatching("editor", "enableBraceMatching", true); Settings *Settings::inst(bool erase) { @@ -181,9 +192,13 @@ template LineWrapIndentationStyle Settings::defaultValue(const SettingsEntry&); template void Settings::set(SettingsEntry&, LineWrapIndentationStyle); -template ShowWhitespaces Settings::defaultValue(const SettingsEntry&); -template ShowWhitespaces Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, ShowWhitespaces); +template ShowWhitespace Settings::defaultValue(const SettingsEntry&); +template ShowWhitespace Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, ShowWhitespace); + +template IndentStyle Settings::defaultValue(const SettingsEntry&); +template IndentStyle Settings::get(const SettingsEntry&); +template void Settings::set(SettingsEntry&, IndentStyle); Visitor::Visitor() { diff --git a/src/settings.h b/src/settings.h index 445a9a8a..f52273ad 100644 --- a/src/settings.h +++ b/src/settings.h @@ -5,7 +5,12 @@ #include namespace Settings { - + +typedef enum { + INDENT_SPACES, + INDENT_TABS, +} IndentStyle; + typedef enum { LINE_WRAP_NONE, LINE_WRAP_CHARACTER, @@ -29,7 +34,7 @@ typedef enum { SHOW_WHITESPACES_NEVER, SHOW_WHITESPACES_ALWAYS, SHOW_WHITESPACES_AFTER_INDENTATION, -} ShowWhitespaces; +} ShowWhitespace; class SettingsEntryBase { @@ -81,11 +86,12 @@ public: static SettingsEntry lineWrapIndentation; static SettingsEntry lineWrapVisualizationBegin; static SettingsEntry lineWrapVisualizationEnd; - static SettingsEntry showWhitespaces; - static SettingsEntry showWhitespacesSize; + static SettingsEntry showWhitespace; + static SettingsEntry showWhitespaceSize; static SettingsEntry autoIndent; - static SettingsEntry tabIndents; - static SettingsEntry indentationsUseTabs; + static SettingsEntry indentStyle; + static SettingsEntry highlightCurrentLine; + static SettingsEntry enableBraceMatching; static Settings *inst(bool erase = false); From 9bcb38df484e238f55bddff84b8b53ad1e9337e4 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 30 Dec 2014 02:37:16 +0100 Subject: [PATCH 219/263] Change settings handling to use Value objects. --- src/Preferences.cc | 165 ++++++++++++++++++++++++--------- src/Preferences.h | 15 ++- src/Preferences.ui | 8 +- src/scintillaeditor.cpp | 106 +++++++++------------ src/settings.cc | 198 +++++++++++++--------------------------- src/settings.h | 101 ++++++-------------- src/value.h | 4 + 7 files changed, 279 insertions(+), 318 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index c6287a93..34ae2afd 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -39,7 +39,6 @@ #endif #include "colormap.h" #include "rendersettings.h" -#include "settings.h" Preferences *Preferences::instance = NULL; @@ -49,22 +48,48 @@ Q_DECLARE_METATYPE(Feature *); class SettingsReader : public Settings::Visitor { QSettings settings; - virtual void handle(Settings::SettingsEntryBase * entry) const { - std::string key = entry->category() + "/" + entry->name(); + const Value getValue(const Settings::SettingsEntry& entry, const std::string& value) const { + if (value.empty()) { + return entry.defaultValue(); + } + + try { + switch (entry.defaultValue().type()) { + case Value::STRING: + return Value(value); + case Value::NUMBER: + return Value(boost::lexical_cast(value)); + case Value::BOOL: + return Value(boost::lexical_cast(value)); + default: + assert(false && "invalid value type for settings"); + } + } catch (const boost::bad_lexical_cast& e) { + return entry.defaultValue(); + } + } + + virtual void handle(Settings::SettingsEntry& entry) const { + Settings::Settings *s = Settings::Settings::inst(); + + std::string key = entry.category() + "/" + entry.name(); std::string value = settings.value(QString::fromStdString(key)).toString().toStdString(); - entry->from_string(value); + s->set(entry, getValue(entry, value)); } }; class SettingsWriter : public Settings::Visitor { - virtual void handle(Settings::SettingsEntryBase * entry) const { + virtual void handle(Settings::SettingsEntry& entry) const { + Settings::Settings *s = Settings::Settings::inst(); + QSettings settings; - QString key = QString::fromStdString(entry->category() + "/" + entry->name()); - if (entry->is_default()) { + QString key = QString::fromStdString(entry.category() + "/" + entry.name()); + if (entry.is_default()) { settings.remove(key); } else { - settings.setValue(key, QString::fromStdString(entry->to_string())); + Value value = s->get(entry); + settings.setValue(key, QString::fromStdString(value.toString())); } } }; @@ -165,9 +190,20 @@ void Preferences::init() { this->polysetCacheSizeEdit->setValidator(validator); this->opencsgLimitEdit->setValidator(validator); - Settings::Settings *s = Settings::Settings::inst(); + initComboBox(this->comboBoxIndentUsing, Settings::Settings::indentStyle); + initComboBox(this->comboBoxLineWrap, Settings::Settings::lineWrap); + initComboBox(this->comboBoxLineWrapIndentationStyle, Settings::Settings::lineWrapIndentationStyle); + initComboBox(this->comboBoxLineWrapVisualizationEnd, Settings::Settings::lineWrapVisualizationEnd); + initComboBox(this->comboBoxLineWrapVisualizationStart, Settings::Settings::lineWrapVisualizationBegin); + initComboBox(this->comboBoxShowWhitespace, Settings::Settings::showWhitespace); + initComboBox(this->comboBoxTabKeyFunction, Settings::Settings::tabKeyFunction); + initSpinBox(this->spinBoxIndentationWidth, Settings::Settings::indentationWidth); + initSpinBox(this->spinBoxLineWrapIndentationIndent, Settings::Settings::lineWrapIndentation); + initSpinBox(this->spinBoxShowWhitespaceSize, Settings::Settings::showWhitespaceSize); + initSpinBox(this->spinBoxTabWidth, Settings::Settings::tabWidth); + SettingsReader settingsReader; - s->visit(&settingsReader); + Settings::Settings::inst()->visit(settingsReader); emit editorConfigChanged(); } @@ -437,86 +473,80 @@ void Preferences::on_launcherBox_toggled(bool state) void Preferences::on_spinBoxIndentationWidth_valueChanged(int val) { - Settings::Settings::inst()->set(Settings::Settings::indentationWidth, val); + Settings::Settings::inst()->set(Settings::Settings::indentationWidth, Value(val)); fireEditorConfigChanged(); } void Preferences::on_spinBoxTabWidth_valueChanged(int val) { - Settings::Settings::inst()->set(Settings::Settings::tabWidth, val); + Settings::Settings::inst()->set(Settings::Settings::tabWidth, Value(val)); fireEditorConfigChanged(); } void Preferences::on_comboBoxLineWrap_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::lineWrap, (Settings::LineWrap)val); - fireEditorConfigChanged(); + applyComboBox(comboBoxLineWrap, val, Settings::Settings::lineWrap); } -void Preferences::on_comboBoxLineWrapIndentation_activated(int val) +void Preferences::on_comboBoxLineWrapIndentationStyle_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentationStyle, (Settings::LineWrapIndentationStyle)val); - fireEditorConfigChanged(); + applyComboBox(comboBoxLineWrapIndentationStyle, val, Settings::Settings::lineWrapIndentationStyle); } void Preferences::on_spinBoxLineWrapIndentationIndent_valueChanged(int val) { - Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentation, val); + Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentation, Value(val)); fireEditorConfigChanged(); } void Preferences::on_comboBoxLineWrapVisualizationStart_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::lineWrapVisualizationBegin, (Settings::LineWrapVisualization)val); - fireEditorConfigChanged(); + applyComboBox(comboBoxLineWrapVisualizationStart, val, Settings::Settings::lineWrapVisualizationBegin); } void Preferences::on_comboBoxLineWrapVisualizationEnd_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::lineWrapVisualizationEnd, (Settings::LineWrapVisualization)val); - fireEditorConfigChanged(); + applyComboBox(comboBoxLineWrapVisualizationEnd, val, Settings::Settings::lineWrapVisualizationEnd); } void Preferences::on_comboBoxShowWhitespace_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::showWhitespace, (Settings::ShowWhitespace)val); - fireEditorConfigChanged(); + applyComboBox(comboBoxShowWhitespace, val, Settings::Settings::showWhitespace); } void Preferences::on_spinBoxShowWhitespaceSize_valueChanged(int val) { - Settings::Settings::inst()->set(Settings::Settings::showWhitespaceSize, val); + Settings::Settings::inst()->set(Settings::Settings::showWhitespaceSize, Value(val)); fireEditorConfigChanged(); } void Preferences::on_checkBoxAutoIndent_toggled(bool val) { - Settings::Settings::inst()->set(Settings::Settings::autoIndent, val); + Settings::Settings::inst()->set(Settings::Settings::autoIndent, Value(val)); fireEditorConfigChanged(); } void Preferences::on_comboBoxIndentUsing_activated(int val) { - Settings::Settings::inst()->set(Settings::Settings::indentStyle, (Settings::IndentStyle)val); - fireEditorConfigChanged(); + applyComboBox(comboBoxIndentUsing, val, Settings::Settings::indentStyle); } void Preferences::on_checkBoxHighlightCurrentLine_toggled(bool val) { - Settings::Settings::inst()->set(Settings::Settings::highlightCurrentLine, val); + Settings::Settings::inst()->set(Settings::Settings::highlightCurrentLine, Value(val)); fireEditorConfigChanged(); } void Preferences::on_checkBoxEnableBraceMatching_toggled(bool val) { - Settings::Settings::inst()->set(Settings::Settings::enableBraceMatching, val); + Settings::Settings::inst()->set(Settings::Settings::enableBraceMatching, Value(val)); fireEditorConfigChanged(); } void Preferences::fireEditorConfigChanged() const { SettingsWriter settingsWriter; - Settings::Settings::inst()->visit(&settingsWriter); + Settings::Settings::inst()->visit(settingsWriter); emit editorConfigChanged(); } @@ -615,19 +645,66 @@ void Preferences::updateGUI() this->launcherBox->setChecked(getValue("launcher/showOnStartup").toBool()); Settings::Settings *s = Settings::Settings::inst(); - this->spinBoxIndentationWidth->setValue(s->get(Settings::Settings::indentationWidth)); - this->spinBoxTabWidth->setValue(s->get(Settings::Settings::tabWidth)); - this->comboBoxLineWrap->setCurrentIndex(s->get(Settings::Settings::lineWrap)); - this->comboBoxLineWrapIndentation->setCurrentIndex(s->get(Settings::Settings::lineWrapIndentationStyle)); - this->spinBoxLineWrapIndentationIndent->setValue(s->get(Settings::Settings::lineWrapIndentation)); - this->comboBoxLineWrapVisualizationStart->setCurrentIndex(s->get(Settings::Settings::lineWrapVisualizationBegin)); - this->comboBoxLineWrapVisualizationEnd->setCurrentIndex(s->get(Settings::Settings::lineWrapVisualizationEnd)); - this->comboBoxShowWhitespace->setCurrentIndex(s->get(Settings::Settings::showWhitespace)); - this->spinBoxShowWhitespaceSize->setValue(s->get(Settings::Settings::showWhitespaceSize)); - this->checkBoxAutoIndent->setChecked(s->get(Settings::Settings::autoIndent)); - this->comboBoxIndentUsing->setCurrentIndex(s->get(Settings::Settings::indentStyle)); - this->checkBoxHighlightCurrentLine->setChecked(s->get(Settings::Settings::highlightCurrentLine)); - this->checkBoxEnableBraceMatching->setChecked(s->get(Settings::Settings::enableBraceMatching)); + updateComboBox(this->comboBoxLineWrap, Settings::Settings::lineWrap); + updateComboBox(this->comboBoxLineWrapIndentationStyle, Settings::Settings::lineWrapIndentationStyle); + updateComboBox(this->comboBoxLineWrapVisualizationStart, Settings::Settings::lineWrapVisualizationBegin); + updateComboBox(this->comboBoxLineWrapVisualizationEnd, Settings::Settings::lineWrapVisualizationEnd); + updateComboBox(this->comboBoxShowWhitespace, Settings::Settings::showWhitespace); + updateComboBox(this->comboBoxIndentUsing, Settings::Settings::indentStyle); + updateComboBox(this->comboBoxTabKeyFunction, Settings::Settings::tabKeyFunction); + this->spinBoxIndentationWidth->setValue(s->get(Settings::Settings::indentationWidth).toDouble()); + this->spinBoxTabWidth->setValue(s->get(Settings::Settings::tabWidth).toDouble()); + this->spinBoxLineWrapIndentationIndent->setValue(s->get(Settings::Settings::lineWrapIndentation).toDouble()); + this->spinBoxShowWhitespaceSize->setValue(s->get(Settings::Settings::showWhitespaceSize).toDouble()); + this->checkBoxAutoIndent->setChecked(s->get(Settings::Settings::autoIndent).toBool()); + this->checkBoxHighlightCurrentLine->setChecked(s->get(Settings::Settings::highlightCurrentLine).toBool()); + this->checkBoxEnableBraceMatching->setChecked(s->get(Settings::Settings::enableBraceMatching).toBool()); +} + +void Preferences::initComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry) +{ + comboBox->clear(); + Value::VectorType vector = entry.range().toVector(); + for (Value::VectorType::iterator it = vector.begin();it != vector.end();it++) { + QString val = QString::fromStdString((*it)[0].toString()); + QString text = QString::fromStdString((*it)[1].toString()); + comboBox->addItem(text, val); + } +} + +void Preferences::initSpinBox(QSpinBox *spinBox, const Settings::SettingsEntry& entry) +{ + Value::RangeType range = entry.range().toRange(); + spinBox->setMinimum(range.begin_value()); + spinBox->setMaximum(range.end_value()); +} + +void Preferences::updateComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry) +{ + Settings::Settings *s = Settings::Settings::inst(); + + Value value = s->get(entry); + QString text = QString::fromStdString(value.toString()); + int idx = comboBox->findData(text); + if (idx >= 0) { + comboBox->setCurrentIndex(idx); + } else { + Value defaultValue = entry.defaultValue(); + QString defaultText = QString::fromStdString(defaultValue.toString()); + int defIdx = comboBox->findData(defaultText); + if (defIdx >= 0) { + comboBox->setCurrentIndex(defIdx); + } else { + comboBox->setCurrentIndex(0); + } + } +} + +void Preferences::applyComboBox(QComboBox *comboBox, int val, Settings::SettingsEntry& entry) +{ + QString s = comboBox->itemData(val).toString(); + Settings::Settings::inst()->set(entry, Value(s.toStdString())); + fireEditorConfigChanged(); } void Preferences::apply() const diff --git a/src/Preferences.h b/src/Preferences.h index 4432140f..a5604dad 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -1,9 +1,11 @@ #pragma once -#include "qtgettext.h" #include #include + +#include "qtgettext.h" #include "ui_Preferences.h" +#include "settings.h" class Preferences : public QMainWindow, public Ui::Preferences { @@ -47,7 +49,7 @@ public slots: void on_spinBoxIndentationWidth_valueChanged(int); void on_spinBoxTabWidth_valueChanged(int); void on_comboBoxLineWrap_activated(int); - void on_comboBoxLineWrapIndentation_activated(int); + void on_comboBoxLineWrapIndentationStyle_activated(int); void on_spinBoxLineWrapIndentationIndent_valueChanged(int); void on_comboBoxLineWrapVisualizationStart_activated(int); void on_comboBoxLineWrapVisualizationEnd_activated(int); @@ -79,6 +81,15 @@ private: void fireEditorConfigChanged() const; void addPrefPage(QActionGroup *group, QAction *action, QWidget *widget); + /** Initialize combobox list values from the settings range values */ + void initComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry); + /** Initialize spinbox min/max values from the settings range values */ + void initSpinBox(QSpinBox *spinBox, const Settings::SettingsEntry& entry); + /** Update combobox from current settings */ + void updateComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry); + /** Set value from combobox to settings */ + void applyComboBox(QComboBox *comboBox, int val, Settings::SettingsEntry& entry); + QSettings::SettingsMap defaultmap; QHash prefPages; diff --git a/src/Preferences.ui b/src/Preferences.ui index f6d26e17..7c411229 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -6,8 +6,8 @@ 0 0 - 607 - 432 + 621 + 413 @@ -780,7 +780,7 @@ - + Fixed @@ -1201,7 +1201,7 @@ 0 0 - 640 + 596 499 diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 46b54583..a240d24c 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -10,67 +10,59 @@ class SettingsConverter { public: - QsciScintilla::WrapMode fromWrapMode(Settings::LineWrap val); - QsciScintilla::WrapVisualFlag fromLineWrapVisualization(Settings::LineWrapVisualization val); - QsciScintilla::WrapIndentMode fromLineWrapIndentationStyle(Settings::LineWrapIndentationStyle val); - QsciScintilla::WhitespaceVisibility fromShowWhitespaces(Settings::ShowWhitespace val); + QsciScintilla::WrapMode toWrapMode(Value val); + QsciScintilla::WrapVisualFlag toLineWrapVisualization(Value val); + QsciScintilla::WrapIndentMode toLineWrapIndentationStyle(Value val); + QsciScintilla::WhitespaceVisibility toShowWhitespaces(Value val); }; -QsciScintilla::WrapMode SettingsConverter::fromWrapMode(Settings::LineWrap val) +QsciScintilla::WrapMode SettingsConverter::toWrapMode(Value val) { - switch (val) { - case Settings::LINE_WRAP_NONE: - return QsciScintilla::WrapNone; - case Settings::LINE_WRAP_CHARACTER: + std::string v = val.toString(); + if (v == "Char") { return QsciScintilla::WrapCharacter; - case Settings::LINE_WRAP_WORD: + } else if (v == "Word") { return QsciScintilla::WrapWord; - default: - assert(false && "unknown wrap mode setting"); + } else { + return QsciScintilla::WrapNone; } } -QsciScintilla::WrapVisualFlag SettingsConverter::fromLineWrapVisualization(Settings::LineWrapVisualization val) +QsciScintilla::WrapVisualFlag SettingsConverter::toLineWrapVisualization(Value val) { - switch (val) { - case Settings::LINE_WRAP_VISUALIZATION_NONE: - return QsciScintilla::WrapFlagNone; - case Settings::LINE_WRAP_VISUALIZATION_TEXT: + std::string v = val.toString(); + if (v == "Text") { return QsciScintilla::WrapFlagByText; - case Settings::LINE_WRAP_VISUALIZATION_BORDER: + } else if (v == "Border") { return QsciScintilla::WrapFlagByBorder; - case Settings::LINE_WRAP_VISUALIZATION_MARGIN: + } else if (v == "Margin") { return QsciScintilla::WrapFlagInMargin; - default: - assert(false && "unknown wrap visualization setting"); + } else { + return QsciScintilla::WrapFlagNone; } } -QsciScintilla::WrapIndentMode SettingsConverter::fromLineWrapIndentationStyle(Settings::LineWrapIndentationStyle val) +QsciScintilla::WrapIndentMode SettingsConverter::toLineWrapIndentationStyle(Value val) { - switch (val) { - case Settings::LINE_WRAP_INDENTATION_FIXED: - return QsciScintilla::WrapIndentFixed; - case Settings::LINE_WRAP_INDENTATION_SAME: + std::string v = val.toString(); + if (v == "Same") { return QsciScintilla::WrapIndentSame; - case Settings::LINE_WRAP_INDENTATION_INDENTED: + } else if (v == "Indented") { return QsciScintilla::WrapIndentIndented; - default: - assert(false && "unknown wrap indentation style setting"); + } else { + return QsciScintilla::WrapIndentFixed; } } -QsciScintilla::WhitespaceVisibility SettingsConverter::fromShowWhitespaces(Settings::ShowWhitespace val) +QsciScintilla::WhitespaceVisibility SettingsConverter::toShowWhitespaces(Value val) { - switch(val) { - case Settings::SHOW_WHITESPACES_NEVER: - return QsciScintilla::WsInvisible; - case Settings::SHOW_WHITESPACES_ALWAYS: + std::string v = val.toString(); + if (v == "Always") { return QsciScintilla::WsVisible; - case Settings::SHOW_WHITESPACES_AFTER_INDENTATION: + } else if (v == "AfterIndentation") { return QsciScintilla::WsVisibleAfterIndent; - default: - assert(false && "unknown show whitespace setting"); + } else { + return QsciScintilla::WsInvisible; } } @@ -165,32 +157,24 @@ void ScintillaEditor::applySettings() SettingsConverter conv; Settings::Settings *s = Settings::Settings::inst(); - qsci->setIndentationWidth(s->get(Settings::Settings::indentationWidth)); - qsci->setTabWidth(s->get(Settings::Settings::tabWidth)); - qsci->setWrapMode(conv.fromWrapMode(s->get(Settings::Settings::lineWrap))); - qsci->setWrapIndentMode(conv.fromLineWrapIndentationStyle(s->get(Settings::Settings::lineWrapIndentationStyle))); - qsci->setWrapVisualFlags(conv.fromLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationEnd)), - conv.fromLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationBegin)), - s->get(Settings::Settings::lineWrapIndentation)); - qsci->setWhitespaceVisibility(conv.fromShowWhitespaces(s->get(Settings::Settings::showWhitespace))); - qsci->setWhitespaceSize(s->get(Settings::Settings::showWhitespaceSize)); - qsci->setAutoIndent(s->get(Settings::Settings::autoIndent)); + qsci->setIndentationWidth(s->get(Settings::Settings::indentationWidth).toDouble()); + qsci->setTabWidth(s->get(Settings::Settings::tabWidth).toDouble()); + qsci->setWrapMode(conv.toWrapMode(s->get(Settings::Settings::lineWrap))); + qsci->setWrapIndentMode(conv.toLineWrapIndentationStyle(s->get(Settings::Settings::lineWrapIndentationStyle))); + qsci->setWrapVisualFlags(conv.toLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationEnd)), + conv.toLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationBegin)), + s->get(Settings::Settings::lineWrapIndentation).toDouble()); + qsci->setWhitespaceVisibility(conv.toShowWhitespaces(s->get(Settings::Settings::showWhitespace))); + qsci->setWhitespaceSize(s->get(Settings::Settings::showWhitespaceSize).toDouble()); + qsci->setAutoIndent(s->get(Settings::Settings::autoIndent).toBool()); - switch (s->get(Settings::Settings::indentStyle)) { - case Settings::INDENT_SPACES: - qsci->setTabIndents(true); - qsci->setIndentationsUseTabs(false); - break; - case Settings::INDENT_TABS: - qsci->setTabIndents(false); - qsci->setIndentationsUseTabs(true); - break; - default: - assert(false && "unknown indent style"); - } + std::string indentStyle = s->get(Settings::Settings::indentStyle).toString(); + qsci->setIndentationsUseTabs(indentStyle == "Tabs"); + std::string tabKeyFunction = s->get(Settings::Settings::tabKeyFunction).toString(); + qsci->setTabIndents(tabKeyFunction == "Indent"); - qsci->setBraceMatching(s->get(Settings::Settings::enableBraceMatching) ? QsciScintilla::SloppyBraceMatch : QsciScintilla::NoBraceMatch); - qsci->setCaretLineVisible(s->get(Settings::Settings::highlightCurrentLine)); + qsci->setBraceMatching(s->get(Settings::Settings::enableBraceMatching).toBool() ? QsciScintilla::SloppyBraceMatch : QsciScintilla::NoBraceMatch); + qsci->setCaretLineVisible(s->get(Settings::Settings::highlightCurrentLine).toBool()); } void ScintillaEditor::setPlainText(const QString &text) diff --git a/src/settings.cc b/src/settings.cc index 2888d96c..8af5fea3 100644 --- a/src/settings.cc +++ b/src/settings.cc @@ -1,132 +1,72 @@ #include "settings.h" -#include "value.h" +#include "printutils.h" + +#include +using namespace boost::assign; // bring 'operator+=()' into scope namespace Settings { -std::list SettingsEntryBase::entries; +static std::list entries; -SettingsEntryBase::SettingsEntryBase(const std::string category, const std::string name) : _category(category), _name(name) +SettingsEntry::SettingsEntry(const std::string category, const std::string name, const Value range, const Value def) + : _category(category), _name(name), _value(def), _range(range), _default(def) { entries.push_back(this); } -SettingsEntryBase::~SettingsEntryBase() +SettingsEntry::~SettingsEntry() { } -const std::string & SettingsEntryBase::category() const +const std::string & SettingsEntry::category() const { return _category; } -const std::string & SettingsEntryBase::name() const +const std::string & SettingsEntry::name() const { return _name; } -template -SettingsEntry::SettingsEntry(const std::string category, const std::string name, T defaultValue) - : SettingsEntryBase(category, name), value(defaultValue), defaultValue(defaultValue) +const Value & SettingsEntry::defaultValue() const { + return _default; } -template -SettingsEntry::~SettingsEntry() +const Value & SettingsEntry::range() const { + return _range; } -template -bool SettingsEntry::is_default() const +bool SettingsEntry::is_default() const { - return defaultValue == value; + return _value == _default; } -template -std::string SettingsEntry::to_string() const -{ - return boost::lexical_cast(value); +static Value value(std::string s1, std::string s2) { + Value::VectorType v; + v += Value(s1), Value(s2); + return v; } -template <> -std::string SettingsEntry::to_string() const -{ - return boost::lexical_cast(value); +static Value values(std::string s1, std::string s1disp, std::string s2, std::string s2disp) { + Value::VectorType v; + v += value(s1, s1disp), value(s2, s2disp); + return v; } -template -void SettingsEntry::from_string(std::string val) -{ - try { - value = boost::lexical_cast(val); - } catch (const boost::bad_lexical_cast &e) { - value = defaultValue; - } +static Value values(std::string s1, std::string s1disp, std::string s2, std::string s2disp, std::string s3, std::string s3disp) { + Value::VectorType v; + v += value(s1, s1disp), value(s2, s2disp), value(s3, s3disp); + return v; } -template <> -void SettingsEntry::from_string(std::string val) -{ - try { - value = (LineWrap)boost::lexical_cast(val); - } catch (const boost::bad_lexical_cast &e) { - value = defaultValue; - } +static Value values(std::string s1, std::string s1disp, std::string s2, std::string s2disp, std::string s3, std::string s3disp, std::string s4, std::string s4disp) { + Value::VectorType v; + v += value(s1, s1disp), value(s2, s2disp), value(s3, s3disp), value(s4, s4disp); + return v; } -template <> -void SettingsEntry::from_string(std::string val) -{ - try { - value = (LineWrapIndentationStyle)boost::lexical_cast(val); - } catch (const boost::bad_lexical_cast &e) { - value = defaultValue; - } -} - -template <> -void SettingsEntry::from_string(std::string val) -{ - try { - value = (LineWrapVisualization)boost::lexical_cast(val); - } catch (const boost::bad_lexical_cast &e) { - value = defaultValue; - } -} - -template <> -void SettingsEntry::from_string(std::string val) -{ - try { - value = (ShowWhitespace)boost::lexical_cast(val); - } catch (const boost::bad_lexical_cast &e) { - value = defaultValue; - } -} - -template <> -void SettingsEntry::from_string(std::string val) -{ - try { - value = (IndentStyle)boost::lexical_cast(val); - } catch (const boost::bad_lexical_cast &e) { - value = defaultValue; - } -} - -SettingsEntry Settings::indentationWidth("editor", "indentationWidth", 4); -SettingsEntry Settings::tabWidth("editor", "tabWidth", 8); -SettingsEntry Settings::lineWrap("editor", "lineWrap", LINE_WRAP_WORD); -SettingsEntry Settings::lineWrapIndentationStyle("editor", "lineWrapIndentationStyle", LINE_WRAP_INDENTATION_FIXED); -SettingsEntry Settings::lineWrapIndentation("editor", "lineWrapIndentation", 4); -SettingsEntry Settings::lineWrapVisualizationBegin("editor", "lineWrapVisualizationBegin", LINE_WRAP_VISUALIZATION_NONE); -SettingsEntry Settings::lineWrapVisualizationEnd("editor", "lineWrapVisualizationEnd", LINE_WRAP_VISUALIZATION_BORDER); -SettingsEntry Settings::showWhitespace("editor", "showWhitespaces", SHOW_WHITESPACES_NEVER); -SettingsEntry Settings::showWhitespaceSize("editor", "showWhitespacesSize", 2); -SettingsEntry Settings::autoIndent("editor", "autoIndent", true); -SettingsEntry Settings::indentStyle("editor", "indentStyle", INDENT_SPACES); -SettingsEntry Settings::highlightCurrentLine("editor", "highlightCurrentLine", true); -SettingsEntry Settings::enableBraceMatching("editor", "enableBraceMatching", true); - Settings *Settings::inst(bool erase) { static Settings *instance = new Settings; @@ -147,59 +87,23 @@ Settings::~Settings() { } -void Settings::visit(class Visitor *visitor) +void Settings::visit(Visitor& visitor) { - for (std::list::iterator it = SettingsEntryBase::entries.begin();it != SettingsEntryBase::entries.end();it++) { - visitor->handle(*it); + for (std::list::iterator it = entries.begin();it != entries.end();it++) { + visitor.handle(*(*it)); } } -template -T Settings::defaultValue(const SettingsEntry &entry) +Value Settings::get(const SettingsEntry& entry) { - return entry.defaultValue; + return entry._value; } -template -T Settings::get(const SettingsEntry &entry) +void Settings::set(SettingsEntry& entry, const Value val) { - return entry.value; + entry._value = val; } -template -void Settings::set(SettingsEntry &entry, T val) -{ - entry.value = val; -} - -template bool Settings::defaultValue(const SettingsEntry&); -template bool Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, bool); - -template int Settings::defaultValue(const SettingsEntry&); -template int Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, int); - -template LineWrap Settings::defaultValue(const SettingsEntry&); -template LineWrap Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, LineWrap); - -template LineWrapVisualization Settings::defaultValue(const SettingsEntry&); -template LineWrapVisualization Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, LineWrapVisualization); - -template LineWrapIndentationStyle Settings::defaultValue(const SettingsEntry&); -template LineWrapIndentationStyle Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, LineWrapIndentationStyle); - -template ShowWhitespace Settings::defaultValue(const SettingsEntry&); -template ShowWhitespace Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, ShowWhitespace); - -template IndentStyle Settings::defaultValue(const SettingsEntry&); -template IndentStyle Settings::get(const SettingsEntry&); -template void Settings::set(SettingsEntry&, IndentStyle); - Visitor::Visitor() { } @@ -208,4 +112,28 @@ Visitor::~Visitor() { } +/* + * Supported settings entry types are: bool / int and string selection + * + * String selection is used to handle comboboxes and has two values + * per config selection. The first value is used internally for both + * finding the combobox selection and for storing the value in the + * external settings file. The second value is the display value that + * can be translated. + */ +SettingsEntry Settings::indentationWidth("editor", "indentationWidth", Value(Value::RangeType(1, 16)), Value(4)); +SettingsEntry Settings::tabWidth("editor", "tabWidth", Value(Value::RangeType(1, 16)), Value(8)); +SettingsEntry Settings::lineWrap("editor", "lineWrap", values("None", _("None"), "Char", _("Wrap at character boundaries"), "Word", _("Wrap at word boundaries")), Value("Word")); +SettingsEntry Settings::lineWrapIndentationStyle("editor", "lineWrapIndentationStyle", values("Fixed", _("Fixed"), "Same", _("Same"), "Indented", _("Indented")), Value("Fixed")); +SettingsEntry Settings::lineWrapIndentation("editor", "lineWrapIndentation", Value(Value::RangeType(0, 999)), Value(4)); +SettingsEntry Settings::lineWrapVisualizationBegin("editor", "lineWrapVisualizationBegin", values("None", _("None"), "Text", _("Text"), "Border", _("Border"), "Margin", _("Margin")), Value("None")); +SettingsEntry Settings::lineWrapVisualizationEnd("editor", "lineWrapVisualizationEnd", values("None", _("None"), "Text", _("Text"), "Border", _("Border"), "Margin", _("Margin")), Value("Border")); +SettingsEntry Settings::showWhitespace("editor", "showWhitespaces", values("Never", _("Never"), "Always", _("Always"), "AfterIndentation", _("After indentation")), Value("Never")); +SettingsEntry Settings::showWhitespaceSize("editor", "showWhitespacesSize", Value(Value::RangeType(1, 16)), Value(2)); +SettingsEntry Settings::autoIndent("editor", "autoIndent", Value(true), Value(true)); +SettingsEntry Settings::indentStyle("editor", "indentStyle", values("Spaces", _("Spaces"), "Tabs", _("Tabs")), Value("Spaces")); +SettingsEntry Settings::tabKeyFunction("editor", "tabKeyFunction", values("Indent", _("Indent"), "InsertTab", _("Insert Tab")), Value("Indent")); +SettingsEntry Settings::highlightCurrentLine("editor", "highlightCurrentLine", Value(true), Value(true)); +SettingsEntry Settings::enableBraceMatching("editor", "enableBraceMatching", Value(true), Value(true)); + } diff --git a/src/settings.h b/src/settings.h index f52273ad..a3099fe8 100644 --- a/src/settings.h +++ b/src/settings.h @@ -4,102 +4,59 @@ #include #include +#include "value.h" + namespace Settings { -typedef enum { - INDENT_SPACES, - INDENT_TABS, -} IndentStyle; - -typedef enum { - LINE_WRAP_NONE, - LINE_WRAP_CHARACTER, - LINE_WRAP_WORD, -} LineWrap; - -typedef enum { - LINE_WRAP_INDENTATION_FIXED, - LINE_WRAP_INDENTATION_SAME, - LINE_WRAP_INDENTATION_INDENTED, -} LineWrapIndentationStyle; - -typedef enum { - LINE_WRAP_VISUALIZATION_NONE, - LINE_WRAP_VISUALIZATION_TEXT, - LINE_WRAP_VISUALIZATION_BORDER, - LINE_WRAP_VISUALIZATION_MARGIN, -} LineWrapVisualization; - -typedef enum { - SHOW_WHITESPACES_NEVER, - SHOW_WHITESPACES_ALWAYS, - SHOW_WHITESPACES_AFTER_INDENTATION, -} ShowWhitespace; - -class SettingsEntryBase +class SettingsEntry { private: std::string _category; std::string _name; + Value _value; + Value _range; + Value _default; public: const std::string & category() const; const std::string & name() const; - virtual bool is_default() const = 0; - virtual std::string to_string() const = 0; - virtual void from_string(std::string) = 0; + virtual const Value & defaultValue() const; + virtual const Value & range() const; + virtual bool is_default() const; protected: - SettingsEntryBase(const std::string category, const std::string name); - ~SettingsEntryBase(); - - static std::list entries; - - friend class Settings; -}; - -template -class SettingsEntry : public SettingsEntryBase -{ -private: - T value; - T defaultValue; - - SettingsEntry(const std::string category, const std::string name, T defaultValue); + SettingsEntry(const std::string category, const std::string name, const Value range, const Value def); virtual ~SettingsEntry(); - virtual bool is_default() const; - virtual std::string to_string() const; - virtual void from_string(std::string); - friend class Settings; }; class Settings { public: - static SettingsEntry indentationWidth; - static SettingsEntry tabWidth; - static SettingsEntry lineWrap; - static SettingsEntry lineWrapIndentationStyle; - static SettingsEntry lineWrapIndentation; - static SettingsEntry lineWrapVisualizationBegin; - static SettingsEntry lineWrapVisualizationEnd; - static SettingsEntry showWhitespace; - static SettingsEntry showWhitespaceSize; - static SettingsEntry autoIndent; - static SettingsEntry indentStyle; - static SettingsEntry highlightCurrentLine; - static SettingsEntry enableBraceMatching; + static SettingsEntry indentationWidth; + static SettingsEntry tabWidth; + static SettingsEntry lineWrap; + static SettingsEntry lineWrapIndentationStyle; + static SettingsEntry lineWrapIndentation; + static SettingsEntry lineWrapVisualizationBegin; + static SettingsEntry lineWrapVisualizationEnd; + static SettingsEntry showWhitespace; + static SettingsEntry showWhitespaceSize; + static SettingsEntry autoIndent; + static SettingsEntry indentStyle; + static SettingsEntry tabKeyFunction; + static SettingsEntry highlightCurrentLine; + static SettingsEntry enableBraceMatching; static Settings *inst(bool erase = false); - void visit(class Visitor *visitor); + void visit(class Visitor& visitor); - template T defaultValue(const SettingsEntry &entry); - template T get(const SettingsEntry &entry); - template void set(SettingsEntry &entry, T val); + Value defaultValue(const SettingsEntry& entry); + Value get(const SettingsEntry& entry); + void set(SettingsEntry& entry, const Value val); private: Settings(); @@ -112,7 +69,7 @@ public: Visitor(); virtual ~Visitor(); - virtual void handle(SettingsEntryBase * entry) const = 0; + virtual void handle(SettingsEntry& entry) const = 0; }; } \ No newline at end of file diff --git a/src/value.h b/src/value.h index 63b57ce6..f646681f 100644 --- a/src/value.h +++ b/src/value.h @@ -82,6 +82,10 @@ public: this->end_val == other.end_val; } + double begin_value() { return begin_val; } + double step_value() { return step_val; } + double end_value() { return end_val; } + iterator begin() { return iterator(*this, RANGE_TYPE_BEGIN); } iterator end() { return iterator(*this, RANGE_TYPE_END); } From e69513fa2e6a88d05ef0e58eb7cd6aabe402e5c6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 30 Dec 2014 02:49:47 -0500 Subject: [PATCH 220/263] #1119 Added missing slot to change tab key function --- src/Preferences.cc | 5 +++++ src/Preferences.h | 37 +++++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index 34ae2afd..11d64502 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -531,6 +531,11 @@ void Preferences::on_comboBoxIndentUsing_activated(int val) applyComboBox(comboBoxIndentUsing, val, Settings::Settings::indentStyle); } +void Preferences::on_comboBoxTabKeyFunction_activated(int val) +{ + applyComboBox(comboBoxTabKeyFunction, val, Settings::Settings::tabKeyFunction); +} + void Preferences::on_checkBoxHighlightCurrentLine_toggled(bool val) { Settings::Settings::inst()->set(Settings::Settings::highlightCurrentLine, Value(val)); diff --git a/src/Preferences.h b/src/Preferences.h index a5604dad..35c7d625 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -45,20 +45,29 @@ public slots: void on_launcherBox_toggled(bool); void on_editorType_editTextChanged(const QString &); - // editor settings - void on_spinBoxIndentationWidth_valueChanged(int); - void on_spinBoxTabWidth_valueChanged(int); - void on_comboBoxLineWrap_activated(int); - void on_comboBoxLineWrapIndentationStyle_activated(int); - void on_spinBoxLineWrapIndentationIndent_valueChanged(int); - void on_comboBoxLineWrapVisualizationStart_activated(int); - void on_comboBoxLineWrapVisualizationEnd_activated(int); - void on_comboBoxShowWhitespace_activated(int); - void on_spinBoxShowWhitespaceSize_valueChanged(int); - void on_checkBoxAutoIndent_toggled(bool); - void on_comboBoxIndentUsing_activated(int); - void on_checkBoxHighlightCurrentLine_toggled(bool); - void on_checkBoxEnableBraceMatching_toggled(bool); + // + // editor settings + // + + // Indentation + void on_checkBoxAutoIndent_toggled(bool); + void on_comboBoxIndentUsing_activated(int); + void on_spinBoxIndentationWidth_valueChanged(int); + void on_spinBoxTabWidth_valueChanged(int); + void on_comboBoxTabKeyFunction_activated(int); + void on_comboBoxShowWhitespace_activated(int); + void on_spinBoxShowWhitespaceSize_valueChanged(int); + + // Line wrap + void on_comboBoxLineWrap_activated(int); + void on_comboBoxLineWrapIndentationStyle_activated(int); + void on_spinBoxLineWrapIndentationIndent_valueChanged(int); + void on_comboBoxLineWrapVisualizationStart_activated(int); + void on_comboBoxLineWrapVisualizationEnd_activated(int); + + // Display + void on_checkBoxHighlightCurrentLine_toggled(bool); + void on_checkBoxEnableBraceMatching_toggled(bool); signals: void requestRedraw() const; From 8d4d83f168f0a6bdc93c9d9cd07f91cb2009f418 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 30 Dec 2014 13:03:51 +0100 Subject: [PATCH 221/263] Fix build with Qt4. --- src/Preferences.cc | 23 ++++++++++++++--------- src/Preferences.h | 3 ++- src/mainwin.cc | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Preferences.cc b/src/Preferences.cc index 11d64502..f133ffdc 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -474,13 +474,13 @@ void Preferences::on_launcherBox_toggled(bool state) void Preferences::on_spinBoxIndentationWidth_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::indentationWidth, Value(val)); - fireEditorConfigChanged(); + writeSettings(); } void Preferences::on_spinBoxTabWidth_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::tabWidth, Value(val)); - fireEditorConfigChanged(); + writeSettings(); } void Preferences::on_comboBoxLineWrap_activated(int val) @@ -496,7 +496,7 @@ void Preferences::on_comboBoxLineWrapIndentationStyle_activated(int val) void Preferences::on_spinBoxLineWrapIndentationIndent_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentation, Value(val)); - fireEditorConfigChanged(); + writeSettings(); } void Preferences::on_comboBoxLineWrapVisualizationStart_activated(int val) @@ -517,13 +517,13 @@ void Preferences::on_comboBoxShowWhitespace_activated(int val) void Preferences::on_spinBoxShowWhitespaceSize_valueChanged(int val) { Settings::Settings::inst()->set(Settings::Settings::showWhitespaceSize, Value(val)); - fireEditorConfigChanged(); + writeSettings(); } void Preferences::on_checkBoxAutoIndent_toggled(bool val) { Settings::Settings::inst()->set(Settings::Settings::autoIndent, Value(val)); - fireEditorConfigChanged(); + writeSettings(); } void Preferences::on_comboBoxIndentUsing_activated(int val) @@ -539,19 +539,24 @@ void Preferences::on_comboBoxTabKeyFunction_activated(int val) void Preferences::on_checkBoxHighlightCurrentLine_toggled(bool val) { Settings::Settings::inst()->set(Settings::Settings::highlightCurrentLine, Value(val)); - fireEditorConfigChanged(); + writeSettings(); } void Preferences::on_checkBoxEnableBraceMatching_toggled(bool val) { Settings::Settings::inst()->set(Settings::Settings::enableBraceMatching, Value(val)); + writeSettings(); +} + +void Preferences::writeSettings() +{ + SettingsWriter settingsWriter; + Settings::Settings::inst()->visit(settingsWriter); fireEditorConfigChanged(); } void Preferences::fireEditorConfigChanged() const { - SettingsWriter settingsWriter; - Settings::Settings::inst()->visit(settingsWriter); emit editorConfigChanged(); } @@ -709,7 +714,7 @@ void Preferences::applyComboBox(QComboBox *comboBox, int val, Settings::Settings { QString s = comboBox->itemData(val).toString(); Settings::Settings::inst()->set(entry, Value(s.toStdString())); - fireEditorConfigChanged(); + writeSettings(); } void Preferences::apply() const diff --git a/src/Preferences.h b/src/Preferences.h index 35c7d625..82cced50 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -20,6 +20,7 @@ public: QVariant getValue(const QString &key) const; void init(); void apply() const; + void fireEditorConfigChanged() const; public slots: void actionTriggered(class QAction *); @@ -87,7 +88,7 @@ private: void updateGUI(); void removeDefaultSettings(); void setupFeaturesPage(); - void fireEditorConfigChanged() const; + void writeSettings(); void addPrefPage(QActionGroup *group, QAction *action, QWidget *widget); /** Initialize combobox list values from the settings range values */ diff --git a/src/mainwin.cc b/src/mainwin.cc index e4a01584..c39dfe58 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -204,7 +204,7 @@ MainWindow::MainWindow(const QString &filename) #ifdef USE_SCINTILLA_EDITOR if (useScintilla) { connect(Preferences::inst(), SIGNAL(editorConfigChanged()), editor, SLOT(applySettings())); - Preferences::inst()->editorConfigChanged(); + Preferences::inst()->fireEditorConfigChanged(); } #endif From bebe08483f511fe87df191fbff5261a729e64b9f Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Tue, 30 Dec 2014 13:58:48 +0100 Subject: [PATCH 222/263] The WrapFlagInMargin value is only available in QScintilla 2.7 and later. This is a workaround for Debian 7 which has QScintilla 2.6.2. The "Margin" setting is simply ignored and behaves as "None". --- src/scintillaeditor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index a240d24c..88836747 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -35,8 +35,10 @@ QsciScintilla::WrapVisualFlag SettingsConverter::toLineWrapVisualization(Value v return QsciScintilla::WrapFlagByText; } else if (v == "Border") { return QsciScintilla::WrapFlagByBorder; +#if QSCINTILLA_VERSION >= 0x020700 } else if (v == "Margin") { return QsciScintilla::WrapFlagInMargin; +#endif } else { return QsciScintilla::WrapFlagNone; } From 4eaf8797c2fba5d46a6ce8cdb111f5a64cfb39b8 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 31 Dec 2014 02:52:56 -0500 Subject: [PATCH 223/263] Small refactoring: Split out Polyhedron-related functions to from cgalutils.cc to cgalutils-polyhedron.cc --- openscad.pro | 1 + src/cgal.h | 2 - src/cgalutils-polyhedron.cc | 308 ++++++++++++++++++++++++++++++++++++ src/cgalutils.cc | 280 +------------------------------- src/cgalutils.h | 7 +- tests/CMakeLists.txt | 1 + 6 files changed, 317 insertions(+), 282 deletions(-) create mode 100644 src/cgalutils-polyhedron.cc diff --git a/openscad.pro b/openscad.pro index 80785f84..f9478c79 100644 --- a/openscad.pro +++ b/openscad.pro @@ -472,6 +472,7 @@ HEADERS += src/cgal.h \ SOURCES += src/cgalutils.cc \ src/cgalutils-tess.cc \ + src/cgalutils-polyhedron.cc \ src/cgalutils-tess-old.cc \ src/CGALCache.cc \ src/CGALRenderer.cc \ diff --git a/src/cgal.h b/src/cgal.h index 888bf2bc..eb7203bd 100644 --- a/src/cgal.h +++ b/src/cgal.h @@ -57,8 +57,6 @@ 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; typedef CGAL::Point_3 CGAL_Point_3; typedef CGAL::Iso_cuboid_3 CGAL_Iso_cuboid_3; diff --git a/src/cgalutils-polyhedron.cc b/src/cgalutils-polyhedron.cc new file mode 100644 index 00000000..16939316 --- /dev/null +++ b/src/cgalutils-polyhedron.cc @@ -0,0 +1,308 @@ +#ifdef ENABLE_CGAL + +#include "cgalutils.h" +#include "polyset.h" +#include "printutils.h" +#include "polyset-utils.h" +#include "grid.h" + +#include "cgal.h" +#include + +#include + +namespace /* anonymous */ { + template + Result vector_convert(V const& v) { + return Result(CGAL::to_double(v[0]),CGAL::to_double(v[1]),CGAL::to_double(v[2])); + } + +#undef GEN_SURFACE_DEBUG + + template + class CGAL_Build_PolySet : public CGAL::Modifier_base + { + typedef typename Polyhedron::HalfedgeDS HDS; + typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; + public: + typedef typename CGAL_Polybuilder::Point_3 CGALPoint; + + const PolySet &ps; + CGAL_Build_PolySet(const PolySet &ps) : ps(ps) { } + +/* + Using Grid here is important for performance reasons. See following model. + If we don't grid the geometry before converting to a Nef Polyhedron, the quads + in the cylinders to tessellated into triangles since floating point + incertainty causes the faces to not be 100% planar. The incertainty is exaggerated + by the transform. This wasn't a problem earlier since we used Nef for everything, + but optimizations since then has made us keep it in floating point space longer. + + minkowski() { + cube([200, 50, 7], center = true); + rotate([90,0,0]) cylinder($fn = 8, h = 1, r = 8.36, center = true); + rotate([0,90,0]) cylinder($fn = 8, h = 1, r = 8.36, center = true); + } +*/ +#if 1 // Use Grid + void operator()(HDS& hds) { + CGAL_Polybuilder B(hds, true); + + std::vector vertices; + Grid3d grid(GRID_FINE); + std::vector indices(3); + + BOOST_FOREACH(const Polygon &p, ps.polygons) { + BOOST_REVERSE_FOREACH(Vector3d v, p) { + if (!grid.has(v)) { + // align v to the grid; the CGALPoint will receive the aligned vertex + grid.align(v) = vertices.size(); + vertices.push_back(CGALPoint(v[0], v[1], v[2])); + } + } + } + +#ifdef GEN_SURFACE_DEBUG + printf("polyhedron(faces=["); + int pidx = 0; +#endif + B.begin_surface(vertices.size(), ps.polygons.size()); + BOOST_FOREACH(const CGALPoint &p, vertices) { + B.add_vertex(p); + } + BOOST_FOREACH(const Polygon &p, ps.polygons) { +#ifdef GEN_SURFACE_DEBUG + if (pidx++ > 0) printf(","); +#endif + indices.clear(); + BOOST_FOREACH(const Vector3d &v, p) { + indices.push_back(grid.data(v)); + } + + // We perform this test since there is a bug in CGAL's + // Polyhedron_incremental_builder_3::test_facet() which + // fails to detect duplicate indices + bool err = false; + for (std::size_t i = 0; i < indices.size(); ++i) { + // check if vertex indices[i] is already in the sequence [0..i-1] + for (std::size_t k = 0; k < i && !err; ++k) { + if (indices[k] == indices[i]) { + err = true; + break; + } + } + } + if (!err && B.test_facet(indices.begin(), indices.end())) { + B.add_facet(indices.begin(), indices.end()); + } +#ifdef GEN_SURFACE_DEBUG + printf("["); + int fidx = 0; + BOOST_FOREACH(size_t i, indices) { + if (fidx++ > 0) printf(","); + printf("%ld", i); + } + printf("]"); +#endif + } + B.end_surface(); +#ifdef GEN_SURFACE_DEBUG + printf("],\n"); +#endif +#ifdef GEN_SURFACE_DEBUG + printf("points=["); + for (int i=0;i 0) printf(","); + const CGALPoint &p = vertices[i]; + printf("[%g,%g,%g]", CGAL::to_double(p.x()), CGAL::to_double(p.y()), CGAL::to_double(p.z())); + } + printf("]);\n"); +#endif + } +#else // Don't use Grid + void operator()(HDS& hds) + { + CGAL_Polybuilder B(hds, true); + Reindexer vertices; + std::vector indices(3); + + // Estimating same # of vertices as polygons (very rough) + B.begin_surface(ps.polygons.size(), ps.polygons.size()); + int pidx = 0; +#ifdef GEN_SURFACE_DEBUG + printf("polyhedron(faces=["); +#endif + BOOST_FOREACH(const Polygon &p, ps.polygons) { +#ifdef GEN_SURFACE_DEBUG + if (pidx++ > 0) printf(","); +#endif + indices.clear(); + BOOST_REVERSE_FOREACH(const Vector3d &v, p) { + size_t s = vertices.size(); + size_t idx = vertices.lookup(v); + // If we added a vertex, also add it to the CGAL builder + if (idx == s) B.add_vertex(CGALPoint(v[0], v[1], v[2])); + indices.push_back(idx); + } + // We perform this test since there is a bug in CGAL's + // Polyhedron_incremental_builder_3::test_facet() which + // fails to detect duplicate indices + bool err = false; + for (std::size_t i = 0; i < indices.size(); ++i) { + // check if vertex indices[i] is already in the sequence [0..i-1] + for (std::size_t k = 0; k < i && !err; ++k) { + if (indices[k] == indices[i]) { + err = true; + break; + } + } + } + if (!err && B.test_facet(indices.begin(), indices.end())) { + B.add_facet(indices.begin(), indices.end()); +#ifdef GEN_SURFACE_DEBUG + printf("["); + int fidx = 0; + BOOST_FOREACH(size_t i, indices) { + if (fidx++ > 0) printf(","); + printf("%ld", i); + } + printf("]"); +#endif + } + } + B.end_surface(); +#ifdef GEN_SURFACE_DEBUG + printf("],\n"); + + printf("points=["); + for (int vidx=0;vidx 0) printf(","); + const Vector3d &v = vertices.getArray()[vidx]; + printf("[%g,%g,%g]", v[0], v[1], v[2]); + } + printf("]);\n"); +#endif + } +#endif + }; + + // This code is from CGAL/demo/Polyhedron/Scene_nef_polyhedron_item.cpp + // quick hacks to convert polyhedra from exact to inexact and vice-versa + template + struct Copy_polyhedron_to : public CGAL::Modifier_base + { + Copy_polyhedron_to(const Polyhedron_input& in_poly) : in_poly(in_poly) {} + + void operator()(typename Polyhedron_output::HalfedgeDS& out_hds) + { + typedef typename Polyhedron_output::HalfedgeDS Output_HDS; + + CGAL::Polyhedron_incremental_builder_3 builder(out_hds); + + typedef typename Polyhedron_input::Vertex_const_iterator Vertex_const_iterator; + typedef typename Polyhedron_input::Facet_const_iterator Facet_const_iterator; + typedef typename Polyhedron_input::Halfedge_around_facet_const_circulator HFCC; + + builder.begin_surface(in_poly.size_of_vertices(), + in_poly.size_of_facets(), + in_poly.size_of_halfedges()); + + for (Vertex_const_iterator + vi = in_poly.vertices_begin(), end = in_poly.vertices_end(); + vi != end ; ++vi) { + typename Polyhedron_output::Point_3 p(::CGAL::to_double(vi->point().x()), + ::CGAL::to_double(vi->point().y()), + ::CGAL::to_double(vi->point().z())); + builder.add_vertex(p); + } + + typedef CGAL::Inverse_index Index; + Index index(in_poly.vertices_begin(), in_poly.vertices_end()); + + for (Facet_const_iterator + fi = in_poly.facets_begin(), end = in_poly.facets_end(); + fi != end; ++fi) { + HFCC hc = fi->facet_begin(); + HFCC hc_end = hc; + // std::size_t n = circulator_size(hc); + // CGAL_assertion(n >= 3); + builder.begin_facet (); + do { + builder.add_vertex_to_facet(index[hc->vertex()]); + ++hc; + } while(hc != hc_end); + builder.end_facet(); + } + builder.end_surface(); + } // end operator()(..) + private: + const Polyhedron_input& in_poly; + }; // end Copy_polyhedron_to<> + +} + +namespace CGALUtils { + + template + void copyPolyhedron(const Polyhedron_A &poly_a, Polyhedron_B &poly_b) + { + Copy_polyhedron_to modifier(poly_a); + poly_b.delegate(modifier); + } + + template void copyPolyhedron(const CGAL::Polyhedron_3 &, CGAL_Polyhedron &); + template void copyPolyhedron(const CGAL_Polyhedron &, CGAL::Polyhedron_3 &); + + template + bool createPolyhedronFromPolySet(const PolySet &ps, Polyhedron &p) + { + bool err = false; + CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); + try { + CGAL_Build_PolySet builder(ps); + p.delegate(builder); + } + catch (const CGAL::Assertion_exception &e) { + PRINTB("CGAL error in CGALUtils::createPolyhedronFromPolySet: %s", e.what()); + err = true; + } + CGAL::set_error_behaviour(old_behaviour); + return err; + } + + template bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p); + template bool createPolyhedronFromPolySet(const PolySet &ps, CGAL::Polyhedron_3 &p); + + template + bool createPolySetFromPolyhedron(const Polyhedron &p, PolySet &ps) + { + bool err = false; + typedef typename Polyhedron::Vertex Vertex; + typedef typename Polyhedron::Vertex_const_iterator VCI; + typedef typename Polyhedron::Facet_const_iterator FCI; + typedef typename 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 const& v = *((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); + } + return err; + } + + template bool createPolySetFromPolyhedron(const CGAL_Polyhedron &p, PolySet &ps); + template bool createPolySetFromPolyhedron(const CGAL::Polyhedron_3 &p, PolySet &ps); + template bool createPolySetFromPolyhedron(const CGAL::Polyhedron_3 &p, PolySet &ps); + template bool createPolySetFromPolyhedron(const CGAL::Polyhedron_3 > &p, PolySet &ps); + +}; // namespace CGALUtils + +#endif /* ENABLE_CGAL */ + diff --git a/src/cgalutils.cc b/src/cgalutils.cc index efc55ee5..fde80286 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -34,238 +34,6 @@ namespace /* anonymous */ { Result vector_convert(V const& v) { return Result(CGAL::to_double(v[0]),CGAL::to_double(v[1]),CGAL::to_double(v[2])); } - -#undef GEN_SURFACE_DEBUG - - class CGAL_Build_PolySet : public CGAL::Modifier_base - { - public: - typedef CGAL_Polybuilder::Point_3 CGALPoint; - - const PolySet &ps; - CGAL_Build_PolySet(const PolySet &ps) : ps(ps) { } - -/* - Using Grid here is important for performance reasons. See following model. - If we don't grid the geometry before converting to a Nef Polyhedron, the quads - in the cylinders to tessellated into triangles since floating point - incertainty causes the faces to not be 100% planar. The incertainty is exaggerated - by the transform. This wasn't a problem earlier since we used Nef for everything, - but optimizations since then has made us keep it in floating point space longer. - - minkowski() { - cube([200, 50, 7], center = true); - rotate([90,0,0]) cylinder($fn = 8, h = 1, r = 8.36, center = true); - rotate([0,90,0]) cylinder($fn = 8, h = 1, r = 8.36, center = true); - } -*/ -#if 1 // Use Grid - void operator()(CGAL_HDS& hds) { - CGAL_Polybuilder B(hds, true); - - std::vector vertices; - Grid3d grid(GRID_FINE); - std::vector indices(3); - - BOOST_FOREACH(const Polygon &p, ps.polygons) { - BOOST_REVERSE_FOREACH(Vector3d v, p) { - if (!grid.has(v)) { - // align v to the grid; the CGALPoint will receive the aligned vertex - grid.align(v) = vertices.size(); - vertices.push_back(CGALPoint(v[0], v[1], v[2])); - } - } - } - -#ifdef GEN_SURFACE_DEBUG - printf("polyhedron(faces=["); - int pidx = 0; -#endif - B.begin_surface(vertices.size(), ps.polygons.size()); - BOOST_FOREACH(const CGALPoint &p, vertices) { - B.add_vertex(p); - } - BOOST_FOREACH(const Polygon &p, ps.polygons) { -#ifdef GEN_SURFACE_DEBUG - if (pidx++ > 0) printf(","); -#endif - indices.clear(); - BOOST_FOREACH(const Vector3d &v, p) { - indices.push_back(grid.data(v)); - } - - // We perform this test since there is a bug in CGAL's - // Polyhedron_incremental_builder_3::test_facet() which - // fails to detect duplicate indices - bool err = false; - for (std::size_t i = 0; i < indices.size(); ++i) { - // check if vertex indices[i] is already in the sequence [0..i-1] - for (std::size_t k = 0; k < i && !err; ++k) { - if (indices[k] == indices[i]) { - err = true; - break; - } - } - } - if (!err && B.test_facet(indices.begin(), indices.end())) { - B.add_facet(indices.begin(), indices.end()); - } -#ifdef GEN_SURFACE_DEBUG - printf("["); - int fidx = 0; - BOOST_FOREACH(size_t i, indices) { - if (fidx++ > 0) printf(","); - printf("%ld", i); - } - printf("]"); -#endif - } - B.end_surface(); -#ifdef GEN_SURFACE_DEBUG - printf("],\n"); -#endif -#ifdef GEN_SURFACE_DEBUG - printf("points=["); - for (int i=0;i 0) printf(","); - const CGALPoint &p = vertices[i]; - printf("[%g,%g,%g]", CGAL::to_double(p.x()), CGAL::to_double(p.y()), CGAL::to_double(p.z())); - } - printf("]);\n"); -#endif - } -#else // Don't use Grid - void operator()(CGAL_HDS& hds) - { - CGAL_Polybuilder B(hds, true); - Reindexer vertices; - std::vector indices(3); - - // Estimating same # of vertices as polygons (very rough) - B.begin_surface(ps.polygons.size(), ps.polygons.size()); - int pidx = 0; -#ifdef GEN_SURFACE_DEBUG - printf("polyhedron(faces=["); -#endif - BOOST_FOREACH(const Polygon &p, ps.polygons) { -#ifdef GEN_SURFACE_DEBUG - if (pidx++ > 0) printf(","); -#endif - indices.clear(); - BOOST_REVERSE_FOREACH(const Vector3d &v, p) { - size_t s = vertices.size(); - size_t idx = vertices.lookup(v); - // If we added a vertex, also add it to the CGAL builder - if (idx == s) B.add_vertex(CGALPoint(v[0], v[1], v[2])); - indices.push_back(idx); - } - // We perform this test since there is a bug in CGAL's - // Polyhedron_incremental_builder_3::test_facet() which - // fails to detect duplicate indices - bool err = false; - for (std::size_t i = 0; i < indices.size(); ++i) { - // check if vertex indices[i] is already in the sequence [0..i-1] - for (std::size_t k = 0; k < i && !err; ++k) { - if (indices[k] == indices[i]) { - err = true; - break; - } - } - } - if (!err && B.test_facet(indices.begin(), indices.end())) { - B.add_facet(indices.begin(), indices.end()); -#ifdef GEN_SURFACE_DEBUG - printf("["); - int fidx = 0; - BOOST_FOREACH(size_t i, indices) { - if (fidx++ > 0) printf(","); - printf("%ld", i); - } - printf("]"); -#endif - } - } - B.end_surface(); -#ifdef GEN_SURFACE_DEBUG - printf("],\n"); - - printf("points=["); - for (int vidx=0;vidx 0) printf(","); - const Vector3d &v = vertices.getArray()[vidx]; - printf("[%g,%g,%g]", v[0], v[1], v[2]); - } - printf("]);\n"); -#endif - } -#endif - }; - - // This code is from CGAL/demo/Polyhedron/Scene_nef_polyhedron_item.cpp - // quick hacks to convert polyhedra from exact to inexact and vice-versa - template - struct Copy_polyhedron_to - : public CGAL::Modifier_base - { - Copy_polyhedron_to(const Polyhedron_input& in_poly) - : in_poly(in_poly) {} - - void operator()(typename Polyhedron_output::HalfedgeDS& out_hds) - { - typedef typename Polyhedron_output::HalfedgeDS Output_HDS; - - CGAL::Polyhedron_incremental_builder_3 builder(out_hds); - - typedef typename Polyhedron_input::Vertex_const_iterator Vertex_const_iterator; - typedef typename Polyhedron_input::Facet_const_iterator Facet_const_iterator; - typedef typename Polyhedron_input::Halfedge_around_facet_const_circulator HFCC; - - builder.begin_surface(in_poly.size_of_vertices(), - in_poly.size_of_facets(), - in_poly.size_of_halfedges()); - - for(Vertex_const_iterator - vi = in_poly.vertices_begin(), end = in_poly.vertices_end(); - vi != end ; ++vi) - { - typename Polyhedron_output::Point_3 p(::CGAL::to_double(vi->point().x()), - ::CGAL::to_double(vi->point().y()), - ::CGAL::to_double(vi->point().z())); - builder.add_vertex(p); - } - - typedef CGAL::Inverse_index Index; - Index index(in_poly.vertices_begin(), in_poly.vertices_end()); - - for(Facet_const_iterator - fi = in_poly.facets_begin(), end = in_poly.facets_end(); - fi != end; ++fi) - { - HFCC hc = fi->facet_begin(); - HFCC hc_end = hc; - // std::size_t n = circulator_size(hc); - // CGAL_assertion(n >= 3); - builder.begin_facet (); - do { - builder.add_vertex_to_facet(index[hc->vertex()]); - ++hc; - } while(hc != hc_end); - builder.end_facet(); - } - builder.end_surface(); - } // end operator()(..) - private: - const Polyhedron_input& in_poly; - }; // end Copy_polyhedron_to<> - - template - void copy_to(const Poly_A& poly_a, Poly_B& poly_b) - { - Copy_polyhedron_to modifier(poly_a); - poly_b.delegate(modifier); - } - } static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) @@ -294,8 +62,8 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) // Apply hull CGAL::Polyhedron_3 r; CGAL::convex_hull_3(points.begin(), points.end(), r); - CGAL::Polyhedron_3 r_exact; - copy_to(r,r_exact); + CGAL_Polyhedron r_exact; + CGALUtils::copyPolyhedron(r, r_exact); return new CGAL_Nef_polyhedron(new CGAL_Nef_polyhedron3(r_exact)); } @@ -341,22 +109,6 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolygon2d(const Polygon2d &po namespace CGALUtils { - bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p) - { - bool err = false; - CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); - try { - CGAL_Build_PolySet builder(ps); - p.delegate(builder); - } - catch (const CGAL::Assertion_exception &e) { - PRINTB("CGAL error in CGALUtils::createPolyhedronFromPolySet: %s", e.what()); - err = true; - } - CGAL::set_error_behaviour(old_behaviour); - return err; - } - bool applyHull(const Geometry::ChildList &children, PolySet &result) { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; @@ -1010,34 +762,6 @@ namespace CGALUtils { return explored_facets.size() == ps.polygons.size(); } - template - bool createPolySetFromPolyhedron(const Polyhedron &p, PolySet &ps) - { - bool err = false; - typedef typename Polyhedron::Vertex Vertex; - typedef typename Polyhedron::Vertex_const_iterator VCI; - typedef typename Polyhedron::Facet_const_iterator FCI; - typedef typename 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 const& v = *((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); - } - return err; - } - - template bool createPolySetFromPolyhedron(const CGAL_Polyhedron &p, PolySet &ps); - template bool createPolySetFromPolyhedron(const CGAL::Polyhedron_3 &p, PolySet &ps); - template bool createPolySetFromPolyhedron(const CGAL::Polyhedron_3 &p, PolySet &ps); - template bool createPolySetFromPolyhedron(const CGAL::Polyhedron_3 > &p, PolySet &ps); /* Create a PolySet from a Nef Polyhedron 3. return false on success, diff --git a/src/cgalutils.h b/src/cgalutils.h index 364ff80e..c8eb69db 100644 --- a/src/cgalutils.h +++ b/src/cgalutils.h @@ -21,10 +21,13 @@ namespace CGALUtils { bool is_approximately_convex(const PolySet &ps); Geometry const* applyMinkowski(const Geometry::ChildList &children); - CGAL_Nef_polyhedron *createNefPolyhedronFromGeometry(const class Geometry &geom); template bool createPolySetFromPolyhedron(const Polyhedron &p, PolySet &ps); + template bool createPolyhedronFromPolySet(const PolySet &ps, Polyhedron &p); + template + void copyPolyhedron(const Polyhedron_A &poly_a, Polyhedron_B &poly_b); + + CGAL_Nef_polyhedron *createNefPolyhedronFromGeometry(const class Geometry &geom); bool createPolySetFromNefPolyhedron3(const CGAL_Nef_polyhedron3 &N, PolySet &ps); - bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p); bool tessellatePolygon(const PolygonK &polygon, Polygons &triangles, diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 199faf4d..ca1f58a8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -676,6 +676,7 @@ set(CGAL_SOURCES ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/cgalutils-tess.cc + ../src/cgalutils-polyhedron.cc ../src/cgalutils-tess-old.cc ../src/CGALCache.cc ../src/CGAL_Nef_polyhedron_DxfData.cc From 648b7acc222d35ed910d9c14b32d3726c39e44a4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 31 Dec 2014 13:49:54 -0500 Subject: [PATCH 224/263] Prefix some missing errors with 'ERROR:' to make highlighting work. Fixes #1123 --- src/cgalutils.cc | 12 ++++++------ src/export.cc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index fde80286..535a3ea0 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -86,7 +86,7 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) PRINT("PolySet has nonplanar faces. Attempting alternate construction"); plane_error=true; } else { - PRINTB("CGAL error in CGAL_Nef_polyhedron3(): %s", e.what()); + PRINTB("ERROR: CGAL error in CGAL_Nef_polyhedron3(): %s", e.what()); } } if (plane_error) try { @@ -95,7 +95,7 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) if (!err) N = new CGAL_Nef_polyhedron3(P); } catch (const CGAL::Assertion_exception &e) { - PRINTB("Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s", e.what()); + PRINTB("ERROR: Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s", e.what()); } CGAL::set_error_behaviour(old_behaviour); return new CGAL_Nef_polyhedron(N); @@ -455,7 +455,7 @@ namespace CGALUtils { // union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad and testdata/scad/bugs/issue204.scad catch (const CGAL::Failure_exception &e) { std::string opstr = op == OPENSCAD_INTERSECTION ? "intersection" : op == OPENSCAD_DIFFERENCE ? "difference" : op == OPENSCAD_MINKOWSKI ? "minkowski" : "UNKNOWN"; - PRINTB("CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what()); + PRINTB("ERROR: CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what()); } CGAL::set_error_behaviour(old_behaviour); return N; @@ -505,7 +505,7 @@ namespace CGALUtils { catch (const CGAL::Failure_exception &e) { // union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad and testdata/scad/bugs/issue204.scad std::string opstr = op == OPENSCAD_UNION ? "union" : op == OPENSCAD_INTERSECTION ? "intersection" : op == OPENSCAD_DIFFERENCE ? "difference" : op == OPENSCAD_MINKOWSKI ? "minkowski" : "UNKNOWN"; - PRINTB("CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what()); + PRINTB("ERROR: CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what()); // Errors can result in corrupt polyhedrons, so put back the old one target = src; @@ -593,7 +593,7 @@ namespace CGALUtils { newN.p3.reset(new CGAL_Nef_polyhedron3(nef_bigbox.intersection(*N.p3))); } catch (const CGAL::Failure_exception &e) { - PRINTB("CGAL error in CGALUtils::project during bigbox intersection: %s", e.what()); + PRINTB("ERROR: CGAL error in CGALUtils::project during bigbox intersection: %s", e.what()); } } @@ -621,7 +621,7 @@ namespace CGALUtils { } poly = convertToPolygon2d(*zremover.output_nefpoly2d); } catch (const CGAL::Failure_exception &e) { - PRINTB("CGAL error in CGALUtils::project while flattening: %s", e.what()); + PRINTB("ERROR: CGAL error in CGALUtils::project while flattening: %s", e.what()); } PRINTD(""); diff --git a/src/export.cc b/src/export.cc index 62ff4089..66abedf9 100644 --- a/src/export.cc +++ b/src/export.cc @@ -427,7 +427,7 @@ void export_amf(const CGAL_Nef_polyhedron *root_N, std::ostream &output) << " \r\n" << "\r\n"; } catch (CGAL::Assertion_exception e) { - PRINTB("CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s", e.what()); + PRINTB("ERROR: CGAL error in CGAL_Nef_polyhedron3::convert_to_Polyhedron(): %s", e.what()); } CGAL::set_error_behaviour(old_behaviour); setlocale(LC_NUMERIC, ""); // Set default locale From f139c4b424b7ec230dc644f12b23506ebbfe3abb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 31 Dec 2014 14:45:34 -0500 Subject: [PATCH 225/263] #1097 Test program do decompose an STL into multiple convex STL's and an OpenSCAD model importing them all with different colors --- cgal/data/cubes.stl | 198 +++++++++++++ cgal/decompose.cpp | 667 ++++++++++++++++++++++++++++++++++++++++++++ cgal/decompose.pro | 108 +++++++ 3 files changed, 973 insertions(+) create mode 100644 cgal/data/cubes.stl create mode 100644 cgal/decompose.cpp create mode 100644 cgal/decompose.pro diff --git a/cgal/data/cubes.stl b/cgal/data/cubes.stl new file mode 100644 index 00000000..be040add --- /dev/null +++ b/cgal/data/cubes.stl @@ -0,0 +1,198 @@ +solid OpenSCAD_Model + facet normal -1 0 0 + outer loop + vertex 0 10 0 + vertex 0 0 0 + vertex 0 0 10 + endloop + endfacet + facet normal -1 -0 -0 + outer loop + vertex 0 10 10 + vertex 0 10 0 + vertex 0 0 10 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 0 0 10 + vertex 0 0 0 + vertex 10 0 0 + endloop + endfacet + facet normal -0 -1 -0 + outer loop + vertex 10 0 10 + vertex 0 0 10 + vertex 10 0 0 + endloop + endfacet + facet normal -0 0 -1 + outer loop + vertex 5 10 0 + vertex 0 0 0 + vertex 0 10 0 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 5 15 0 + vertex 15 15 0 + vertex 5 10 0 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex 5 10 0 + vertex 10 5 0 + vertex 0 0 0 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex 15 15 0 + vertex 15 5 0 + vertex 10 5 0 + endloop + endfacet + facet normal 0 -0 -1 + outer loop + vertex 10 5 0 + vertex 10 0 0 + vertex 0 0 0 + endloop + endfacet + facet normal 0 0 -1 + outer loop + vertex 15 15 0 + vertex 10 5 0 + vertex 5 10 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 5 10 0 + vertex 0 10 0 + vertex 0 10 10 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 5 10 10 + vertex 5 10 0 + vertex 0 10 10 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 10 5 10 + vertex 0 0 10 + vertex 10 0 10 + endloop + endfacet + facet normal 0 -0 1 + outer loop + vertex 15 5 10 + vertex 15 15 10 + vertex 10 5 10 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 10 5 10 + vertex 5 10 10 + vertex 0 0 10 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 15 15 10 + vertex 5 15 10 + vertex 5 10 10 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 5 10 10 + vertex 0 10 10 + vertex 0 0 10 + endloop + endfacet + facet normal 0 0 1 + outer loop + vertex 15 15 10 + vertex 5 10 10 + vertex 10 5 10 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 10 0 10 + vertex 10 0 0 + vertex 10 5 0 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 10 5 10 + vertex 10 0 10 + vertex 10 5 0 + endloop + endfacet + facet normal -1 0 0 + outer loop + vertex 5 15 0 + vertex 5 10 0 + vertex 5 10 10 + endloop + endfacet + facet normal -1 -0 -0 + outer loop + vertex 5 15 10 + vertex 5 15 0 + vertex 5 10 10 + endloop + endfacet + facet normal 0 -1 0 + outer loop + vertex 10 5 10 + vertex 10 5 0 + vertex 15 5 0 + endloop + endfacet + facet normal -0 -1 -0 + outer loop + vertex 15 5 10 + vertex 10 5 10 + vertex 15 5 0 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 15 15 0 + vertex 5 15 0 + vertex 5 15 10 + endloop + endfacet + facet normal 0 1 0 + outer loop + vertex 15 15 10 + vertex 15 15 0 + vertex 5 15 10 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 15 5 10 + vertex 15 5 0 + vertex 15 15 0 + endloop + endfacet + facet normal 1 0 0 + outer loop + vertex 15 15 10 + vertex 15 5 10 + vertex 15 15 0 + endloop + endfacet +endsolid OpenSCAD_Model diff --git a/cgal/decompose.cpp b/cgal/decompose.cpp new file mode 100644 index 00000000..8435814b --- /dev/null +++ b/cgal/decompose.cpp @@ -0,0 +1,667 @@ +#include +#include +#include +#include +#include + +#include "cgalutils.h" +#include "export.h" +#include "polyset.h" +#include "CGAL_Nef_polyhedron.h" + +using namespace CGALUtils; + +// Nef polyhedron are using CGAL_Kernel3 (Cartesian) +// Triangulation will use Epick +typedef CGAL::Epick K; +typedef CGAL::Polyhedron_3 PolyhedronK; + +#include +#include +using namespace boost::assign; // bring 'operator+=()' into scope +std::vector colors = boost::assign::list_of + (Color4f(240, 248, 255)) + (Color4f(250, 235, 215)) + (Color4f(0, 255, 255)) + (Color4f(127, 255, 212)) + (Color4f(240, 255, 255)) + (Color4f(245, 245, 220)) + (Color4f(255, 228, 196)) + (Color4f(0, 0, 0)) + (Color4f(255, 235, 205)) + (Color4f(0, 0, 255)) + (Color4f(138, 43, 226)) + (Color4f(165, 42, 42)) + (Color4f(222, 184, 135)) + (Color4f(95, 158, 160)) + (Color4f(127, 255, 0)) + (Color4f(210, 105, 30)) + (Color4f(255, 127, 80)) + (Color4f(100, 149, 237)) + (Color4f(255, 248, 220)) + (Color4f(220, 20, 60)) + (Color4f(0, 255, 255)) + (Color4f(0, 0, 139)) + (Color4f(0, 139, 139)) + (Color4f(184, 134, 11)) + (Color4f(169, 169, 169)) + (Color4f(0, 100, 0)) + (Color4f(169, 169, 169)) + (Color4f(189, 183, 107)) + (Color4f(139, 0, 139)) + (Color4f(85, 107, 47)) + (Color4f(255, 140, 0)) + (Color4f(153, 50, 204)) + (Color4f(139, 0, 0)) + (Color4f(233, 150, 122)) + (Color4f(143, 188, 143)) + (Color4f(72, 61, 139)) + (Color4f(47, 79, 79)) + (Color4f(47, 79, 79)) + (Color4f(0, 206, 209)) + (Color4f(148, 0, 211)) + (Color4f(255, 20, 147)) + (Color4f(0, 191, 255)) + (Color4f(105, 105, 105)) + (Color4f(105, 105, 105)) + (Color4f(30, 144, 255)) + (Color4f(178, 34, 34)) + (Color4f(255, 250, 240)) + (Color4f(34, 139, 34)) + (Color4f(255, 0, 255)) + (Color4f(220, 220, 220)) + (Color4f(248, 248, 255)) + (Color4f(255, 215, 0)) + (Color4f(218, 165, 32)) + (Color4f(128, 128, 128)) + (Color4f(0, 128, 0)) + (Color4f(173, 255, 47)) + (Color4f(128, 128, 128)) + (Color4f(240, 255, 240)) + (Color4f(255, 105, 180)) + (Color4f(205, 92, 92)) + (Color4f(75, 0, 130)) + (Color4f(255, 255, 240)) + (Color4f(240, 230, 140)) + (Color4f(230, 230, 250)) + (Color4f(255, 240, 245)) + (Color4f(124, 252, 0)) + (Color4f(255, 250, 205)) + (Color4f(173, 216, 230)) + (Color4f(240, 128, 128)) + (Color4f(224, 255, 255)) + (Color4f(250, 250, 210)) + (Color4f(211, 211, 211)) + (Color4f(144, 238, 144)) + (Color4f(211, 211, 211)) + (Color4f(255, 182, 193)) + (Color4f(255, 160, 122)) + (Color4f(32, 178, 170)) + (Color4f(135, 206, 250)) + (Color4f(119, 136, 153)) + (Color4f(119, 136, 153)) + (Color4f(176, 196, 222)) + (Color4f(255, 255, 224)) + (Color4f(0, 255, 0)) + (Color4f(50, 205, 50)) + (Color4f(250, 240, 230)) + (Color4f(255, 0, 255)) + (Color4f(128, 0, 0)) + (Color4f(102, 205, 170)) + (Color4f(0, 0, 205)) + (Color4f(186, 85, 211)) + (Color4f(147, 112, 219)) + (Color4f(60, 179, 113)) + (Color4f(123, 104, 238)) + (Color4f(0, 250, 154)) + (Color4f(72, 209, 204)) + (Color4f(199, 21, 133)) + (Color4f(25, 25, 112)) + (Color4f(245, 255, 250)) + (Color4f(255, 228, 225)) + (Color4f(255, 228, 181)) + (Color4f(255, 222, 173)) + (Color4f(0, 0, 128)) + (Color4f(253, 245, 230)) + (Color4f(128, 128, 0)) + (Color4f(107, 142, 35)) + (Color4f(255, 165, 0)) + (Color4f(255, 69, 0)) + (Color4f(218, 112, 214)) + (Color4f(238, 232, 170)) + (Color4f(152, 251, 152)) + (Color4f(175, 238, 238)) + (Color4f(219, 112, 147)) + (Color4f(255, 239, 213)) + (Color4f(255, 218, 185)) + (Color4f(205, 133, 63)) + (Color4f(255, 192, 203)) + (Color4f(221, 160, 221)) + (Color4f(176, 224, 230)) + (Color4f(128, 0, 128)) + (Color4f(255, 0, 0)) + (Color4f(188, 143, 143)) + (Color4f(65, 105, 225)) + (Color4f(139, 69, 19)) + (Color4f(250, 128, 114)) + (Color4f(244, 164, 96)) + (Color4f(46, 139, 87)) + (Color4f(255, 245, 238)) + (Color4f(160, 82, 45)) + (Color4f(192, 192, 192)) + (Color4f(135, 206, 235)) + (Color4f(106, 90, 205)) + (Color4f(112, 128, 144)) + (Color4f(112, 128, 144)) + (Color4f(255, 250, 250)) + (Color4f(0, 255, 127)) + (Color4f(70, 130, 180)) + (Color4f(210, 180, 140)) + (Color4f(0, 128, 128)) + (Color4f(216, 191, 216)) + (Color4f(255, 99, 71)) + (Color4f(0, 0, 0, 0)) + (Color4f(64, 224, 208)) + (Color4f(238, 130, 238)) + (Color4f(245, 222, 179)) + (Color4f(255, 255, 255)) + (Color4f(245, 245, 245)) + (Color4f(255, 255, 0)) + (Color4f(154, 205, 50)); + +#include +#include +template +bool is_weakly_convex(Polyhedron const& p) { + for (typename Polyhedron::Edge_const_iterator i = p.edges_begin(); i != p.edges_end(); ++i) { + typename Polyhedron::Plane_3 p(i->opposite()->vertex()->point(), i->vertex()->point(), i->next()->vertex()->point()); + if (p.has_on_positive_side(i->opposite()->next()->vertex()->point()) && + CGAL::squared_distance(p, i->opposite()->next()->vertex()->point()) > 1e-8) { + return false; + } + } + // Also make sure that there is only one shell: + boost::unordered_set visited; + // c++11 + // visited.reserve(p.size_of_facets()); + + std::queue to_explore; + to_explore.push(p.facets_begin()); // One arbitrary facet + visited.insert(to_explore.front()); + + while (!to_explore.empty()) { + typename Polyhedron::Facet_const_handle f = to_explore.front(); + to_explore.pop(); + typename Polyhedron::Facet::Halfedge_around_facet_const_circulator he, end; + end = he = f->facet_begin(); + CGAL_For_all(he,end) { + typename Polyhedron::Facet_const_handle o = he->opposite()->facet(); + + if (!visited.count(o)) { + visited.insert(o); + to_explore.push(o); + } + } + } + + return visited.size() == p.size_of_facets(); +} + +class Shell_explorer +{ +public: + std::vector vertices; + + Shell_explorer() {} + void visit(CGAL_Nef_polyhedron3::Vertex_const_handle v) { + vertices.push_back(K::Point_3(to_double(v->point()[0]), + to_double(v->point()[1]), + to_double(v->point()[2]))); + } + void visit(CGAL_Nef_polyhedron3::Halfedge_const_handle ) {} + void visit(CGAL_Nef_polyhedron3::Halffacet_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 ) {} +}; + +template +void decompose(const CGAL_Nef_polyhedron3 *N, Output out_iter) +{ + int parts = 0; + assert(N); + CGAL_Polyhedron poly; + if (N->is_simple()) { + nefworkaround::convert_to_Polyhedron(*N, poly); + } + if (is_weakly_convex(poly)) { + PRINTD("Minkowski: Object is convex and Nef"); + PolyhedronK poly2; + CGALUtils::copyPolyhedron(poly, poly2); + *out_iter++ = poly2; + return; + } + else { + PRINTD("Minkowski: Object is nonconvex Nef, decomposing..."); + CGAL_Nef_polyhedron3 decomposed_nef = *N; + CGAL::convex_decomposition_3(decomposed_nef); + + // the first volume is the outer volume, which ignored in the decomposition + CGAL_Nef_polyhedron3::Volume_const_iterator ci = ++decomposed_nef.volumes_begin(); + // Convert each convex volume to a Polyhedron + for(; ci != decomposed_nef.volumes_end(); ++ci) { + if(ci->mark()) { + // CGAL_Polyhedron poly; + // decomposed_nef.convert_inner_shell_to_polyhedron(ci->shells_begin(), poly); + // P.push_back(poly); + + + auto s = CGAL_Nef_polyhedron3::SFace_const_handle(ci->shells_begin()); + + CGAL_Nef_polyhedron3::SFace_const_iterator sf = ci->shells_begin(); + Shell_explorer SE; + decomposed_nef.visit_shell_objects(CGAL_Nef_polyhedron3::SFace_const_handle(sf),SE); + + PolyhedronK poly; + CGAL::convex_hull_3(SE.vertices.begin(), SE.vertices.end(), poly); + *out_iter++ = poly; + parts++; + } + } + + PRINTDB("Minkowski: decomposed into %d convex parts", parts); + } +} + +Geometry const * minkowskitest(const Geometry::ChildList &children) +{ + CGAL::Timer t,t_tot; + assert(children.size() >= 2); + // Iterate over children, perform pairwise minkowski on children: + // operands = [ch, ch+1] + Geometry::ChildList::const_iterator minkowski_ch_it = children.begin(); + t_tot.start(); + Geometry const *operands[2] = {minkowski_ch_it->second.get(), NULL}; + try { + while (++minkowski_ch_it != children.end()) { + operands[1] = minkowski_ch_it->second.get(); + + std::vector convexP[2]; // Stores decomposed operands + std::list result_parts; + + for (int i = 0; i < 2; i++) { + shared_ptr N; + if (const PolySet *ps = dynamic_cast(operands[i])) { + if (ps->is_convex()) { + PRINTDB("Minkowski: child %d is convex and PolySet", i); + PolyhedronK poly; + CGALUtils::createPolyhedronFromPolySet(*ps, poly); + convexP[i].push_back(poly); + } + else { + PRINTDB("Minkowski: child %d is nonconvex PolySet, transforming to Nef", i); + N.reset(createNefPolyhedronFromGeometry(*ps)); + } + } + else if (const CGAL_Nef_polyhedron *n = dynamic_cast(operands[i])) { + CGAL_Polyhedron poly; + if (n->p3->is_simple()) { + nefworkaround::convert_to_Polyhedron(*n->p3, poly); + // FIXME: Can we calculate weakly_convex on a PolyhedronK instead? + if (is_weakly_convex(poly)) { + PRINTDB("Minkowski: child %d is convex and Nef", i); + PolyhedronK poly2; + CGALUtils::copyPolyhedron(poly, poly2); + convexP[i].push_back(poly2); + } + else { + PRINTDB("Minkowski: child %d is nonconvex Nef",i); + N.reset(n); + } + } + else throw 0; // We cannot handle this, fall back to CGAL's minkowski + } + + // If not convex... + if (N && N->p3) { + PRINTD("Decomposing..."); + decompose(N->p3.get(), std::back_inserter(convexP[i])); + } + + PRINTD("Hulling convex parts..."); + std::vector points[2]; + std::vector minkowski_points; + + // For each permutation of convex operands.. + BOOST_FOREACH(const PolyhedronK &p0, convexP[0]) { + BOOST_FOREACH(const PolyhedronK &p1, convexP[1]) { + t.start(); + + // Create minkowski pointcloud + minkowski_points.clear(); + minkowski_points.reserve(p0.size_of_vertices() * p0.size_of_vertices()); + BOOST_FOREACH(const K::Point_3 &p0p, std::make_pair(p0.points_begin(), p0.points_end())) { + BOOST_FOREACH(const K::Point_3 &p1p, std::make_pair(p1.points_begin(), p1.points_end())) { + minkowski_points.push_back(p0p+(p1p-CGAL::ORIGIN)); + } + } + + t.stop(); + + // Ignore empty volumes + if (minkowski_points.size() <= 3) continue; + + // Hull point cloud + PolyhedronK result; + PRINTDB("Minkowski: Point cloud creation (%d ⨉ %d -> %d) took %f ms", + points[0].size() % points[1].size() % minkowski_points.size() % (t.time()*1000)); + t.reset(); + t.start(); + CGAL::convex_hull_3(minkowski_points.begin(), minkowski_points.end(), result); + + std::vector strict_points; + strict_points.reserve(minkowski_points.size()); + + for (PolyhedronK::Vertex_iterator i = result.vertices_begin(); i != result.vertices_end(); ++i) { + K::Point_3 const &p = i->point(); + + PolyhedronK::Vertex::Halfedge_handle h,e; + h = i->halfedge(); + e = h; + bool collinear = false; + bool coplanar = true; + + do { + K::Point_3 const& q = h->opposite()->vertex()->point(); + if (coplanar && !CGAL::coplanar(p,q, + h->next_on_vertex()->opposite()->vertex()->point(), + h->next_on_vertex()->next_on_vertex()->opposite()->vertex()->point())) { + coplanar = false; + } + + + for (PolyhedronK::Vertex::Halfedge_handle j = h->next_on_vertex(); + j != h && !collinear && ! coplanar; + j = j->next_on_vertex()) { + + K::Point_3 const& r = j->opposite()->vertex()->point(); + if (CGAL::collinear(p,q,r)) { + collinear = true; + } + } + + h = h->next_on_vertex(); + } while (h != e && !collinear); + + if (!collinear && !coplanar) strict_points.push_back(p); + } + + result.clear(); + CGAL::convex_hull_3(strict_points.begin(), strict_points.end(), result); + + t.stop(); + PRINTDB("Minkowski: Computing convex hull took %f s", t.time()); + t.reset(); + + result_parts.push_back(result); + } + } + } + + if (minkowski_ch_it != boost::next(children.begin())) delete operands[0]; + + if (result_parts.size() == 1) { + PolySet *ps = new PolySet(3,true); + createPolySetFromPolyhedron(*result_parts.begin(), *ps); + operands[0] = ps; + } else if (!result_parts.empty()) { + t.start(); + PRINTDB("Minkowski: Computing union of %d parts",result_parts.size()); + Geometry::ChildList fake_children; + for (std::list::iterator i = result_parts.begin(); i != result_parts.end(); ++i) { + PolySet ps(3,true); + createPolySetFromPolyhedron(*i, ps); + fake_children.push_back(std::make_pair((const AbstractNode*)NULL, + shared_ptr(createNefPolyhedronFromGeometry(ps)))); + } + CGAL_Nef_polyhedron *N = CGALUtils::applyOperator(fake_children, OPENSCAD_UNION); + t.stop(); + if (N) PRINTDB("Minkowski: Union done: %f s",t.time()); + else PRINTDB("Minkowski: Union failed: %f s",t.time()); + t.reset(); + operands[0] = N; + } else { + operands[0] = new CGAL_Nef_polyhedron(); + } + } + + t_tot.stop(); + PRINTDB("Minkowski: Total execution time %f s", t_tot.time()); + t_tot.reset(); + return operands[0]; + } + catch (...) { + // If anything throws we simply fall back to Nef Minkowski + PRINTD("Minkowski: Falling back to Nef Minkowski"); + + CGAL_Nef_polyhedron *N = applyOperator(children, OPENSCAD_MINKOWSKI); + return N; + } +} + +#define STL_FACET_NUMBYTES 4*3*4+2 +// as there is no 'float32_t' standard, we assume the systems 'float' +// is a 'binary32' aka 'single' standard IEEE 32-bit floating point type +union stl_facet { + uint8_t data8[ STL_FACET_NUMBYTES ]; + uint32_t data32[4*3]; + struct facet_data { + float i, j, k; + float x1, y1, z1; + float x2, y2, z2; + float x3, y3, z3; + uint16_t attribute_byte_count; + } data; +}; + +void uint32_byte_swap( uint32_t &x ) +{ +#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 + x = __builtin_bswap32( x ); +#elif defined(__clang__) + x = __builtin_bswap32( x ); +#elif defined(_MSC_VER) + x = _byteswap_ulong( x ); +#else + uint32_t b1 = ( 0x000000FF & x ) << 24; + uint32_t b2 = ( 0x0000FF00 & x ) << 8; + uint32_t b3 = ( 0x00FF0000 & x ) >> 8; + uint32_t b4 = ( 0xFF000000 & x ) >> 24; + x = b1 | b2 | b3 | b4; +#endif +} + +void read_stl_facet( std::ifstream &f, stl_facet &facet ) +{ + f.read( (char*)facet.data8, STL_FACET_NUMBYTES ); +#ifdef BOOST_BIG_ENDIAN + for ( int i = 0; i < 12; i++ ) { + uint32_byte_swap( facet.data32[ i ] ); + } + // we ignore attribute byte count +#endif +} + +PolySet *import_stl(const std::string &filename) +{ + PolySet *p = new PolySet(3); + + // Open file and position at the end + std::ifstream f(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + if (!f.good()) { + PRINTB("WARNING: Can't open import file '%s'.", filename); + return NULL; + } + + boost::regex ex_sfe("solid|facet|endloop"); + boost::regex ex_outer("outer loop"); + boost::regex ex_vertex("vertex"); + boost::regex ex_vertices("\\s*vertex\\s+([^\\s]+)\\s+([^\\s]+)\\s+([^\\s]+)"); + + bool binary = false; + std::streampos file_size = f.tellg(); + f.seekg(80); + if (f.good() && !f.eof()) { + uint32_t facenum = 0; + f.read((char *)&facenum, sizeof(uint32_t)); +#ifdef BOOST_BIG_ENDIAN + uint32_byte_swap( facenum ); +#endif + if (file_size == static_cast(80 + 4 + 50*facenum)) { + binary = true; + } + } + f.seekg(0); + + char data[5]; + f.read(data, 5); + if (!binary && !f.eof() && f.good() && !memcmp(data, "solid", 5)) { + int i = 0; + double vdata[3][3]; + std::string line; + std::getline(f, line); + while (!f.eof()) { + std::getline(f, line); + boost::trim(line); + if (boost::regex_search(line, ex_sfe)) { + continue; + } + if (boost::regex_search(line, ex_outer)) { + i = 0; + continue; + } + boost::smatch results; + if (boost::regex_search(line, results, ex_vertices)) { + try { + for (int v=0;v<3;v++) { + vdata[i][v] = boost::lexical_cast(results[v+1]); + } + } + catch (const boost::bad_lexical_cast &blc) { + PRINTB("WARNING: Can't parse vertex line '%s'.", line); + i = 10; + continue; + } + if (++i == 3) { + p->append_poly(); + p->append_vertex(vdata[0][0], vdata[0][1], vdata[0][2]); + p->append_vertex(vdata[1][0], vdata[1][1], vdata[1][2]); + p->append_vertex(vdata[2][0], vdata[2][1], vdata[2][2]); + } + } + } + } + else if (binary && !f.eof() && f.good()) + { + f.ignore(80-5+4); + while (1) { + stl_facet facet; + read_stl_facet( f, facet ); + if (f.eof()) break; + p->append_poly(); + p->append_vertex(facet.data.x1, facet.data.y1, facet.data.z1); + p->append_vertex(facet.data.x2, facet.data.y2, facet.data.z2); + p->append_vertex(facet.data.x3, facet.data.y3, facet.data.z3); + } + } + return p; +} + +/*! + file format: + 1. polygon coordinates (x,y,z) are comma separated (+/- spaces) and + each coordinate is on a separate line + 2. each polygon is separated by one or more blank lines +*/ +bool import_polygon(PolyholeK &polyhole, const std::string &filename) +{ + std::ifstream ifs(filename.c_str()); + if (!ifs) return false; + + std::string line; + PolygonK polygon; + while (std::getline(ifs, line)) { + std::stringstream ss(line); + double X = 0.0, Y = 0.0, Z = 0.0; + if (!(ss >> X)) { + //ie blank lines => flag start of next polygon + if (polygon.size() > 0) polyhole.push_back(polygon); + polygon.clear(); + continue; + } + char c = ss.peek(); + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces before comma + if (c == ',') {ss.read(&c, 1); c = ss.peek();} //gobble comma + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces after comma + if (!(ss >> Y)) { + std::cerr << "Y error\n"; + return false; + } + c = ss.peek(); + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces before comma + if (c == ',') {ss.read(&c, 1); c = ss.peek();} //gobble comma + while (c == ' ') {ss.read(&c, 1); c = ss.peek();} //gobble spaces after comma + if (!(ss >> Z)) { + std::cerr << "Z error\n"; + return false; + } + polygon.push_back(Vertex3K(X, Y, Z)); + } + if (polygon.size() > 0) polyhole.push_back(polygon); + ifs.close(); + return true; +} +//------------------------------------------------------------------------------ + +int main(int argc, char *argv[]) +{ + + OpenSCAD::debug = "decompose"; + + PolySet *ps = NULL; + if (argc == 2) { + if (!(ps = import_stl(argv[1]))) { + std::cerr << "Error importing STL " << argv[1] << std::endl; + exit(1); + } + std::cerr << "Imported " << ps->numPolygons() << " polygons" << std::endl; + } + else { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + exit(1); + } + + Geometry::ChildList children; + + CGAL_Nef_polyhedron *N = createNefPolyhedronFromGeometry(*ps); + + std::vector result; + decompose(N->p3.get(), std::back_inserter(result)); + + std::cerr << "Decomposed into " << result.size() << " convex parts" << std::endl; + + int idx = 0; + BOOST_FOREACH(const PolyhedronK &P, result) { + PolySet result_ps(3); + if (CGALUtils::createPolySetFromPolyhedron(P, result_ps)) { + std::cerr << "Error converting to PolySet\n"; + } + else { + std::stringstream ss; + ss << "out" << idx++ << ".stl"; + exportFileByName(&result_ps, OPENSCAD_STL, ss.str().c_str(), ss.str().c_str()); + std::cout << "color([" << colors[idx%147][0] << "," << colors[idx%147][1] << "," << colors[idx%147][2] << "]) " << "import(\"" << ss.str() << "\");\n"; + } + } + std::cerr << "Done." << std::endl; +} diff --git a/cgal/decompose.pro b/cgal/decompose.pro new file mode 100644 index 00000000..83b2b0a5 --- /dev/null +++ b/cgal/decompose.pro @@ -0,0 +1,108 @@ +CONFIG += debug +CONFIG -= qt +debug: DEFINES += DEBUG + +TEMPLATE = app + +INCLUDEPATH += ../src +DEPENDPATH += ../src + +# Handle custom library location. +# Used when manually installing 3rd party libraries +isEmpty(OPENSCAD_LIBDIR) OPENSCAD_LIBDIR = $$(OPENSCAD_LIBRARIES) +macx:isEmpty(OPENSCAD_LIBDIR) { + exists(/opt/local):exists(/usr/local/Cellar) { + error("It seems you might have libraries in both /opt/local and /usr/local. Please specify which one to use with qmake OPENSCAD_LIBDIR=") + } else { + exists(/opt/local) { + #Default to MacPorts on Mac OS X + message("Automatically searching for libraries in /opt/local. To override, use qmake OPENSCAD_LIBDIR=") + OPENSCAD_LIBDIR = /opt/local + } else:exists(/usr/local/Cellar) { + message("Automatically searching for libraries in /usr/local. To override, use qmake OPENSCAD_LIBDIR=") + OPENSCAD_LIBDIR = /usr/local + } + } +} +!isEmpty(OPENSCAD_LIBDIR) { + QMAKE_INCDIR = $$OPENSCAD_LIBDIR/include + QMAKE_LIBDIR = $$OPENSCAD_LIBDIR/lib +} + +TARGET = decompose +mac { + CONFIG -= app_bundle +} + +macx { + # Mac needs special care to link against the correct C++ library + # We attempt to auto-detect it by inspecting Boost + dirs = $${BOOSTDIR} $${QMAKE_LIBDIR} + for(dir, dirs) { + system(grep -q __112basic_string $${dir}/libboost_thread* >& /dev/null) { + message("Detected libc++-linked boost in $${dir}") + CONFIG += libc++ + } + } + + libc++ { + QMAKE_CXXFLAGS += -stdlib=libc++ + QMAKE_LFLAGS += -stdlib=libc++ + QMAKE_OBJECTIVE_CFLAGS += -stdlib=libc++ + # libc++ on requires Mac OS X 10.7+ + QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 + } +} + +# See Dec 2011 OpenSCAD mailing list, re: CGAL/GCC bugs. +*g++* { + QMAKE_CXXFLAGS *= -fno-strict-aliasing + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-local-typedefs # ignored before 4.8 +} + +*clang* { + # http://llvm.org/bugs/show_bug.cgi?id=9182 + QMAKE_CXXFLAGS_WARN_ON += -Wno-overloaded-virtual + # disable enormous amount of warnings about CGAL / boost / etc + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-variable + QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-function + QMAKE_CXXFLAGS_WARN_ON += -Wno-c++11-extensions + # might want to actually turn this on once in a while + QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-compare +} + +# Application configuration +CONFIG += cgal +CONFIG += boost +CONFIG += eigen +CONFIG += gettext + +mac: { + LIBS += -framework OpenGL +} + +include(../common.pri) + +HEADERS += ../src/cgal.h \ + ../src/cgalutils.h \ + ../src/linalg.h \ + ../src/polyset.h \ + ../src/polyset-utils.h \ + ../src/printutils.h + +SOURCES += decompose.cpp \ + ../src/polygon2d.cc \ + ../src/polygon2d-CGAL.cc \ + ../src/CGAL_Nef_polyhedron.cc \ + ../src/CGAL_Nef_polyhedron_DxfData.cc \ + ../src/cgalutils.cc \ + ../src/cgalutils-tess.cc \ + ../src/cgalutils-polyhedron.cc \ + ../src/polyset.cc \ + ../src/svg.cc \ + ../src/node.cc \ + ../src/export.cc \ + ../src/polyset-utils.cc \ + ../src/progress.cc \ + ../src/printutils.cc From 6fc720d1b7b0b6c8530288f96281faaabf34d203 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 31 Dec 2014 15:02:20 -0500 Subject: [PATCH 226/263] Bumped Eigen to 3.2.2 --- scripts/macosx-build-dependencies.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index 86bb3c7b..6b7ac3fb 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -450,6 +450,7 @@ build_eigen() elif [ $version = "3.1.4" ]; then EIGENDIR=eigen-eigen-36bf2ceaf8f5; elif [ $version = "3.2.0" ]; then EIGENDIR=eigen-eigen-ffa86ffb5570; elif [ $version = "3.2.1" ]; then EIGENDIR=eigen-eigen-6b38706d90a9; + elif [ $version = "3.2.2" ]; then EIGENDIR=eigen-eigen-1306d75b4a21; fi if [ $EIGENDIR = "none" ]; then @@ -773,7 +774,7 @@ mkdir -p $SRCDIR $DEPLOYDIR build_qt5 5.3.2 build_qscintilla 2.8.4 # NB! For eigen, also update the path in the function -build_eigen 3.2.1 +build_eigen 3.2.2 build_gmp 5.1.3 build_mpfr 3.1.2 build_boost 1.54.0 From 743732d8744b7dd23783d19cbd8bceb46afd61e5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 31 Dec 2014 15:31:27 -0500 Subject: [PATCH 227/263] Fix bug in harfbuzz build causing us to require OS X 10.9+ --- scripts/macosx-build-dependencies.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index 6b7ac3fb..bdb8a619 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -687,7 +687,7 @@ build_harfbuzz() # disable doc directories as they make problems on Mac OS Build sed -e "s/SUBDIRS = src util test docs/SUBDIRS = src util test/g" Makefile.am > Makefile.am.bak && mv Makefile.am.bak Makefile.am sed -e "s/^docs.*$//" configure.ac > configure.ac.bak && mv configure.ac.bak configure.ac - PKG_CONFIG_LIBDIR="$DEPLOYDIR/lib/pkgconfig" ./autogen.sh --prefix="$DEPLOYDIR" --with-freetype=yes --with-gobject=no --with-cairo=no --with-icu=no CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN LDFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN $extra_config_flags + PKG_CONFIG_LIBDIR="$DEPLOYDIR/lib/pkgconfig" ./autogen.sh --prefix="$DEPLOYDIR" --with-freetype=yes --with-gobject=no --with-cairo=no --with-icu=no CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN CXXFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN LDFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN $extra_config_flags make -j$NUMCPU make install } @@ -787,7 +787,7 @@ build_glib2 2.40.0 build_opencsg 1.4.0 build_freetype 2.5.4 --without-png build_ragel 6.9 -build_harfbuzz 0.9.35 "--with-coretext=auto --with-glib=no" +build_harfbuzz 0.9.37 "--with-coretext=auto --with-glib=no" export FREETYPE_CFLAGS="-I$DEPLOYDIR/include -I$DEPLOYDIR/include/freetype2" export FREETYPE_LIBS="-L$DEPLOYDIR/lib -lfreetype" build_libxml2 2.9.1 From f10d0c5d5f92477460e9376a6751ccb5f99f55d5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Jan 2015 22:50:58 -0500 Subject: [PATCH 228/263] #1129 Added testcase for empty projection crash --- testdata/scad/2D/features/projection-cut-tests.scad | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testdata/scad/2D/features/projection-cut-tests.scad b/testdata/scad/2D/features/projection-cut-tests.scad index 99e7fd37..51af9120 100644 --- a/testdata/scad/2D/features/projection-cut-tests.scad +++ b/testdata/scad/2D/features/projection-cut-tests.scad @@ -6,6 +6,9 @@ projection(cut=true) translate([20,0,0]) cube(10, center=true); // Boundary case: clipping the top of a cube translate([0,20,0]) projection(cut=true) translate([0,0,-4.999999]) cube(10, center=true); +// Empty cut +projection(cut=true) !translate([0,0,5]) cube(5, center=true); + // holes translate([0,-10,0]) projection(cut=true) { union() { From b68ac5e6f2a42394f078f21bce580d2d796e430f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Jan 2015 22:54:09 -0500 Subject: [PATCH 229/263] fixed typo in last commit --- testdata/scad/2D/features/projection-cut-tests.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/scad/2D/features/projection-cut-tests.scad b/testdata/scad/2D/features/projection-cut-tests.scad index 51af9120..59898551 100644 --- a/testdata/scad/2D/features/projection-cut-tests.scad +++ b/testdata/scad/2D/features/projection-cut-tests.scad @@ -7,7 +7,7 @@ projection(cut=true) translate([20,0,0]) cube(10, center=true); translate([0,20,0]) projection(cut=true) translate([0,0,-4.999999]) cube(10, center=true); // Empty cut -projection(cut=true) !translate([0,0,5]) cube(5, center=true); +projection(cut=true) translate([0,0,5]) cube(5, center=true); // holes translate([0,-10,0]) projection(cut=true) { From 09e7bfc96dce9173b531d31a51fe1e00196f19c9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 1 Jan 2015 23:01:09 -0500 Subject: [PATCH 230/263] #1129 Fixed crash when performing empty projection --- src/GeometryEvaluator.cc | 7 ++++--- .../regression/dumptest/projection-cut-tests-expected.csg | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 719c6ed7..72490314 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -953,9 +953,10 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node) } if (!Nptr->isEmpty()) { Polygon2d *poly = CGALUtils::project(*Nptr, node.cut_mode); - assert(poly); - poly->setConvexity(node.convexity); - geom.reset(poly); + if (poly) { + poly->setConvexity(node.convexity); + geom.reset(poly); + } } } } diff --git a/tests/regression/dumptest/projection-cut-tests-expected.csg b/tests/regression/dumptest/projection-cut-tests-expected.csg index 5ee575af..fde98f48 100644 --- a/tests/regression/dumptest/projection-cut-tests-expected.csg +++ b/tests/regression/dumptest/projection-cut-tests-expected.csg @@ -14,6 +14,11 @@ group() { } } } + projection(cut = true, convexity = 0) { + multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 5], [0, 0, 0, 1]]) { + cube(size = [5, 5, 5], center = true); + } + } multmatrix([[1, 0, 0, 0], [0, 1, 0, -10], [0, 0, 1, 0], [0, 0, 0, 1]]) { projection(cut = true, convexity = 0) { union() { From 7cefaa730024d794feeeb023f9d14c1b9855478b Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sat, 3 Jan 2015 19:28:42 +0100 Subject: [PATCH 231/263] Drop setting the WhitespaceBackgroundColor. QScintilla uses this color even when the whitespace is selected instead of drawing it in the selection background color. This causes selection to look strange when the whitespace display is enabled. --- color-schemes/editor/dark-background.json | 1 - color-schemes/editor/light-background.json | 1 - color-schemes/editor/monokai.json | 1 - color-schemes/editor/solarized-dark.json | 1 - color-schemes/editor/solarized-light.json | 1 - color-schemes/editor/tomorrow-night.json | 1 - color-schemes/editor/tomorrow.json | 1 - color-schemes/editor/visualstudio.json | 1 - src/scintillaeditor.cpp | 1 - 9 files changed, 9 deletions(-) diff --git a/color-schemes/editor/dark-background.json b/color-schemes/editor/dark-background.json index 7ae0857e..2c199fcc 100644 --- a/color-schemes/editor/dark-background.json +++ b/color-schemes/editor/dark-background.json @@ -19,7 +19,6 @@ "number" : "#ff0000", "string" : "#e6db74", "operator" : "#e8b609", - "whitespace-background" : "#222222", "whitespace-foreground" : "#e0e0e0", "selection-foreground" : "#ffffff", "selection-background" : "#4a90d9", diff --git a/color-schemes/editor/light-background.json b/color-schemes/editor/light-background.json index f80e735e..2c0ffb30 100644 --- a/color-schemes/editor/light-background.json +++ b/color-schemes/editor/light-background.json @@ -19,7 +19,6 @@ "number" : "DarkRed", "string" : "DarkMagenta", "operator" : "Blue", - "whitespace-background" : "#ffffff", "whitespace-foreground" : "#272822", "selection-foreground" : "#ffffff", "selection-background" : "#4a90d9", diff --git a/color-schemes/editor/monokai.json b/color-schemes/editor/monokai.json index b4c74451..8ddac03c 100644 --- a/color-schemes/editor/monokai.json +++ b/color-schemes/editor/monokai.json @@ -19,7 +19,6 @@ "number" : "#ae81ff", "string" : "#e6db74", "operator" : "#f8f8f2", - "whitespace-background" : "#272822", "whitespace-foreground" : "#f8f8f2", "selection-foreground" : "#272822", "selection-background" : "#f8f8f2", diff --git a/color-schemes/editor/solarized-dark.json b/color-schemes/editor/solarized-dark.json index e6ad36df..73d369fb 100644 --- a/color-schemes/editor/solarized-dark.json +++ b/color-schemes/editor/solarized-dark.json @@ -19,7 +19,6 @@ "number" : "#d33682", "string" : "#b58900", "operator" : "#cb4b16", - "whitespace-background" : "#002b36", "whitespace-foreground" : "#839496", "selection-foreground" : "#fdf6e3", "selection-background" : "#657b83", diff --git a/color-schemes/editor/solarized-light.json b/color-schemes/editor/solarized-light.json index 40f5203f..d99bcbcd 100644 --- a/color-schemes/editor/solarized-light.json +++ b/color-schemes/editor/solarized-light.json @@ -19,7 +19,6 @@ "number" : "#d33682", "string" : "#b58900", "operator" : "#cb4b16", - "whitespace-background" : "#fdf6e3", "whitespace-foreground" : "#657b83", "selection-foreground" : "#fdf6e3", "selection-background" : "#657b83", diff --git a/color-schemes/editor/tomorrow-night.json b/color-schemes/editor/tomorrow-night.json index 529fc910..69199850 100644 --- a/color-schemes/editor/tomorrow-night.json +++ b/color-schemes/editor/tomorrow-night.json @@ -19,7 +19,6 @@ "number" : "#cc6666", "string" : "#b5bd68", "operator" : "#8abeb7", - "whitespace-background" : "#1d1f21", "whitespace-foreground" : "#c5c8c6", "selection-foreground" : "#373b41", "selection-background" : "#c5c8c6", diff --git a/color-schemes/editor/tomorrow.json b/color-schemes/editor/tomorrow.json index 71d2e4f1..d3cef5f4 100644 --- a/color-schemes/editor/tomorrow.json +++ b/color-schemes/editor/tomorrow.json @@ -19,7 +19,6 @@ "number" : "#c82829", "string" : "#718c00", "operator" : "#3e999f", - "whitespace-background" : "#f8f8f8", "whitespace-foreground" : "#4d4d4c", "selection-foreground" : "#4d4d4c", "selection-background" : "#d6d6d6", diff --git a/color-schemes/editor/visualstudio.json b/color-schemes/editor/visualstudio.json index aeab6b70..9a1da1b1 100644 --- a/color-schemes/editor/visualstudio.json +++ b/color-schemes/editor/visualstudio.json @@ -19,7 +19,6 @@ "number" : "DarkRed", "string" : "#A31515", "operator" : "Blue", - "whitespace-background" : "#ffffff", "whitespace-foreground" : "#101010", "selection-foreground" : "black", "selection-background" : "lightblue", diff --git a/src/scintillaeditor.cpp b/src/scintillaeditor.cpp index 88836747..43f36f01 100644 --- a/src/scintillaeditor.cpp +++ b/src/scintillaeditor.cpp @@ -304,7 +304,6 @@ void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme) qsci->setMarkerBackgroundColor(readColor(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber); qsci->setIndicatorForegroundColor(readColor(colors, "error-indicator", QColor(255, 0, 0, 100)), indicatorNumber); qsci->setIndicatorOutlineColor(readColor(colors, "error-indicator-outline", QColor(255, 0, 0, 100)), indicatorNumber); - qsci->setWhitespaceBackgroundColor(readColor(colors, "whitespace-background", paperColor)); qsci->setWhitespaceForegroundColor(readColor(colors, "whitespace-foreground", textColor)); qsci->setMarginsBackgroundColor(readColor(colors, "margin-background", paperColor)); qsci->setMarginsForegroundColor(readColor(colors, "margin-foreground", textColor)); From d997226f3ca95fdc969f464b381fda5c949b818e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 3 Jan 2015 16:43:28 -0500 Subject: [PATCH 232/263] #1089 Provide error message instead of crashing hard on CGAL hull exceptions --- src/cgalutils.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 535a3ea0..98d61af8 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -140,14 +140,17 @@ namespace CGALUtils { // Apply hull if (points.size() >= 4) { - CGAL::Polyhedron_3 r; - CGAL::convex_hull_3(points.begin(), points.end(), r); - if (!createPolySetFromPolyhedron(r, result)) - return true; - return false; - } else { - return false; + CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); + try { + CGAL::Polyhedron_3 r; + CGAL::convex_hull_3(points.begin(), points.end(), r); + if (!createPolySetFromPolyhedron(r, result)) return true; + } + catch (const CGAL::Assertion_exception &e) { + PRINTB("ERROR: CGAL error in applyHull(): %s", e.what()); + } } + return false; } template From 0e20a7cb17644f9aaa0729c29b14ac631bfb1a9c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Wed, 31 Dec 2014 22:54:02 +0100 Subject: [PATCH 233/263] Remove border from SVG viewport to fix scaling issues (fixes #1122). --- src/export.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/export.cc b/src/export.cc index 66abedf9..81c2c933 100644 --- a/src/export.cc +++ b/src/export.cc @@ -505,11 +505,15 @@ void export_svg(const Polygon2d &poly, std::ostream &output) int miny = floor(-bbox.max().y()); int maxx = ceil(bbox.max().x()); int maxy = ceil(-bbox.min().y()); - + + int width = maxx - minx; + int height = maxy - miny; output << "\n" << "\n" - << "\n" + << "\n" << "OpenSCAD Model\n"; output << " Date: Sun, 4 Jan 2015 16:50:37 +0100 Subject: [PATCH 234/263] Use correct eye position in orthogonal projection mode (fixes #1058). --- src/Camera.cc | 20 +++----------------- src/GLView.cc | 11 +++++++---- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/Camera.cc b/src/Camera.cc index 29ecc013..479c1d0c 100644 --- a/src/Camera.cc +++ b/src/Camera.cc @@ -101,25 +101,11 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor) void Camera::zoom(int delta) { - if (this->projection == PERSPECTIVE) { - this->viewer_distance *= pow(0.9, delta / 120.0); - } - else { - this->height *= pow(0.9, delta / 120.0); - } + this->viewer_distance *= pow(0.9, delta / 120.0); + this->height = this->viewer_distance; } void Camera::setProjection(ProjectionType type) { - if (this->projection != type) { - switch (type) { - case PERSPECTIVE: - this->viewer_distance = this->height; - break; - case ORTHOGONAL: - this->height = this->viewer_distance; - break; - } - this->projection = type; - } + this->projection = type; } diff --git a/src/GLView.cc b/src/GLView.cc index 4baa38ab..af4e4e11 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -91,21 +91,23 @@ void GLView::setupCamera() glLoadIdentity(); switch (this->cam.type) { - case Camera::GIMBAL: + case Camera::GIMBAL: { + double eyeY = 0.0; switch (this->cam.projection) { case Camera::PERSPECTIVE: { - double dist = cam.viewer_distance; - gluPerspective(cam.fov, aspectratio, 0.1*dist, 100*dist); + eyeY = cam.viewer_distance; + gluPerspective(cam.fov, aspectratio, 0.1 * eyeY, 100 * eyeY); break; } case Camera::ORTHOGONAL: { + eyeY = cam.height; glOrtho(-cam.height/2*aspectratio, cam.height*aspectratio/2, -cam.height/2, cam.height/2, -far_far_away, +far_far_away); break; } } - gluLookAt(0.0, -cam.viewer_distance, 0.0, + gluLookAt(0.0, -eyeY, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); @@ -114,6 +116,7 @@ void GLView::setupCamera() glRotated(cam.object_rot.y(), 0.0, 1.0, 0.0); glRotated(cam.object_rot.z(), 0.0, 0.0, 1.0); break; + } case Camera::VECTOR: { switch (this->cam.projection) { case Camera::PERSPECTIVE: { From 8d401d3534960d2b2394acbe323538e0a083105c Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Sun, 4 Jan 2015 17:05:21 +0100 Subject: [PATCH 235/263] Use viewport height as "distance" for the status text in orthogonal mode. While this is not strictly correct as the actual distance has no effect in orthogonal mode, it's giving the user an indication of the zoom factor. --- src/Camera.cc | 9 +++++++++ src/Camera.h | 1 + src/QGLView.cc | 9 +-------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Camera.cc b/src/Camera.cc index 479c1d0c..9f739940 100644 --- a/src/Camera.cc +++ b/src/Camera.cc @@ -109,3 +109,12 @@ void Camera::setProjection(ProjectionType type) { this->projection = type; } + +std::string Camera::statusText() +{ + boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f")); + fmt % object_trans.x() % object_trans.y() % object_trans.z() + % object_rot.x() % object_rot.y() % object_rot.z() + % (this->projection == PERSPECTIVE ? viewer_distance : height); + return fmt.str(); +} diff --git a/src/Camera.h b/src/Camera.h index 0979ccc6..a04196c9 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -31,6 +31,7 @@ public: void setProjection(ProjectionType type); void zoom(int delta); void viewAll(const BoundingBox &bbox, float scalefactor = 1.0f); + std::string statusText(); // Vectorcam Eigen::Vector3d eye; diff --git a/src/QGLView.cc b/src/QGLView.cc index 65410615..5068f07b 100644 --- a/src/QGLView.cc +++ b/src/QGLView.cc @@ -164,16 +164,9 @@ void QGLView::paintGL() GLView::paintGL(); if (statusLabel) { - QString msg; - Camera nc(cam); nc.gimbalDefaultTranslate(); - msg.sprintf(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f"), - nc.object_trans.x(), nc.object_trans.y(), nc.object_trans.z(), - nc.object_rot.x(), nc.object_rot.y(), nc.object_rot.z(), - nc.viewer_distance ); - - statusLabel->setText(msg); + statusLabel->setText(QString::fromStdString(nc.statusText())); } if (running_under_wine) swapBuffers(); From acb206dd18a23d33ab9ada42bd60d13ee6a42a2d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Jan 2015 12:24:46 -0500 Subject: [PATCH 236/263] #1089 Added minimal testcase --- testdata/scad/bugs/issue1089.scad | 8 ++++++++ tests/CMakeLists.txt | 1 + .../cgalpngtest/issue1089-expected.png | Bin 0 -> 5239 bytes .../monotonepngtest/issue1089-expected.png | Bin 0 -> 5239 bytes .../opencsgtest/issue1089-expected.png | Bin 0 -> 5383 bytes 5 files changed, 9 insertions(+) create mode 100644 testdata/scad/bugs/issue1089.scad create mode 100644 tests/regression/cgalpngtest/issue1089-expected.png create mode 100644 tests/regression/monotonepngtest/issue1089-expected.png create mode 100644 tests/regression/opencsgtest/issue1089-expected.png diff --git a/testdata/scad/bugs/issue1089.scad b/testdata/scad/bugs/issue1089.scad new file mode 100644 index 00000000..17aa137c --- /dev/null +++ b/testdata/scad/bugs/issue1089.scad @@ -0,0 +1,8 @@ +hull() + polyhedron(points = [ +[-0.249434174697078959, -9.946811825017595865, 7.668480694904857842], +[-0.503165223042536525, 8.8964795095546467252, 0.896037100784631946], +[-0.503165223042536525, -0.66656805007570774091, 3.819754148011998751], +[-0.503165223042536525, -10.229615609706060653, 6.743471195239365557]], +faces = [[0,1,2,3]]); + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ca1f58a8..1b23a552 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1219,6 +1219,7 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1069.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1089.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(REMOVE_ITEM EXPORT3D_TEST_FILES diff --git a/tests/regression/cgalpngtest/issue1089-expected.png b/tests/regression/cgalpngtest/issue1089-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..5fdebc2487543efdfcb9b9cc1927c54e601f32da GIT binary patch literal 5239 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 Date: Sun, 4 Jan 2015 13:38:06 -0500 Subject: [PATCH 237/263] #1089 Correctly handle CGAL exception behavior --- src/cgalutils.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 98d61af8..06b02709 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -139,18 +139,20 @@ namespace CGALUtils { if (points.size() <= 3) return false; // Apply hull + bool success = false; if (points.size() >= 4) { CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); try { CGAL::Polyhedron_3 r; CGAL::convex_hull_3(points.begin(), points.end(), r); - if (!createPolySetFromPolyhedron(r, result)) return true; + success = !createPolySetFromPolyhedron(r, result); } catch (const CGAL::Assertion_exception &e) { PRINTB("ERROR: CGAL error in applyHull(): %s", e.what()); } + CGAL::set_error_behaviour(old_behaviour); } - return false; + return success; } template From 4b5ff845f7402089bd54119e409328f59bcfa07e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 4 Jan 2015 20:10:37 -0500 Subject: [PATCH 238/263] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 090f60d8..97d6c9e7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ [![Travis CI](https://api.travis-ci.org/openscad/openscad.png)](https://travis-ci.org/openscad/openscad) [![Coverity Status](https://scan.coverity.com/projects/2510/badge.svg)](https://scan.coverity.com/projects/2510) +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/openscad/openscad/trend.png)](https://bitdeli.com/free "Bitdeli Badge") # What is OpenSCAD? [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=openscad&url=http://openscad.org&title=OpenSCAD&language=&tags=github&category=software) From 5b865293a60466c692a99d059e55386e427184cf Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 01:56:24 -0500 Subject: [PATCH 239/263] Library updates; qt-5.4.0, eigen-3.2.3, boost-1.57, cgal-4.5.1, glew-1.11, gettext-0.19.4, libffi-3.2.1, glib-2.42.1, libxml2-2.9.2 --- scripts/macosx-build-dependencies.sh | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index bdb8a619..109b95a5 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -325,10 +325,10 @@ build_boost() fi if $USING_LLVM; then BOOST_TOOLSET="toolset=darwin-llvm" - echo "using darwin : llvm : llvm-g++ ;" >> tools/build/v2/user-config.jam + echo "using darwin : llvm : llvm-g++ ;" >> tools/build/user-config.jam elif $USING_CLANG; then BOOST_TOOLSET="toolset=clang" - echo "using clang ;" >> tools/build/v2/user-config.jam + echo "using clang ;" >> tools/build/user-config.jam fi ./b2 -j"$NUMCPU" -d+2 $BOOST_TOOLSET cflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS" linkflags="-mmacosx-version-min=$MAC_OSX_VERSION_MIN -arch x86_64 $BOOST_EXTRA_FLAGS -headerpad_max_install_names" install install_name_tool -id $DEPLOYDIR/lib/libboost_thread.dylib $DEPLOYDIR/lib/libboost_thread.dylib @@ -356,8 +356,9 @@ build_cgal() cd $BASEDIR/src rm -rf CGAL-$version if [ ! -f CGAL-$version.tar.gz ]; then - # 4.5 - curl -O https://gforge.inria.fr/frs/download.php/file/34149/CGAL-$version.tar.gz + # 4.5.1 + curl -O https://gforge.inria.fr/frs/download.php/file/34400/CGAL-$version.tar.gz + # 4.5 curl -O https://gforge.inria.fr/frs/download.php/file/34149/CGAL-$version.tar.gz # 4.4 curl -O https://gforge.inria.fr/frs/download.php/file/33525/CGAL-$version.tar.gz # 4.3 curl -O https://gforge.inria.fr/frs/download.php/32994/CGAL-$version.tar.gz # 4.2 curl -O https://gforge.inria.fr/frs/download.php/32359/CGAL-$version.tar.gz @@ -451,6 +452,7 @@ build_eigen() elif [ $version = "3.2.0" ]; then EIGENDIR=eigen-eigen-ffa86ffb5570; elif [ $version = "3.2.1" ]; then EIGENDIR=eigen-eigen-6b38706d90a9; elif [ $version = "3.2.2" ]; then EIGENDIR=eigen-eigen-1306d75b4a21; + elif [ $version = "3.2.3" ]; then EIGENDIR=eigen-eigen-36fd1ba04c12; fi if [ $EIGENDIR = "none" ]; then @@ -542,7 +544,7 @@ build_libxml2() fi tar xzf "libxml2-$version.tar.gz" cd "libxml2-$version" - ./configure --prefix="$DEPLOYDIR" --without-ftp --without-http --without-python CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN LDFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN + ./configure --prefix="$DEPLOYDIR" --with-zlib=/usr -without-lzma --without-ftp --without-http --without-python CFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN LDFLAGS=-mmacosx-version-min=$MAC_OSX_VERSION_MIN make -j$NUMCPU make install } @@ -771,26 +773,26 @@ fi echo "Using basedir:" $BASEDIR mkdir -p $SRCDIR $DEPLOYDIR -build_qt5 5.3.2 +build_qt5 5.4.0 build_qscintilla 2.8.4 # NB! For eigen, also update the path in the function -build_eigen 3.2.2 +build_eigen 3.2.3 build_gmp 5.1.3 build_mpfr 3.1.2 -build_boost 1.54.0 +build_boost 1.57.0 # NB! For CGAL, also update the actual download URL in the function -build_cgal 4.5 -build_glew 1.10.0 -build_gettext 0.18.3.2 -build_libffi 3.1 -build_glib2 2.40.0 +build_cgal 4.5.1 +build_glew 1.11.0 +build_gettext 0.19.4 +build_libffi 3.2.1 +build_glib2 2.42.1 build_opencsg 1.4.0 build_freetype 2.5.4 --without-png build_ragel 6.9 build_harfbuzz 0.9.37 "--with-coretext=auto --with-glib=no" export FREETYPE_CFLAGS="-I$DEPLOYDIR/include -I$DEPLOYDIR/include/freetype2" export FREETYPE_LIBS="-L$DEPLOYDIR/lib -lfreetype" -build_libxml2 2.9.1 +build_libxml2 2.9.2 build_fontconfig 2.11.1 if $OPTION_DEPLOY; then # build_sparkle andymatuschak 0ed83cf9f2eeb425d4fdd141c01a29d843970c20 From 3c337449e99dd8e4d586529e5aafe7f795b3e9b1 Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 5 Jan 2015 18:34:08 +0100 Subject: [PATCH 240/263] Unify zoom handling for perspective and orthogonal mode. --- src/Camera.cc | 28 +++++++++++++++++++--------- src/Camera.h | 12 ++++++++---- src/GLView.cc | 22 +++++++++++----------- src/QGLView.cc | 11 ++++------- src/mainwin.cc | 4 ++-- 5 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/Camera.cc b/src/Camera.cc index 9f739940..ccf02062 100644 --- a/src/Camera.cc +++ b/src/Camera.cc @@ -3,13 +3,13 @@ #include "printutils.h" Camera::Camera(enum CameraType camtype) : - type(camtype), projection(Camera::PERSPECTIVE), fov(45), height(60), viewall(false) + type(camtype), projection(Camera::PERSPECTIVE), fov(45), viewall(false), zoom_value(60) { PRINTD("Camera()"); if (this->type == Camera::GIMBAL) { object_trans << 0,0,0; object_rot << 35,0,25; - viewer_distance = 500; + zoom_value = 500; } else if (this->type == Camera::VECTOR) { center << 0,0,0; Eigen::Vector3d cameradir(1, 1, -0.5); @@ -26,8 +26,7 @@ void Camera::setup(std::vector params) type = Camera::GIMBAL; object_trans << params[0], params[1], params[2]; object_rot << params[3], params[4], params[5]; - viewer_distance = params[6]; - height = params[6]; + zoom_value = params[6]; } else if (params.size() == 6) { type = Camera::VECTOR; eye << params[0], params[1], params[2]; @@ -74,13 +73,13 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor) switch (this->projection) { case Camera::ORTHOGONAL: - this->height = bbox.diagonal().norm(); + this->zoom_value = bbox.diagonal().norm(); break; case Camera::PERSPECTIVE: { double radius = bbox.diagonal().norm()/2; switch (this->type) { case Camera::GIMBAL: - this->viewer_distance = radius / tan(this->fov*M_PI/360); + this->zoom_value = radius / tan(this->fov*M_PI/360); break; case Camera::VECTOR: { Vector3d cameradir = (this->center - this->eye).normalized(); @@ -101,8 +100,7 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor) void Camera::zoom(int delta) { - this->viewer_distance *= pow(0.9, delta / 120.0); - this->height = this->viewer_distance; + this->zoom_value *= pow(0.9, delta / 120.0); } void Camera::setProjection(ProjectionType type) @@ -110,11 +108,23 @@ void Camera::setProjection(ProjectionType type) this->projection = type; } +void Camera::resetView() +{ + object_rot << 35, 0, -25; + object_trans << 0, 0, 0; + zoom_value = 140; +} + +double Camera::zoomValue() +{ + return zoom_value; +} + std::string Camera::statusText() { boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f")); fmt % object_trans.x() % object_trans.y() % object_trans.z() % object_rot.x() % object_rot.y() % object_rot.z() - % (this->projection == PERSPECTIVE ? viewer_distance : height); + % zoom_value; return fmt.str(); } diff --git a/src/Camera.h b/src/Camera.h index a04196c9..f736f902 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -30,7 +30,9 @@ public: void gimbalDefaultTranslate(); void setProjection(ProjectionType type); void zoom(int delta); + void resetView(); void viewAll(const BoundingBox &bbox, float scalefactor = 1.0f); + double zoomValue(); std::string statusText(); // Vectorcam @@ -41,14 +43,10 @@ public: // Gimbalcam Eigen::Vector3d object_trans; Eigen::Vector3d object_rot; - double viewer_distance; // Perspective settings double fov; // Field of view - // Orthographic settings - double height; // world-space height of viewport - // true if camera should try to view everything in a given // bounding box. bool viewall; @@ -59,4 +57,10 @@ public: unsigned int pixel_width; unsigned int pixel_height; + +protected: + // This is the viewer-distance in perspective mode and in + // ortographic mode, this is defining the viewport height + // (in world-space) + double zoom_value; }; diff --git a/src/GLView.cc b/src/GLView.cc index af4e4e11..e79c5fb7 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -92,22 +92,21 @@ void GLView::setupCamera() switch (this->cam.type) { case Camera::GIMBAL: { - double eyeY = 0.0; switch (this->cam.projection) { case Camera::PERSPECTIVE: { - eyeY = cam.viewer_distance; - gluPerspective(cam.fov, aspectratio, 0.1 * eyeY, 100 * eyeY); + double dist = cam.zoomValue(); + gluPerspective(cam.fov, aspectratio, 0.1 * dist, 100 * dist); break; } case Camera::ORTHOGONAL: { - eyeY = cam.height; - glOrtho(-cam.height/2*aspectratio, cam.height*aspectratio/2, - -cam.height/2, cam.height/2, + double height = cam.zoomValue(); + glOrtho(-height/2*aspectratio, height*aspectratio/2, + -height/2, height/2, -far_far_away, +far_far_away); break; } } - gluLookAt(0.0, -eyeY, 0.0, + gluLookAt(0.0, -cam.zoomValue(), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); @@ -125,8 +124,9 @@ void GLView::setupCamera() break; } case Camera::ORTHOGONAL: { - glOrtho(-cam.height/2*aspectratio, cam.height*aspectratio/2, - -cam.height/2, cam.height/2, + double height = cam.zoomValue(); + glOrtho(-height/2*aspectratio, height*aspectratio/2, + -height/2, height/2, -far_far_away, +far_far_away); break; } @@ -453,7 +453,7 @@ void GLView::showSmallaxes(const Color4f &col) void GLView::showAxes(const Color4f &col) { - double l = cam.projection == Camera::PERSPECTIVE ? cam.viewer_distance : cam.height; + double l = cam.zoomValue(); // FIXME: doesn't work under Vector Camera // Large gray axis cross inline with the model @@ -492,7 +492,7 @@ void GLView::showCrosshairs() glBegin(GL_LINES); for (double xf = -1; xf <= +1; xf += 2) for (double yf = -1; yf <= +1; yf += 2) { - double vd = cam.viewer_distance/8; + double vd = cam.zoomValue()/8; glVertex3d(-xf*vd, -yf*vd, -vd); glVertex3d(+xf*vd, +yf*vd, +vd); } diff --git a/src/QGLView.cc b/src/QGLView.cc index 5068f07b..43178989 100644 --- a/src/QGLView.cc +++ b/src/QGLView.cc @@ -84,9 +84,7 @@ void QGLView::init() void QGLView::resetView() { - cam.object_rot << 35, 0, -25; - cam.object_trans << 0, 0, 0; - cam.viewer_distance = 140; + cam.resetView(); } void QGLView::viewAll() @@ -245,11 +243,10 @@ void QGLView::mouseMoveEvent(QMouseEvent *event) // Middle button pans in the xy plane // Shift-right and Shift-middle zooms if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0) { - cam.viewer_distance += (GLdouble)dy; + cam.zoom(-12.0 * dy); } else { - - double mx = +(dx) * cam.viewer_distance/1000; - double mz = -(dy) * cam.viewer_distance/1000; + double mx = +(dx) * 3.0 * cam.zoomValue() / QWidget::width(); + double mz = -(dy) * 3.0 * cam.zoomValue() / QWidget::height(); double my = 0; #if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0)) diff --git a/src/mainwin.cc b/src/mainwin.cc index c39dfe58..ff5ff713 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1505,7 +1505,7 @@ void MainWindow::updateTemporalVariables() vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.z(), 360))); top_ctx.set_variable("$vpr", ValuePtr(vpr)); - top_ctx.set_variable("$vpd", ValuePtr(qglview->cam.viewer_distance)); + top_ctx.set_variable("$vpd", ValuePtr(qglview->cam.zoomValue())); } @@ -1529,7 +1529,7 @@ void MainWindow::updateCamera() double rx = cam.object_rot.x(); double ry = cam.object_rot.y(); double rz = cam.object_rot.z(); - double d = cam.viewer_distance; + double d = cam.zoomValue(); double x, y, z; const ValuePtr vpr = root_module->lookup_variable("$vpr"); From 0cf6de75a4f9ea00b7926cc39ec20d94b588fe06 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 13:36:03 -0500 Subject: [PATCH 241/263] Updated hosting issue. Fixes #1136 --- src/AboutDialog.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AboutDialog.html b/src/AboutDialog.html index 8eefeecf..22ca9272 100644 --- a/src/AboutDialog.html +++ b/src/AboutDialog.html @@ -149,9 +149,9 @@ benhowes, 5263, Craig Trader, Miro Hrončok, Tony Theodore ... and many others

-
  • Github -
  • Rock Linux -
  • Thingiverse +
  • Source code repos and website hosted on Github +
  • Downloads hosted by Joshua Holbrook +
  • CI hosted on Travis-CI

    From 1a1f36035d2d665efac8626877dd69a7531cfc84 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 13:38:26 -0500 Subject: [PATCH 242/263] polyhedron debug output had indices reversed --- src/cgalutils-polyhedron.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cgalutils-polyhedron.cc b/src/cgalutils-polyhedron.cc index 16939316..68669875 100644 --- a/src/cgalutils-polyhedron.cc +++ b/src/cgalutils-polyhedron.cc @@ -98,7 +98,7 @@ namespace /* anonymous */ { #ifdef GEN_SURFACE_DEBUG printf("["); int fidx = 0; - BOOST_FOREACH(size_t i, indices) { + BOOST_REVERSE_FOREACH(size_t i, indices) { if (fidx++ > 0) printf(","); printf("%ld", i); } From 5786ba89ff86aede2bc63ea2f3a581169ae02ba6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 14:32:59 -0500 Subject: [PATCH 243/263] #1137 Added testcase --- testdata/scad/bugs/issue1137.scad | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 testdata/scad/bugs/issue1137.scad diff --git a/testdata/scad/bugs/issue1137.scad b/testdata/scad/bugs/issue1137.scad new file mode 100644 index 00000000..9a131352 --- /dev/null +++ b/testdata/scad/bugs/issue1137.scad @@ -0,0 +1,7 @@ +minkowski() { +polyhedron(faces=[[3,2,0,1], [7,6,5,4],[4,5,2,3],[5,6,1,2],[6,7,0,1],[7,4,3,0]], + points=[[0,1,1],[1,1,1],[1,0,1],[0,0,1],[0,0,0],[1,0,0],[1,1,0],[0,1,0]]); + polyhedron(faces=[[3,2,1,0],[7,6,5,4],[4,5,2,3],[5,6,1,2],[6,7,0,1],[7,4,3,0]], + points=[[0,1,1],[1,1,1],[1,0,1],[0,0,1],[0,0,0],[1,0,0],[1,1,0],[0,1,0]]); +} + From 1896c3f09a6c8456bdcc215446a5570d07ddf07e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 14:33:54 -0500 Subject: [PATCH 244/263] Gracefully handle malformed PolySets in minkowski. Fixes #1137 --- src/cgalutils.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index 06b02709..d09cf9a0 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -228,7 +228,7 @@ namespace CGALUtils { if (ps) { PRINTDB("Minkowski: child %d is nonconvex PolySet, transforming to Nef and decomposing...", i); CGAL_Nef_polyhedron *p = createNefPolyhedronFromGeometry(*ps); - decomposed_nef = *p->p3; + if (!p->isEmpty()) decomposed_nef = *p->p3; delete p; } else { PRINTDB("Minkowski: child %d is nonconvex Nef, decomposing...",i); From fe1e300756a7422b1085255c21a51d40d3914236 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 15:31:59 -0500 Subject: [PATCH 245/263] #1138 Added testcase --- testdata/scad/bugs/issue1138.scad | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 testdata/scad/bugs/issue1138.scad diff --git a/testdata/scad/bugs/issue1138.scad b/testdata/scad/bugs/issue1138.scad new file mode 100644 index 00000000..ca3f5002 --- /dev/null +++ b/testdata/scad/bugs/issue1138.scad @@ -0,0 +1,12 @@ +minkowski() { + polyhedron(faces=[[4,5,6,7],[3,2,5,4],[2,1,6,5],[1,0,7,6],[0,3,4,7], + [0,8,3], + [1,2,9], + [0,1,9,8], + [2,3,8,9]], + points=[[0,10,10],[10,10,10],[10,0,10],[0,0,10],[0,0,0],[10,0,0],[10,10,0],[0,10,0], + [4.9999999,5,9],[5.0000001,5,9]]); + polyhedron(faces=[[0,1,2,3],[4,5,6,7],[3,2,5,4],[2,1,6,5],[1,0,7,6],[0,3,4,7]], + points=[[0,1,1],[1,1,1],[1,0,1],[0,0,1],[0,0,0],[1,0,0],[1,1,0],[0,1,0]]); +} + From f79414a208aff37467e9b22098d3cf86565ce971 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 15:57:42 -0500 Subject: [PATCH 246/263] More debug output --- src/cgalutils.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index d09cf9a0..e9f348b6 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -92,6 +92,10 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) if (plane_error) try { CGAL_Polyhedron P; bool err = CGALUtils::createPolyhedronFromPolySet(ps_tri, P); + if (!err) { + PRINTDB("Polyhedron is closed: %d", P.is_closed()); + PRINTDB("Polyhedron is valid: %d", P.is_valid(false, 0)); + } if (!err) N = new CGAL_Nef_polyhedron3(P); } catch (const CGAL::Assertion_exception &e) { From 1ad4af8b0b44def19d2e1bd919d23a0a9e9ced62 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 16:04:48 -0500 Subject: [PATCH 247/263] Collapse consequtive identical vertices instead of deleting the whole polygon. Fixes #1138 --- src/cgalutils-polyhedron.cc | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/cgalutils-polyhedron.cc b/src/cgalutils-polyhedron.cc index 68669875..43ab72d6 100644 --- a/src/cgalutils-polyhedron.cc +++ b/src/cgalutils-polyhedron.cc @@ -79,20 +79,13 @@ namespace /* anonymous */ { indices.push_back(grid.data(v)); } - // We perform this test since there is a bug in CGAL's - // Polyhedron_incremental_builder_3::test_facet() which - // fails to detect duplicate indices - bool err = false; - for (std::size_t i = 0; i < indices.size(); ++i) { - // check if vertex indices[i] is already in the sequence [0..i-1] - for (std::size_t k = 0; k < i && !err; ++k) { - if (indices[k] == indices[i]) { - err = true; - break; - } - } - } - if (!err && B.test_facet(indices.begin(), indices.end())) { + // We remove duplicate indices since there is a bug in CGAL's + // Polyhedron_incremental_builder_3::test_facet() which fails to detect this + std::vector::iterator last = std::unique(indices.begin(), indices.end()); + std::advance(last, -1); + if (*last != indices.front()) last++; // In case the first & last are equal + indices.erase(last, indices.end()); + if (indices.size() >= 3 && B.test_facet(indices.begin(), indices.end())) { B.add_facet(indices.begin(), indices.end()); } #ifdef GEN_SURFACE_DEBUG From fe0b7dd334541e6daa115d192534f9cb67a0ed71 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 16:10:02 -0500 Subject: [PATCH 248/263] #835 Added expected image --- .../monotonepngtest/issue835-expected.png | Bin 0 -> 8333 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression/monotonepngtest/issue835-expected.png diff --git a/tests/regression/monotonepngtest/issue835-expected.png b/tests/regression/monotonepngtest/issue835-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..e776820d13cfb0dc298bc5538ed11028eb585ab5 GIT binary patch literal 8333 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 Date: Mon, 5 Jan 2015 16:11:51 -0500 Subject: [PATCH 249/263] #904 Added expected image --- .../monotonepngtest/issue904-expected.png | Bin 0 -> 6642 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression/monotonepngtest/issue904-expected.png diff --git a/tests/regression/monotonepngtest/issue904-expected.png b/tests/regression/monotonepngtest/issue904-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..1a370d074d45ea56a02c36e719a41b1e4652334e GIT binary patch literal 6642 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 literal 0 HcmV?d00001 From 179ad1ea7cd88498c54044831e9ffef51674dc29 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 16:13:21 -0500 Subject: [PATCH 250/263] #911 Added expected image --- .../monotonepngtest/issue911-expected.png | Bin 0 -> 7825 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression/monotonepngtest/issue911-expected.png diff --git a/tests/regression/monotonepngtest/issue911-expected.png b/tests/regression/monotonepngtest/issue911-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..2eb927926e20aafe8e531516516405c8770a3b86 GIT binary patch literal 7825 zcmeHM`8$;D+rQ>Eld)u9D@?MbEETE9j3SaPNiv0$5<(s!+uS2kDYV!sj8dp9l|9U; zr{p1&?1qVm?26GaGww4`@ZgAXSr5*oiG4k z?LjMZM*t9LA^^Yo6R~c8AppuQ2hGi#!Z1_J+E>53kFH_uD7voYPCYH<`O)g&$;FOJ zJYGo4eXXve<96eaq2NfI?icY-2A1uXh1032yv5#$jTyYpsf*E_rV~ny{=b+N0mR59 zB7((Bih>eByad6)i3DVHYP_TgBnU^~UpW6(=ij~a@5%aqbnn#Z zRr@#T>dh`wxDB6Kq5QeLxiWd|PkbbMs!#lqv+olx+;ksT3VXZ6ym4C(yfqhv@AGRI zy@^ChYODQ7eO@djM4bStwa@jupX{4X)4vg`Zk>4k1PK_p5!xR}?xHhWZHB&Wx;;x8 zy3z^9Psnbko6$Zc@~aKzS!GE9WLPX6r}_pY~}Lkd-^bJyI9_0qUTUG+?o&>tu1b5HQmshp>uq*DYw5ssgbvr3bt#mqNd6~kW;P$;Lw%B+3iwNp3 zQaC(lZ9KkoH{2fam@hP`q<*~8_+f0c5RB#C>*cz9>{6nbOfC*x0ybi)f}5^cDQtG6 zOMuNydCbAI3r8F1D!XdjWWn8+^DJd^wSM0-mvumplXU~VxIHzILdp8JkP6ZtS}XTo z`FJJb)>(HERPNAYrv0;5ryH^#UT%QC2hD3DtTVGJdU?adN78A!L;4=45yuz0(*DN#ijRoX@|Nuj)Z|iP1kE1KlFU-8HA#G^qzPMDD?q8Y)sYb%&K`N`u3CDwKYh5ivAo>ol`LJRx*N$Z8Ixdw;wl z^zn5C(|lhiXq(Qy@TsBo(u(EXIcbc(qe)$|V3J0w>A`hE=Mho^rTmvNv1?AnHY-XM zWHp*Z>xwHw`;NMJ9i<$-YRc~`UVq=_YQf4cBA2OeyDd4#dG~1kLh-Zq**x|G%AfdC zA60nEtaAY>jMH~{-_cWlKl%kN>Noe|)Lty3QsJP!X7 z{Rgkf`L`+^x;LwMML}GNW;te^MQcy?=4jkbkIq_wu>OP7Ldv#CcBKxUR;%!6oX$AT z>)0Jd`4hQrwe&%X*MvP{lU~{k}HthhhpoUS*$FSb7lo zG=GM8_xN(v-f{;Uur=lmHX%J#$v~q%u#)IxOX(>(9(-@A^xF6|0TUSilJ!K*1uY#) zzJH1~UfiuJBG$o{Cwx*-1*0biqP2wvqzd6$}4jO-4UtRG=s-+q<)lyZ#0bo;sd=I}tK zR;zgZ)q^U0a*1(uZEH)z^sU!K~ z>h*_T5i>(YuWaI6tD~HlO3d%N_d5qgTJ}cTy1?RysTXO9UNpZcyGVl(@hhpFFK#vPg*Hd-E-SJuV(w3Bav% zkp`tshM=jzinSs$nhqs1%f-~`iYVdi#=U0WhVtCQ>+7;#o-LRLYgm4CTwkbtrDk_m zdrydb8(W$?!FPz_D>9}jh+tOR-g;`KU9A~ua1ae0aliyViC*fxL$Eo=N<=uk#Pqa> z*5Jh3x;_i_djETNr7omFcbg6l6`?H%>paX>bHR_4l%RDgPklpZz`NX_{`$cf!oySc z*xy`D{k@S}L3sYqP-t7v{M*Eeg30jN-I5+Ol#^+--@@C?@twp7P`ac_7 za@FuOLqqeyfM**n*c||+$J4H!RTo;P{UN3RVocsJ&xi8J*+rWmlxltQ;=?*hTsX&9 z7)CImVD7LYf1Nw_m7U$V6nPy5tB>rZu*BohO-`A=Qc$(ZuFvcl!y41$ zB=AslI*2IZWQRoYe?+l5F2RZRL>%ME@VGoeq z6#PyXj*iQN^*%GlpYXgg>gencZ+4_21-H|?TEIK>P(}|Sc`l1ISaIn!47xStnQ80d zUD9B2ouzbhX70Zd9;-*I|AcRn^b}O$}t&P29rq;hx7gTTdV#YnpfE}1o zox}g&NJ&QvtDg?vfiqO+?QyRFV>JxJw2EU8k0IMW^QZ{Ar>v;*iwpcO%eHPb%;RqC zcF>{Ywp4i;>2ludHT~w^D))-l4D2i8xcnjY0o@@2tMi&zuI0qR?51I~JCj1)s`+3$j4->!A87^aN5UhNVGED?G1+b(J2Qbmt2W%#b$? zoHDHtUFs_i-Ia0#LS+pp@&e$S*jbEzxL@HOVZu&2vq~jTq>Zx zN1{Uc)SN+M^yLSC+yP-dyo8HJThs)7n+zW9+xMRFDr!axd5^nM$|I*lP_PC)O<8zb zQjI!^Wk+*jt8|_m74vxUl1#n*RscnZP=o~^^`IQ(SBC<}= zU(ZDHJ{oq2W{hF->vE^Tw4teKzi{NjY$C}Bc00Wp$9Q~QA$`Z3BDEC$fBoe$_P5RG z4oD1V)+5+n`8KZm*N;jJk%z6Kv-GW8sm3&HuS^?fu+swSB`E=sYa8~_)G>vWQ-&sp zD}F&yAVEBofI-smW4xvwCT42|ry1DCcBb!6Wt@leyZT^CoNYv3$nS_@)FZAG(e6#O z^uBYV=9cR%QHC2*O>z06L`t9DAz&ieOY+vD>cByAwWnTyZoJl-odSC>aL>8&!(V4e zDq}v;%uVO%n`92}xJoi7v6J#Y-MT2KpC`54%ujS^{-lK@;7WP#of5=kKtj6n2DLTL z9=q=`93k3*ulI)`-p6GtF7~mh0i4T463m(AT6bv=&URWLT1nue4;hNatLZ&z4Guh5B)Fk@r=JG4QCh<%csX<7TT+ zzmPXKR3V-&1LCDARj9(!+iz>B*$`B=PD}WRWZUsCP)?YSxxMp6R8*?@>TeiI4E0H# zpqj2{XwM?Hlqce=3UvRL7f2g=v(y2>bjU8v;>YHtB0rD>q_^RaJfSgO-eG!WvN0;Z zOEY?exWQDi?@5tt8>e`IPOk=)U6q_Nh01EAh?0+XQnUhC-<2`AHZkQP`lew0l6H4h z+Oqpw9_P_Ca9cj{yO2yxV4YmVV+#5Bj*~5$LC7hSQ8iDN!m)FEZAlZvTYEw_CZV4G znu+t~W9EKoy@yHcLCIgVBUJ*s@F898)w10w?Tv|YZJZ>zfr%BwL$7hTb<>(eqmZ~; z5d8th-S`M>@b;zArpv0O8EryhQf*xEn7z}b(;)Hn-pOWvoY><_L+NOz%3p6H?}5r1 z>}R2C)cl7RjfK6r#-3Re?Ig6tXmH_17JllV@iWh{!Th5q)+$em(dr+)czB0QP4N&L z)TJ#182Nn@MQCx_liLKhmBc^#s|HqNP)dCdV-wB%y{rCF`&c=`Zndqn<@oX54P#=o zPt|_uDP-!}u&buhZJg}JT;2(gt2_9sF@gGHXWemi+CuTrKbJ}@NmW0~g37b-h1kEA z;Eu~igBLrMNat`-E{SBSpp?p1$u>@!mKX5=I8)4e^(TSqWtX@PuH&9Q7a%;NL8tdZ=nFEH=TjYK;mY@X<}WS-n5iM}-~P=IexWSZ z!HLKpQudw2dyBs}ZTWWHLFH0ph4AVw&zWIjWV9ETpH$0+1>9T07ZNYdC1zBET^|e= zj=v}Uod0C&Hj#Z~t|#7-w6k6sV;`Hv$X#|}+aG(?t}!XbGWZ!QAG9U8#G8GjlLMJj zw2TBu(lGs_O;}SGo*S08kf+r?a`*S@Mper|HTNA9HncgyZawlm;oMI#)(~>0x`s?0 zeg0&@$o)~dh8F03W*O6SjjEB5yI^!YwNrCM(qTf@CpbC_U*@F1q(AXFb3eftwdwHj zE%L{$%a89IBuPryn*lXlH|Znt0`e(l6Lfst^QLg@*Q2}j$Tv0j{rED$`w<=*VHgT4 zvN#!6CA-Vw!~`*}>K_X%DaAUw)NWg#LTM*O;Q~`S0_#+Oxzhf`$8 z3)C1r9hDj7#wcWDCUjEbzl{_?s_En}zpUzDx~7z;w_N|A9cO~<$?V5zB1g0F=55VTA{`mg&%hzJ1Mo15X#Yqa#bQZ+sc*}%KtBDAcGC0R#C#m#G0|x9bQHlA zMXTm6>utUFu2&{duq8N^gAc>r%XN6F zDA7F(v8td(Y6);Pwx(=vO=esrV+x6C{tgeXWtewVRd)SLUjWUbv6Skc}u8A}JK zt(yC)`3J1t{SyA~m!_A`1&l%xMUapS6qI$$+#D3keZaknpLB4T1!? ze_=-iq*k%epWZ@()^|AxP&ILG5l(=Ie*H}9DiPHofS|6{N%)CN0{Tzw5r9@Q84}T= z>>l{(iLjLb-UhFcf>s42q9=*3H6i_Ufkbp%R1I4GFy%MVXIGh72@3G-idN9-hd@HP r%~=rMDah3S1^RDA|4;8xDqo;?>cFY0qFfyO)C>+<*qImY^N9H`zsazk literal 0 HcmV?d00001 From 90172fa5c36c64d4ff8a2baf828e8187e73786bf Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 16:14:02 -0500 Subject: [PATCH 251/263] #913 Added expected image --- .../monotonepngtest/issue913-expected.png | Bin 0 -> 7079 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression/monotonepngtest/issue913-expected.png diff --git a/tests/regression/monotonepngtest/issue913-expected.png b/tests/regression/monotonepngtest/issue913-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..677d52ca8bc001554d27e59b4decd40abbad783a GIT binary patch literal 7079 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 XY6R=pD>nQC4zb(nxTRndBl^DpPSBy0 literal 0 HcmV?d00001 From 5a2b89981cdf033c50bf24cdb80084501e3659ea Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 17:37:14 -0500 Subject: [PATCH 252/263] Minor fix: If we know that a PolySet is convex, there is no need to perform a computationally expensive test. Should improve #1090 --- src/cgalutils.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cgalutils.cc b/src/cgalutils.cc index e9f348b6..971f12f7 100644 --- a/src/cgalutils.cc +++ b/src/cgalutils.cc @@ -45,7 +45,7 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps) // we tessellate the polyset before checking. PolySet psq(ps); psq.quantizeVertices(); - PolySet ps_tri(3); + PolySet ps_tri(3, psq.convexValue()); PolysetUtils::tessellate_faces(psq, ps_tri); if (ps_tri.is_convex()) { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; From 26f8742023088496ae1306866af8a046570077e4 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 17:38:42 -0500 Subject: [PATCH 253/263] Added convexValue() --- src/polyset.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/polyset.h b/src/polyset.h index d200bf39..cf151dbe 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -43,6 +43,7 @@ public: void resize(Vector3d newsize, const Eigen::Matrix &autosize); bool is_convex() const; + boost::tribool convexValue() const { return this->convex; } private: Polygon2d polygon; From 10e3676a017a00b58faf95a9a8a50ab002600fd3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 20:03:20 -0500 Subject: [PATCH 254/263] Added a test config 'Good' which includes all tests except Bugs --- tests/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1b23a552..f40bf4bf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -933,6 +933,11 @@ function(add_cmdline_test TESTCMD_BASENAME) set_test_config(Default ${TEST_FULLNAME}) endif() set_test_config(All ${TEST_FULLNAME}) + list(FIND FOUNDCONFIGS Bugs FOUND) + if (FOUND EQUAL -1) + set_test_config(Good ${TEST_FULLNAME}) + endif() + unset(FOUNDCONFIGS) get_test_config(${TEST_FULLNAME} FOUNDCONFIGS) set(CONFARG CONFIGURATIONS) From f3f343e101b7579f9ebe7ff8413ce5b013a3c28d Mon Sep 17 00:00:00 2001 From: Torsten Paul Date: Mon, 5 Jan 2015 23:05:09 +0100 Subject: [PATCH 255/263] Fix test case failures caused by camera changes. --- src/Camera.cc | 22 +++++++++++++--------- src/Camera.h | 10 +++++----- src/GLView.cc | 13 +++++++------ src/QGLView.cc | 2 +- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/Camera.cc b/src/Camera.cc index ccf02062..7e53d363 100644 --- a/src/Camera.cc +++ b/src/Camera.cc @@ -3,13 +3,13 @@ #include "printutils.h" Camera::Camera(enum CameraType camtype) : - type(camtype), projection(Camera::PERSPECTIVE), fov(45), viewall(false), zoom_value(60) + type(camtype), projection(Camera::PERSPECTIVE), fov(45), viewall(false), height(60) { PRINTD("Camera()"); if (this->type == Camera::GIMBAL) { object_trans << 0,0,0; object_rot << 35,0,25; - zoom_value = 500; + viewer_distance = 500; } else if (this->type == Camera::VECTOR) { center << 0,0,0; Eigen::Vector3d cameradir(1, 1, -0.5); @@ -26,7 +26,8 @@ void Camera::setup(std::vector params) type = Camera::GIMBAL; object_trans << params[0], params[1], params[2]; object_rot << params[3], params[4], params[5]; - zoom_value = params[6]; + viewer_distance = params[6]; + height = params[6]; } else if (params.size() == 6) { type = Camera::VECTOR; eye << params[0], params[1], params[2]; @@ -73,13 +74,13 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor) switch (this->projection) { case Camera::ORTHOGONAL: - this->zoom_value = bbox.diagonal().norm(); + this->height = bbox.diagonal().norm(); break; case Camera::PERSPECTIVE: { double radius = bbox.diagonal().norm()/2; switch (this->type) { case Camera::GIMBAL: - this->zoom_value = radius / tan(this->fov*M_PI/360); + this->viewer_distance = radius / tan(this->fov*M_PI/360); break; case Camera::VECTOR: { Vector3d cameradir = (this->center - this->eye).normalized(); @@ -100,7 +101,8 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor) void Camera::zoom(int delta) { - this->zoom_value *= pow(0.9, delta / 120.0); + this->viewer_distance *= pow(0.9, delta / 120.0); + this->height = this->viewer_distance; } void Camera::setProjection(ProjectionType type) @@ -110,14 +112,16 @@ void Camera::setProjection(ProjectionType type) void Camera::resetView() { + type = Camera::GIMBAL; object_rot << 35, 0, -25; object_trans << 0, 0, 0; - zoom_value = 140; + height = 140; + viewer_distance = 140; } double Camera::zoomValue() { - return zoom_value; + return this->projection == PERSPECTIVE ? viewer_distance : height; } std::string Camera::statusText() @@ -125,6 +129,6 @@ std::string Camera::statusText() boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f")); fmt % object_trans.x() % object_trans.y() % object_trans.z() % object_rot.x() % object_rot.y() % object_rot.z() - % zoom_value; + % (this->projection == PERSPECTIVE ? viewer_distance : height); return fmt.str(); } diff --git a/src/Camera.h b/src/Camera.h index f736f902..ae9ffaac 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -30,9 +30,9 @@ public: void gimbalDefaultTranslate(); void setProjection(ProjectionType type); void zoom(int delta); + double zoomValue(); void resetView(); void viewAll(const BoundingBox &bbox, float scalefactor = 1.0f); - double zoomValue(); std::string statusText(); // Vectorcam @@ -59,8 +59,8 @@ public: unsigned int pixel_height; protected: - // This is the viewer-distance in perspective mode and in - // ortographic mode, this is defining the viewport height - // (in world-space) - double zoom_value; + // Perspective settings + double viewer_distance; + // Orthographic settings + double height; // world-space height of viewport }; diff --git a/src/GLView.cc b/src/GLView.cc index e79c5fb7..e76a10c3 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -92,21 +92,22 @@ void GLView::setupCamera() switch (this->cam.type) { case Camera::GIMBAL: { + double eyeY = 0.0; switch (this->cam.projection) { case Camera::PERSPECTIVE: { - double dist = cam.zoomValue(); - gluPerspective(cam.fov, aspectratio, 0.1 * dist, 100 * dist); + eyeY = cam.zoomValue(); + gluPerspective(cam.fov, aspectratio, 0.1 * eyeY, 100 * eyeY); break; } case Camera::ORTHOGONAL: { - double height = cam.zoomValue(); - glOrtho(-height/2*aspectratio, height*aspectratio/2, - -height/2, height/2, + eyeY = cam.zoomValue(); + glOrtho(-eyeY/2*aspectratio, eyeY*aspectratio/2, + -eyeY/2, eyeY/2, -far_far_away, +far_far_away); break; } } - gluLookAt(0.0, -cam.zoomValue(), 0.0, + gluLookAt(0.0, -eyeY, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); diff --git a/src/QGLView.cc b/src/QGLView.cc index 43178989..25ca07a2 100644 --- a/src/QGLView.cc +++ b/src/QGLView.cc @@ -64,7 +64,6 @@ static bool running_under_wine = false; void QGLView::init() { - cam.type = Camera::GIMBAL; resetView(); this->mouse_drag_active = false; @@ -245,6 +244,7 @@ void QGLView::mouseMoveEvent(QMouseEvent *event) if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0) { cam.zoom(-12.0 * dy); } else { + double mx = +(dx) * 3.0 * cam.zoomValue() / QWidget::width(); double mz = -(dy) * 3.0 * cam.zoomValue() / QWidget::height(); From 27f8370c7b870eae97189161a1d7c4907f82c6ba Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 21:41:05 -0500 Subject: [PATCH 256/263] Export blank image on empty top-level objects, instead of no image --- src/openscad.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/openscad.cc b/src/openscad.cc index 1e8f56c1..ab7e3acf 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -457,10 +457,7 @@ int cmdline(const char *deps_output_file, const std::string &filename, Camera &c // echo or OpenCSG png -> don't necessarily need geometry evaluation } else { root_geom = geomevaluator.evaluateGeometry(*tree.root(), true); - if (!root_geom) { - PRINT("No top-level object found."); - return 1; - } + if (!root_geom) root_geom.reset(new CGAL_Nef_polyhedron()); if (renderer == Render::CGAL && root_geom->getDimension() == 3) { const CGAL_Nef_polyhedron *N = dynamic_cast(root_geom.get()); if (!N) { From 4d454367f965cb3a5e0160394ca1b5616e510be0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 21:41:58 -0500 Subject: [PATCH 257/263] Run fixed bug test cases as part of the normal regression tests --- .../scad/{bugs => 3D/issues}/issue1004.scad | 0 .../scad/{bugs => 3D/issues}/issue1005.scad | 0 .../scad/{bugs => 3D/issues}/issue1061.scad | 0 .../scad/{bugs => 3D/issues}/issue1069.scad | 0 .../scad/{bugs => 3D/issues}/issue835.scad | 0 .../scad/{bugs => 3D/issues}/issue911.scad | 0 .../scad/{bugs => 3D/issues}/issue913.scad | 0 .../scad/{bugs => 3D/issues}/issue964.scad | 0 .../scad/{bugs => 3D/issues}/issue964b.scad | 0 .../scad/{bugs => 3D/issues}/issue990.scad | 0 tests/CMakeLists.txt | 18 ++---------------- 11 files changed, 2 insertions(+), 16 deletions(-) rename testdata/scad/{bugs => 3D/issues}/issue1004.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue1005.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue1061.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue1069.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue835.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue911.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue913.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue964.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue964b.scad (100%) rename testdata/scad/{bugs => 3D/issues}/issue990.scad (100%) diff --git a/testdata/scad/bugs/issue1004.scad b/testdata/scad/3D/issues/issue1004.scad similarity index 100% rename from testdata/scad/bugs/issue1004.scad rename to testdata/scad/3D/issues/issue1004.scad diff --git a/testdata/scad/bugs/issue1005.scad b/testdata/scad/3D/issues/issue1005.scad similarity index 100% rename from testdata/scad/bugs/issue1005.scad rename to testdata/scad/3D/issues/issue1005.scad diff --git a/testdata/scad/bugs/issue1061.scad b/testdata/scad/3D/issues/issue1061.scad similarity index 100% rename from testdata/scad/bugs/issue1061.scad rename to testdata/scad/3D/issues/issue1061.scad diff --git a/testdata/scad/bugs/issue1069.scad b/testdata/scad/3D/issues/issue1069.scad similarity index 100% rename from testdata/scad/bugs/issue1069.scad rename to testdata/scad/3D/issues/issue1069.scad diff --git a/testdata/scad/bugs/issue835.scad b/testdata/scad/3D/issues/issue835.scad similarity index 100% rename from testdata/scad/bugs/issue835.scad rename to testdata/scad/3D/issues/issue835.scad diff --git a/testdata/scad/bugs/issue911.scad b/testdata/scad/3D/issues/issue911.scad similarity index 100% rename from testdata/scad/bugs/issue911.scad rename to testdata/scad/3D/issues/issue911.scad diff --git a/testdata/scad/bugs/issue913.scad b/testdata/scad/3D/issues/issue913.scad similarity index 100% rename from testdata/scad/bugs/issue913.scad rename to testdata/scad/3D/issues/issue913.scad diff --git a/testdata/scad/bugs/issue964.scad b/testdata/scad/3D/issues/issue964.scad similarity index 100% rename from testdata/scad/bugs/issue964.scad rename to testdata/scad/3D/issues/issue964.scad diff --git a/testdata/scad/bugs/issue964b.scad b/testdata/scad/3D/issues/issue964b.scad similarity index 100% rename from testdata/scad/bugs/issue964b.scad rename to testdata/scad/3D/issues/issue964b.scad diff --git a/testdata/scad/bugs/issue990.scad b/testdata/scad/3D/issues/issue990.scad similarity index 100% rename from testdata/scad/bugs/issue990.scad rename to testdata/scad/3D/issues/issue990.scad diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f40bf4bf..a0bda3dd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1210,30 +1210,16 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue666.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue791.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue802.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue835.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue904.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue911.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue913.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue936.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue945.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue990.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1004.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1005.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1061.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1069.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1089.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) list(REMOVE_ITEM EXPORT3D_TEST_FILES - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad) -list(APPEND EXPORTCSG_TEST_FILES - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue964b.scad) + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad) +#list(APPEND EXPORTCSG_TEST_FILES ) list(APPEND ALL_2D_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad) list(APPEND OPENCSGTEST_FILES ${BUGS_FILES}) From 966add80a82a1456d1db7770d163efb82372579e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 21:43:17 -0500 Subject: [PATCH 258/263] Run fixed bug test cases as part of the normal regression tests --- src/Camera.cc | 22 +++++++++++------- src/Camera.h | 10 ++++---- src/GLView.cc | 13 ++++++----- src/QGLView.cc | 2 +- .../throwntogethertest/issue1004-expected.png | Bin 0 -> 9348 bytes .../throwntogethertest/issue1005-expected.png | Bin 0 -> 4408 bytes .../throwntogethertest/issue1061-expected.png | Bin 0 -> 11401 bytes .../throwntogethertest/issue1069-expected.png | Bin 0 -> 7349 bytes .../throwntogethertest/issue835-expected.png | Bin 0 -> 10134 bytes .../throwntogethertest/issue911-expected.png | Bin 0 -> 7775 bytes .../throwntogethertest/issue913-expected.png | Bin 0 -> 4857 bytes .../throwntogethertest/issue964-expected.png | Bin 0 -> 7631 bytes .../throwntogethertest/issue964b-expected.png | Bin 0 -> 9065 bytes .../throwntogethertest/issue990-expected.png | Bin 0 -> 5983 bytes 14 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 tests/regression/throwntogethertest/issue1004-expected.png create mode 100644 tests/regression/throwntogethertest/issue1005-expected.png create mode 100644 tests/regression/throwntogethertest/issue1061-expected.png create mode 100644 tests/regression/throwntogethertest/issue1069-expected.png create mode 100644 tests/regression/throwntogethertest/issue835-expected.png create mode 100644 tests/regression/throwntogethertest/issue911-expected.png create mode 100644 tests/regression/throwntogethertest/issue913-expected.png create mode 100644 tests/regression/throwntogethertest/issue964-expected.png create mode 100644 tests/regression/throwntogethertest/issue964b-expected.png create mode 100644 tests/regression/throwntogethertest/issue990-expected.png diff --git a/src/Camera.cc b/src/Camera.cc index ccf02062..7e53d363 100644 --- a/src/Camera.cc +++ b/src/Camera.cc @@ -3,13 +3,13 @@ #include "printutils.h" Camera::Camera(enum CameraType camtype) : - type(camtype), projection(Camera::PERSPECTIVE), fov(45), viewall(false), zoom_value(60) + type(camtype), projection(Camera::PERSPECTIVE), fov(45), viewall(false), height(60) { PRINTD("Camera()"); if (this->type == Camera::GIMBAL) { object_trans << 0,0,0; object_rot << 35,0,25; - zoom_value = 500; + viewer_distance = 500; } else if (this->type == Camera::VECTOR) { center << 0,0,0; Eigen::Vector3d cameradir(1, 1, -0.5); @@ -26,7 +26,8 @@ void Camera::setup(std::vector params) type = Camera::GIMBAL; object_trans << params[0], params[1], params[2]; object_rot << params[3], params[4], params[5]; - zoom_value = params[6]; + viewer_distance = params[6]; + height = params[6]; } else if (params.size() == 6) { type = Camera::VECTOR; eye << params[0], params[1], params[2]; @@ -73,13 +74,13 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor) switch (this->projection) { case Camera::ORTHOGONAL: - this->zoom_value = bbox.diagonal().norm(); + this->height = bbox.diagonal().norm(); break; case Camera::PERSPECTIVE: { double radius = bbox.diagonal().norm()/2; switch (this->type) { case Camera::GIMBAL: - this->zoom_value = radius / tan(this->fov*M_PI/360); + this->viewer_distance = radius / tan(this->fov*M_PI/360); break; case Camera::VECTOR: { Vector3d cameradir = (this->center - this->eye).normalized(); @@ -100,7 +101,8 @@ void Camera::viewAll(const BoundingBox &bbox, float scalefactor) void Camera::zoom(int delta) { - this->zoom_value *= pow(0.9, delta / 120.0); + this->viewer_distance *= pow(0.9, delta / 120.0); + this->height = this->viewer_distance; } void Camera::setProjection(ProjectionType type) @@ -110,14 +112,16 @@ void Camera::setProjection(ProjectionType type) void Camera::resetView() { + type = Camera::GIMBAL; object_rot << 35, 0, -25; object_trans << 0, 0, 0; - zoom_value = 140; + height = 140; + viewer_distance = 140; } double Camera::zoomValue() { - return zoom_value; + return this->projection == PERSPECTIVE ? viewer_distance : height; } std::string Camera::statusText() @@ -125,6 +129,6 @@ std::string Camera::statusText() boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f")); fmt % object_trans.x() % object_trans.y() % object_trans.z() % object_rot.x() % object_rot.y() % object_rot.z() - % zoom_value; + % (this->projection == PERSPECTIVE ? viewer_distance : height); return fmt.str(); } diff --git a/src/Camera.h b/src/Camera.h index f736f902..ae9ffaac 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -30,9 +30,9 @@ public: void gimbalDefaultTranslate(); void setProjection(ProjectionType type); void zoom(int delta); + double zoomValue(); void resetView(); void viewAll(const BoundingBox &bbox, float scalefactor = 1.0f); - double zoomValue(); std::string statusText(); // Vectorcam @@ -59,8 +59,8 @@ public: unsigned int pixel_height; protected: - // This is the viewer-distance in perspective mode and in - // ortographic mode, this is defining the viewport height - // (in world-space) - double zoom_value; + // Perspective settings + double viewer_distance; + // Orthographic settings + double height; // world-space height of viewport }; diff --git a/src/GLView.cc b/src/GLView.cc index e79c5fb7..e76a10c3 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -92,21 +92,22 @@ void GLView::setupCamera() switch (this->cam.type) { case Camera::GIMBAL: { + double eyeY = 0.0; switch (this->cam.projection) { case Camera::PERSPECTIVE: { - double dist = cam.zoomValue(); - gluPerspective(cam.fov, aspectratio, 0.1 * dist, 100 * dist); + eyeY = cam.zoomValue(); + gluPerspective(cam.fov, aspectratio, 0.1 * eyeY, 100 * eyeY); break; } case Camera::ORTHOGONAL: { - double height = cam.zoomValue(); - glOrtho(-height/2*aspectratio, height*aspectratio/2, - -height/2, height/2, + eyeY = cam.zoomValue(); + glOrtho(-eyeY/2*aspectratio, eyeY*aspectratio/2, + -eyeY/2, eyeY/2, -far_far_away, +far_far_away); break; } } - gluLookAt(0.0, -cam.zoomValue(), 0.0, + gluLookAt(0.0, -eyeY, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); diff --git a/src/QGLView.cc b/src/QGLView.cc index 43178989..25ca07a2 100644 --- a/src/QGLView.cc +++ b/src/QGLView.cc @@ -64,7 +64,6 @@ static bool running_under_wine = false; void QGLView::init() { - cam.type = Camera::GIMBAL; resetView(); this->mouse_drag_active = false; @@ -245,6 +244,7 @@ void QGLView::mouseMoveEvent(QMouseEvent *event) if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0) { cam.zoom(-12.0 * dy); } else { + double mx = +(dx) * 3.0 * cam.zoomValue() / QWidget::width(); double mz = -(dy) * 3.0 * cam.zoomValue() / QWidget::height(); diff --git a/tests/regression/throwntogethertest/issue1004-expected.png b/tests/regression/throwntogethertest/issue1004-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..46c136ab09176f0c431aa31786a1ccf780adc847 GIT binary patch literal 9348 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 J_jk~v{tqGIDNO(X literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/issue1069-expected.png b/tests/regression/throwntogethertest/issue1069-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..989385eeab098d42872e7f5bb7cc356639c5261c GIT binary patch literal 7349 zcmeHLc|4T+zyHo-#te!?3K z>Y!4Vib29qvXv#(h?x7CbN{=qdtbkMe!t&;_xi{4dgimdKkN7Xea_nL+Ob%4nJ7YN zv89EXJwg~fVu&L67rpG4B7_u9SeltSL=ryt)ZWvqawKz)?G-jT0KG-VNlDV)t#(LPO>!N{v)44 zrO|0w?7%NJUFSsLnad;*@i01$ST`|@cBJ1X4G}Pmy^Kc3>GlLdQt4!_4UPx|#$tiu zZ5&y+MZQs^<2Wi223tuEbfmhj`iL}*PDd_6L<-eHorZp2+FJ_7X{eBZ5h;2KQND3l8E%zPtrESk3?Me|Ka?9cK(m_4y#X@mSn}f z$mDg9r|17PS(tmg`wWFBJu^7R^EzqsJoI-lg}^D@Ed$rhTOLTm+=wLZw+JN89-RtQ zIuYq&r0`|SmK+>ixvSo=X=tg}9@#0ooT0b7Ff3cTu)9VwzP!Hn>SX`Esi0@?8QKIw ztM%p|F`p-n%HpSd#zq26VA@iGcC(iflK6X@6@H=XWF$WU8 z3K^`^8cI&ux#-HHxbM6!je{rdkW}mZ($-#};8TZ6>M!15NuHxpB~;p&QMqX5Y|fh% zWiz`<0+zebjo#UL5L$)1mi9Hg+Dl27rb-N@_olBxy~tR+dtk+qt<)c-mWBZc}&$5V5D5`zqwVdD#9ul5U%l^V0yD_zxD{x5pXf zlfsNy9a#9!j?Ka$^o_nrSfaGu28UJ;x6<9U8o zkzt=E<7usY_1ECBYD!s?e`^)vR_@-GjuoMUVbfLw!v*1rMt4THT^LFcTNr;4G5`2` zP?}s-Ddo0rT?+oZ76*IgYGj|vANdgR8%-ipecjY8MdsNJixqAnx%k?KoQUHk zi``UTy6Sh&r-xlV?qL0hQf3+@>tEBZDq-GUcfrJJfmEyI6W`)ft5r6JGPTY_vDspM`OvnRTi-SfJ7&Ka^)G*py+d^bZ@#IBt=ZBo#5|oOg3hTGWJjFgKuk=;wobu8p>}a4+@b%-FQ8cQW z#HSguW4MnnfuQq?%(;FGf%5HRWt6hH9Cd@uw_s=7(-aO{Q<8XU_i@HklfvImih(jI z;b8nztbCBA$giMY&{|#cHjTZ!B$buwekg~0qG)?b&&A^Is1~m=U2c;zxujQlN~1%`Vv;3+12>tz#nk>RUECE4iOylPr#YZ ztxb}^0g@rU4cgwoA!z4tMA>5{z4E_^YRVzzRLj1vHm49v2YUf&eXcEs_Hh!=f>lO7 zj^r9A`eBIWR?|>JSM&z3e;Rh>^`A<+fY}6N7$g1BYOw#eMA_E}+(X>!i4A{>P&-8m zXO>NF{#93q;XPpsn5k=^QiF$!1wl~=1nP}*YNp^Sgg~$h_$Uejr-1CNZ1j=(Ux~VG zM%7|V_s?G?vJjS7BM5IfA~>C2`)?0VgN#Q!ZYWxAt48OZVLuFH9ewYmk2L9mkn#bt zOr+K-Sa6MyvcXY#LrA1Lkw_8FuQ*q{9NN@Hw zI&$DvCIg|{&X0#kB<8IuyDUvK0aq zefLc-8Y4=>fz|yOqiodyBWTYn z&=4=(_!iK|a{fupN568Q9dul5T*)aDr{>cj#Oq^lb)ot2d*3 zHB3t(Obe$`P8MJph?y;d_`*Cl1=!NA)2qwbWyHI#y(%26` zgM$~H2lK`N)OIfqE^X{O06H)rw+w(rL4GqIj>F}S1rx}wt6#qfvi@}m6&Z*12rhxr zQ023U2Ydk5FdSAJrXa_Gj)$S(P1tY3*YYJ{s(XaPvGv}REXD5(&MY)V** zfFlvXSDdmO21@2oR>{#!OYkKE0>te)MDPXl52>^nUlRBN0g(g-1$@at3e5AP)daq% z6h+iaN@M&gkFjo%uv$`C`>If+`DlDmCMf++1)$)~>;PNvPm}3k@6MOSV%O+BJHmgu9ne?LPXEB zTywB$0Gn@U$QO)iYS7T-br~#ZjO<->)b^wD8rXjU_77QmbHRSTG!=!#77H?e53IPe0`XK>A;Xu3iahmc4t-X$h{t)RAT;}~C1G-~}+XNX{Y9S5nQtYV_ zK&PFh|K5R@`{s(^su~@eKqm++rRRnygQfkz0bIUqS`Mz#p;mdf(=7m%3k->qanorq zng_)^qP|*+MyFkdec)(&A4mfG2!RlEt??{)ieHtqRxl5KpRX-uDPhNZvF@)MNc4;K z1DS%Loaji?-9QMYm7W1XO&`+*ras0>V; z1(WYeAe8uzEE1epVc2twUBw7{QQuD7FLpCZ%wOZsJrw^avgrc+x(cS*>_sIwrKr*n zCiBKYFwM#|WL27O4d&?(lihloU;nP?4~+eSy=v^wO5zvF!RW=21^zYY+5Pk;!D)L2 z!?;OLO#yKogcR)OcNpAnf#RGo5*K8w7&7MWzEK4-1{-wChu|bo3WmM#?(H>sNQ5|q zyz=5nK^irZHVD!fVVWk-^20>>u9Ggd zS+No0{@#)_svYe!ho5uV)ewJb#St}HbApz%llEi0*3mGSJn1s##v=bJK@6dE&NAEd zW8lsBf4Ebo0aK|LcE86vleX;StYdV7yaMZc7!Va@mLc= zM)~YBWI|54qMyn>ij^(c`zq3JckWn}>@@@=Z&svpUb}M?X=TS8#GSZOnTeEAnUZf_ z-`fZtxpVQXgyj{ZPYd433C&Z|c9I>Hm*y2ho1eQ9cZqh++HOn9%oSQAV;EE8#NCu4Euui_ zoREmvki9T(Ly&1QqGgm{F$|&7A62VP)VwO!DhF zTNA>!r3)cU6LQSTDH0SZNjFDrzERe1P z?T<}^Ty7pMmv{|XdpJcbVxR9+3af>}$4Gm@Bl4p0neQhAMum zH52}-_x+S1>C-}lZx-`%7T)aM6P=rNa{Sx((p`XOSBXtPfsoIW&d+LYtbo#h6DPrs z@P}(VhLP{rfJ!HgAhG*r1U*px?Ng|pB7Joyr@URXbZJ;^Ecl5nJ33J)9+2uiJ=3e09`2ntL8N540g^B9dE6}$3vM@J{#`OYuW<_*E>xhSH3|{TW&CeYTa7)qPFgZ6?K}d1I zl9F%ESaVRNIODXs!$s&JSoPZhkaF=6TMl8T`?V*mBP7ws>9ID@15HPp3qsK`&fsW% zDds%r5n;|AXPO_mek>G;$&9_Tdw>n4r#q@L#xA=F8YlOSdLC8X6xqA!p=<3^+p%IA3D)4Wl@juU(;~Sc}7n z2u&E(?`MM@$kdz*6Nj(MM6UiY^9!59&!+HA$#9*|Qp=Ztu6n-*Ozydy?=^~UIDN0L zhS_JFI67uqAsmWC5*I$FInfSvNvIv=nXpApSRkU-cz@eL_Db77PKNUx1{aK6O$ad@ zi|<`6rq4we!XB0_+)=w-^NMg&op=AaFDdi(!I|dqtm}E*Jg=sUa}(Sq{Yo)O zF@N4gm-e^%BgmI@z!O9qoZXq(`!{DMh-a_&$?rZw;%MjfFz1(rr?b#-{PKRz2F9TJ z+j-~WUd01E=~l%?Ka)ROOvN}YoLa^!;YF@w9Tf9?hcAhQO! z@i>Hog;9O_ek6mLx3h-X4+r%W@$IcU=o+of?c;sTuQOt$S_wbv`Y&F_+*rOg?o8e5 z%N0b1(S=Y2KU%g-MS>5nR(M;BiE`=#0p)Q-DOYR??>-nmd2`5VyOV6pG3(MRPS+3PrFY9Oq-0wYWGp z_L%L7b<~HjAZoR$RStm11MiH#S0f2RTAuNNCD< zHiJDYFtqo);tHT*=A+Tyqgg2%0aHy)vz$72b+%yZnKK?|o%Emg79C6P2ju;$bns)? zSSgID{I6Z=C8}%AW$4$DTL`HOk?-UKx$ey^rI>$T8i$ITZLVE z02}Z30sRPNkTR>+N#4NHcZ0*swLRVV5-!fj^_8=}&2DvKbG+QNhFa9Jg{~ASH|){U zxgk?Bm)h}M<_*xN5v%=lXX1Dhs^X_Ct314wU_xkemR5PF7WAUUv~0nzKDa#{JnE0_ zcW@>}2|yG$2KU?)fDk+2(m^sP1rTF{L4$ShN^l?1#Xbu_*eH4!-UkpLN9Eiz=wXnp zI~sU_w`?onrRU1`1u_+Hfgkt{?lpM?7r7cUVHa(?OsH2>Si}`Cwk>_S;~B-BlD?q- zjMEp_ZOoyz5(;;(&hb~7EC%r9!QrXfp%jTr8g<-7s(ncQ^N@V+m5_&R^&8s4F_Urt z8h&rQ^mn#)UoHRP>&Wwh>kn}mbnPLeb33hn51(G>DsTs-ygmw~vE&+jZzd&Quzw>aFfFnb|gni+H@gPB7`!5g_+&n4Z7f@>_64|~o8$H4ECMha9PwNqI p=>n)ryZYg3@azK|^}hqmWunk{yNKcYa|;OmEVu76E8fP4`wyiID0lz> literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/issue835-expected.png b/tests/regression/throwntogethertest/issue835-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..09d0a8c74e87ddf4e2af615c5117c38a44d6efe6 GIT binary patch literal 10134 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 CS3G6_ literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/issue911-expected.png b/tests/regression/throwntogethertest/issue911-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c7aed480e7dcd3124ee8ac7cf0b3a0e018cd3a GIT binary patch literal 7775 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 literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/issue913-expected.png b/tests/regression/throwntogethertest/issue913-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..f2427b72f21ac3d1d7a2b2e81950eec0f902f6fc GIT binary patch literal 4857 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 literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/issue964b-expected.png b/tests/regression/throwntogethertest/issue964b-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..c611ecf26df46dd2dc0149101fcf35a847cd1a5c GIT binary patch literal 9065 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 Date: Mon, 5 Jan 2015 23:30:51 -0500 Subject: [PATCH 259/263] Fix crash when checking if invalid Nef3 is valid --- src/mainwin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwin.cc b/src/mainwin.cc index ff5ff713..67bc93a8 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1931,7 +1931,7 @@ void MainWindow::actionCheckValidity() { N.reset(CGALUtils::createNefPolyhedronFromGeometry(*ps)); } if (N || (N = dynamic_pointer_cast(this->root_geom))) { - valid = N->p3->is_valid(); + valid = N->p3 ? N->p3->is_valid() : false; } PRINTB(" Valid: %6s", (valid ? "yes" : "no")); clearCurrentOutput(); From 02d591556c6f6e8b8a41da857ba8fd89a92e285b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 23:31:03 -0500 Subject: [PATCH 260/263] Moved tests from #936 to #945 --- testdata/scad/bugs/issue945b.scad | 2 ++ .../scad/bugs/{issue936.scad => issue945c.scad} | 0 testdata/scad/bugs/issue945d.scad | 2 ++ tests/CMakeLists.txt | 4 +++- .../cgalpngtest/issue945b-expected.png | Bin 0 -> 8930 bytes ...ue936-expected.png => issue945c-expected.png} | Bin .../cgalpngtest/issue945d-expected.png | Bin 0 -> 7169 bytes .../monotonepngtest/issue945b-expected.png | Bin 0 -> 8930 bytes ...ue936-expected.png => issue945c-expected.png} | Bin .../monotonepngtest/issue945d-expected.png | Bin 0 -> 7169 bytes .../opencsgtest/issue945b-expected.png | Bin 0 -> 9108 bytes ...ue936-expected.png => issue945c-expected.png} | Bin .../opencsgtest/issue945d-expected.png | Bin 0 -> 7378 bytes 13 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 testdata/scad/bugs/issue945b.scad rename testdata/scad/bugs/{issue936.scad => issue945c.scad} (100%) create mode 100644 testdata/scad/bugs/issue945d.scad create mode 100644 tests/regression/cgalpngtest/issue945b-expected.png rename tests/regression/cgalpngtest/{issue936-expected.png => issue945c-expected.png} (100%) create mode 100644 tests/regression/cgalpngtest/issue945d-expected.png create mode 100644 tests/regression/monotonepngtest/issue945b-expected.png rename tests/regression/monotonepngtest/{issue936-expected.png => issue945c-expected.png} (100%) create mode 100644 tests/regression/monotonepngtest/issue945d-expected.png create mode 100644 tests/regression/opencsgtest/issue945b-expected.png rename tests/regression/opencsgtest/{issue936-expected.png => issue945c-expected.png} (100%) create mode 100644 tests/regression/opencsgtest/issue945d-expected.png diff --git a/testdata/scad/bugs/issue945b.scad b/testdata/scad/bugs/issue945b.scad new file mode 100644 index 00000000..b3f75d0a --- /dev/null +++ b/testdata/scad/bugs/issue945b.scad @@ -0,0 +1,2 @@ +rotate([0, 45, 0]) cube(50, true); +rotate([0, 0, 45]) cube(50, true); diff --git a/testdata/scad/bugs/issue936.scad b/testdata/scad/bugs/issue945c.scad similarity index 100% rename from testdata/scad/bugs/issue936.scad rename to testdata/scad/bugs/issue945c.scad diff --git a/testdata/scad/bugs/issue945d.scad b/testdata/scad/bugs/issue945d.scad new file mode 100644 index 00000000..771e0da6 --- /dev/null +++ b/testdata/scad/bugs/issue945d.scad @@ -0,0 +1,2 @@ +translate([-5,5,0]) cube(10); +rotate([0, -90, 0]) cube(10); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a0bda3dd..608b60c1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1212,8 +1212,10 @@ list(APPEND BUGS_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue584.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue802.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue899.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue904.scad - ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue936.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue945.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue945b.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue945c.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue945d.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1089.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/issue1105.scad) list(APPEND EXPORT3D_TEST_FILES ${BUGS_FILES}) diff --git a/tests/regression/cgalpngtest/issue945b-expected.png b/tests/regression/cgalpngtest/issue945b-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..88ee57b229e26577e137fc2a688996bcc7ddcdf3 GIT binary patch literal 8930 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 E0LNe>r2qf` literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/issue936-expected.png b/tests/regression/opencsgtest/issue945c-expected.png similarity index 100% rename from tests/regression/opencsgtest/issue936-expected.png rename to tests/regression/opencsgtest/issue945c-expected.png diff --git a/tests/regression/opencsgtest/issue945d-expected.png b/tests/regression/opencsgtest/issue945d-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..63ecaad1da452d9bae339d27b84e3808bf8029c5 GIT binary patch literal 7378 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 lO Date: Mon, 5 Jan 2015 23:47:48 -0500 Subject: [PATCH 261/263] Minor adjustment to testcase --- testdata/scad/3D/issues/issue835.scad | 2 +- .../throwntogethertest/issue835-expected.png | Bin 10134 -> 9683 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/scad/3D/issues/issue835.scad b/testdata/scad/3D/issues/issue835.scad index 1f467dfc..0de6d455 100644 --- a/testdata/scad/3D/issues/issue835.scad +++ b/testdata/scad/3D/issues/issue835.scad @@ -1,7 +1,7 @@ difference() { cube([20,20,3], center=true); - linear_extrude(height=60, center=true, convexity=2) { + linear_extrude(height=10, center=true, convexity=2) { translate([5,0]) circle(r=3); translate([-5,5]) circle(r=3); translate([-5,-5]) circle(r=3); diff --git a/tests/regression/throwntogethertest/issue835-expected.png b/tests/regression/throwntogethertest/issue835-expected.png index 09d0a8c74e87ddf4e2af615c5117c38a44d6efe6..f35cb9b9d851c84c7fa01b79980f25d9472508af 100644 GIT binary patch literal 9683 zcmeHtX*ksF+y6CVhQVM;GPIbwwaOM!wizkfM97*fx5~Z~iJ6Ha5|z?jVI)g3DEm57 zb}1qxjZw%lcE&PeW}a`q-|>I(fBn3Bj(gtB_c+e$ysq;+kL&uJ>s|BnCK6)uVgLY% z)2B{Y004(R;Q;mLFGAjk3c#Lcr%xDKg~4VRXY-T?>_p}t;S#$tC5~gprU(z#(&J3G z9KPTYjL}6M@4($ZVJNaG^FdbwZZl>F7PEa4rz2J_x8KkZUSB=6UL z_1vFtKNJeE{(KlB5rnP}&yT?12n0!sKmue69FBAUY5E)@!s+rj0*PP_gJDYNb4;Q2 zFlPx2j)2P}0hE1M&t3wF1d4@G7#zlm01(Qx9@01h0oV#5P#Dxf9JsZ0s8ke#!+`>5 zdlW(j0}RFezC%O|=!3RL+!8~PD7UqJAR-EQ{VUGD*7^7D{QI*0kKxXIh~c=;cf`u( zFlNz4V_zyKi^(aWs{Y(?6ssLu7*V}`O#RVr|2VqjOjJ{?Vxw3oDi%dTT|Cl4MNE0G zu9wK5*R36A4}j`JZ%+H{>AKNE8{I9c(zeX21rs&(S8a?b{q;m^6YPsClZ&TeU03W( z^IsA2X7RTlAuJPBDv*TKD_XBz;Vv}-EA!3gv~GM~2?F{TdoGEIPw+)kjDFs}_-PVB z(8^ZBKrlS5gaa$=(6Ug(Mp;Fgz1-v(7+$n?bK#ncL+Lg@#*jr$24{WlOst@7j>l6T z4>&~jL?Y-rvj<*Qjo;(8hg>m|bpF0?4;kAkTXIbaUN4?^GrO>qu_!w@eDB?^%&2K` z1-&=h)I|9Uega+zaecBxKHb}%0Djol_YLy0*AvKRVabivN#x8)v;I5asb_GBGT55( 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 literal 10134 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 CS3G6_ From 57fd4a20bc6a7efbc2e99a009d7fd4374290e8bb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 5 Jan 2015 23:51:21 -0500 Subject: [PATCH 262/263] Minor adjustment to testcase --- testdata/scad/3D/issues/issue1004.scad | 2 +- .../opencsgtest/issue1004-expected.png | Bin 8771 -> 8979 bytes .../throwntogethertest/issue1004-expected.png | Bin 9348 -> 10234 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/scad/3D/issues/issue1004.scad b/testdata/scad/3D/issues/issue1004.scad index c4118712..cf431171 100644 --- a/testdata/scad/3D/issues/issue1004.scad +++ b/testdata/scad/3D/issues/issue1004.scad @@ -1,2 +1,2 @@ %square(20); -cube(10); +translate([1,1,0]) cube(10); diff --git a/tests/regression/opencsgtest/issue1004-expected.png b/tests/regression/opencsgtest/issue1004-expected.png index 8b815e152dc9319f0ed6ae5ec2905dcf1a238a0c..74bd3b0aa466794e1eddd319fb05a2dcb4d90e8c 100644 GIT binary patch literal 8979 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 literal 8771 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 diff --git a/tests/regression/throwntogethertest/issue1004-expected.png b/tests/regression/throwntogethertest/issue1004-expected.png index 46c136ab09176f0c431aa31786a1ccf780adc847..84b1fe3ff744cc698e381e2783c02f2597a86211 100644 GIT binary patch literal 10234 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 Date: Tue, 6 Jan 2015 00:14:14 -0500 Subject: [PATCH 263/263] Suppress a few test cases triggering Gallium bugs on Ubuntu-12.04 --- scripts/travis-ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/travis-ci.sh b/scripts/travis-ci.sh index 1f7cbc22..cc904ad3 100755 --- a/scripts/travis-ci.sh +++ b/scripts/travis-ci.sh @@ -13,7 +13,7 @@ if [[ $? != 0 ]]; then fi # Exclude tests known the cause issues on Travis # opencsgtest_rotate_extrude-tests - Fails on Ubuntu 12.04 using Gallium 0.4 drivers -ctest -j8 -E "opencsgtest_rotate_extrude-tests|opencsgtest_render-tests|opencsgtest_rotate_extrude-hole|opencsgtest_internal-cavity|opencsgtest_internal-cavity-polyhedron|opencsgtest_minkowski3-erosion" +ctest -j8 -E "opencsgtest_rotate_extrude-tests|opencsgtest_render-tests|opencsgtest_rotate_extrude-hole|opencsgtest_internal-cavity|opencsgtest_internal-cavity-polyhedron|opencsgtest_minkowski3-erosion|opencsgtest_issue835|opencsgtest_issue911|opencsgtest_issue913" if [[ $? != 0 ]]; then echo "Test failure" exit 1