This commit is contained in:
bubnikv 2018-03-02 18:15:15 +01:00
commit 15dbeff0c9
5 changed files with 3903 additions and 74 deletions

76
doc/Localization_guide.md Normal file
View File

@ -0,0 +1,76 @@
# Localization and translation guide
The purpose of this guide is to describe how to contribute to the Slic3rPE translations. We use GNUgettext for extracting string resources from the project and PoEdit for editing translations.
Those are possible to download here:
- https://sourceforge.net/directory/os:windows/?q=gnu+gettext GNUgettext package contains a set of tools to extract strings from the source code and to create the translation Catalog.
- https://poedit.net PoEdit provides good interface for the translators.
After GNUgettext is installed it is recommended to add the path to gettext/bin to PATH variable.
Full manual for GNUgettext you can see here: http://www.gnu.org/software/gettext/manual/gettext.html
### Scenario 1. How do I add a translation or fix the existing translation
1. Get PO-file from corresponding folder here:
https://github.com/prusa3d/Slic3r/tree/master/resources/localization
2. Open this file in PoEdit as "Edit a translation"
3. Apply your corrections to translation
4. Push changed Slic3rPE.po and Slic3rPE.mo (will create automatically after saving of Slic3r.po in PoEdit) back to to the enter folder.
### Scenario 2. How do I add a new language support
1. Get file Slic3rPE.pot here :
https://github.com/prusa3d/Slic3r/tree/master/resources/localization
2. Open it in PoEdit for "Create new translation"
3. Select Translation Language (for example French).
4. As a result you will have fr.po - the file contaning translation to French.
Notice. When the transtation is complete you need to:
- Rename the file to Slic3rPE.po
- Click "Save file" button. Slic3rPE.mo will be created immediatly
- Both Slic3rPE.po and Slic3rPE.mo have to be saved here:
https://github.com/prusa3d/Slic3r/tree/master/resources/localization/fr
( name of folder "fr" means "French" - the translation language).
### Scenario 3. How do I add a new text resource when implementing a feature to Slic3rPE
Each string resource in Slic3rPE available for translation needs to be explicitly marked using L() macro like this:
```C++
auto msg = L("This message to be localized")
```
To get translated text use one of needed macro/function (`_(s)`, `_CHB(s)` or `L_str(s)` ).
If you add new file resourse, add it to list of files contaned macro `L()`
### Scenario 4. How do I use GNUgettext to localize my own application taking Slic3rPE as an example
1. For conviniance create list of files with this macro `L(s)`. We have
https://github.com/prusa3d/Slic3r/tree/master/resources/localization/list.txt.
2. Create template file(*.POT) with GNUgettext command:
```
xgettext --keyword=L --from-code=UTF-8 --debug -o Slic3rPE.pot -f list.txt
```
Use flag `--from-code=UTF-8` to specify that the source strings are in UTF-8 encoding
Use flag `--debug` to correctly extract formated strings(used %d, %s etc.)
3. Create PO- and MO-files for your project as described above.
4. To merge old PO-file with strings from creaded new POT-file use command:
```
msgmerge -N -o new.po old.po new.pot
```
Use option `-N` to not using fuzzy matching when an exact match is not found.
5. To concatenate old PO-file with strings from new PO-file use command:
```
msgcat -o new.po old.po
```
6. Create an English translation catalog with command:
```
msgen -o new.po old.po
```
Notice, in this Catalog it will be totally same strings for initial text and translated.
When you have Catalog to translation open POT or PO file in PoEdit and start to translation.
It's very important to keep attention to every gaps and punctuation. Especially with
formated strings. (used %d, %s etc.)

View File

@ -1,45 +0,0 @@
From the begining you need to have GNUgettext and PoEdit.
GNUgettext package contains a set of tools to extract strings from the source code and
to create the Catalog to translation.
PoEdit provide good interface for the translators.
Those are possible to download here:
GNUgettext - https://sourceforge.net/directory/os:windows/?q=gnu+gettext
PoEdit - https://poedit.net/
When GNUgettext and poEdit are downloaded and installationed, next step is
to add path to gettext/bin directory to your PATH variable.
You can use gettext from cmdline now.
In Slic3rPE we have one macro (L) used to markup strings to localizations.
So, to create Catalog to translation there are next steps:
1. create list of files with this macro (list.txt)
2. create template file(*.POT) with command:
xgettext --keyword=L --from-code=UTF-8 --debug -o Slic3rPE.pot -f list.txt
Use flag --from-code=UTF-8 to specify that the source strings are in UTF-8 encoding
Use flag --debug to correctly extract formated strings(used %d, %s etc.)
3.1 if you start to create PO-file for your projest just open this POT-file in PoEdit.
When you select translation language after first opening of POT-files,
PO-file will be created immediatly.
3.2 if you already have PO-file created before, you have to merge old PO-file with
strings from creaded POT-file. You can do that with command:
msgmerge -N -o new.po old.po new.pot
Use option -N to not using fuzzy matching when an exact match is not found.
3.3 if you already have PO-file created before and new PO-file created from new sourse files
which is not related with first one, you have to concatenate old PO-file with
strings from new PO-file. You can do that with command:
msgcat -o new.po old.po
4. create an English translation catalog with command:
msgen -o new.po old.po
Notice, in this Catalog it will be totally same strings for initial text and translated.
When you have Catalog to translation open POT or PO file in PoEdit and start to translation.
It's very important to keep attention to every gaps and punctuation. Especially with
formated strings. (used %d, %s etc.)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.cpp
c:\src\Slic3r\xs\src\slic3r\GUI\BedShapeDialog.hpp
c:\src\Slic3r\xs\src\slic3r\GUI\GUI.cpp
c:\src\Slic3r\xs\src\slic3r\GUI\Tab.cpp
c:\src\Slic3r\xs\src\slic3r\GUI\Tab.hpp
c:\src\Slic3r\xs\src\slic3r\GUI\Field.cpp
c:\src\Slic3r\xs\src\slic3r\GUI\OptionsGroup.cpp
c:\src\Slic3r\xs\src\slic3r\GUI\2DBed.cpp
c:\src\Slic3r\xs\src\slic3r\GUI\PresetHints.cpp
c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.hpp
c:\src\Slic3r\xs\src\slic3r\GUI\Preferences.cpp
C:\src\Slic3r\xs\src\libslic3r\PrintConfig.cpp
c:\src\Slic3r\lib\Slic3r\GUI\MainFrame.pm
c:\src\Slic3r\lib\Slic3r\GUI\Plater.pm

View File

@ -1186,40 +1186,46 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic
loops correctly in some edge cases when original model had overlapping facets loops correctly in some edge cases when original model had overlapping facets
*/ */
std::vector<double> area; /* The following lines are commented out because they can generate wrong polygons,
std::vector<size_t> sorted_area; // vector of indices see for example issue #661 */
for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) {
area.push_back(loop->area());
sorted_area.push_back(loop - loops.begin());
}
// outer first
std::sort(sorted_area.begin(), sorted_area.end(),
[&area](size_t a, size_t b) { return std::abs(area[a]) > std::abs(area[b]); });
// we don't perform a safety offset now because it might reverse cw loops //std::vector<double> area;
Polygons p_slices; //std::vector<size_t> sorted_area; // vector of indices
for (std::vector<size_t>::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) { //for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) {
/* we rely on the already computed area to determine the winding order // area.push_back(loop->area());
of the loops, since the Orientation() function provided by Clipper // sorted_area.push_back(loop - loops.begin());
would do the same, thus repeating the calculation */ //}
Polygons::const_iterator loop = loops.begin() + *loop_idx; //
if (area[*loop_idx] > +EPSILON) //// outer first
p_slices.push_back(*loop); //std::sort(sorted_area.begin(), sorted_area.end(),
else if (area[*loop_idx] < -EPSILON) // [&area](size_t a, size_t b) { return std::abs(area[a]) > std::abs(area[b]); });
//FIXME This is arbitrary and possibly very slow.
// If the hole is inside a polygon, then there is no need to diff. //// we don't perform a safety offset now because it might reverse cw loops
// If the hole intersects a polygon boundary, then diff it, but then //Polygons p_slices;
// there is no guarantee of an ordering of the loops. //for (std::vector<size_t>::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) {
// Maybe we can test for the intersection before running the expensive diff algorithm? // /* we rely on the already computed area to determine the winding order
p_slices = diff(p_slices, *loop); // of the loops, since the Orientation() function provided by Clipper
} // would do the same, thus repeating the calculation */
// Polygons::const_iterator loop = loops.begin() + *loop_idx;
// if (area[*loop_idx] > +EPSILON)
// p_slices.push_back(*loop);
// else if (area[*loop_idx] < -EPSILON)
// //FIXME This is arbitrary and possibly very slow.
// // If the hole is inside a polygon, then there is no need to diff.
// // If the hole intersects a polygon boundary, then diff it, but then
// // there is no guarantee of an ordering of the loops.
// // Maybe we can test for the intersection before running the expensive diff algorithm?
// p_slices = diff(p_slices, *loop);
//}
// perform a safety offset to merge very close facets (TODO: find test case for this) // perform a safety offset to merge very close facets (TODO: find test case for this)
double safety_offset = scale_(0.0499); double safety_offset = scale_(0.0499);
//FIXME see https://github.com/prusa3d/Slic3r/issues/520 //FIXME see https://github.com/prusa3d/Slic3r/issues/520
// double safety_offset = scale_(0.0001); // double safety_offset = scale_(0.0001);
ExPolygons ex_slices = offset2_ex(p_slices, +safety_offset, -safety_offset);
/* The following line is commented out because it can generate wrong polygons,
see for example issue #661 */
//ExPolygons ex_slices = offset2_ex(p_slices, +safety_offset, -safety_offset);
#ifdef SLIC3R_TRIANGLEMESH_DEBUG #ifdef SLIC3R_TRIANGLEMESH_DEBUG
size_t holes_count = 0; size_t holes_count = 0;
@ -1230,7 +1236,10 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic
#endif #endif
// append to the supplied collection // append to the supplied collection
expolygons_append(*slices, ex_slices); /* Fix for issue #661 { */
expolygons_append(*slices, offset2_ex(union_(loops, false), +safety_offset, -safety_offset));
//expolygons_append(*slices, ex_slices);
/* } */
} }
void TriangleMeshSlicer::make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices) const void TriangleMeshSlicer::make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices) const