Merge branch 'master' of https://github.com/prusa3d/Slic3r
This commit is contained in:
commit
15dbeff0c9
76
doc/Localization_guide.md
Normal file
76
doc/Localization_guide.md
Normal 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.)
|
@ -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.)
|
|
3775
resources/localization/Slic3rPE.pot
Normal file
3775
resources/localization/Slic3rPE.pot
Normal file
File diff suppressed because it is too large
Load Diff
14
resources/localization/list.txt
Normal file
14
resources/localization/list.txt
Normal 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
|
@ -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::vector<double> area;
|
||||||
std::sort(sorted_area.begin(), sorted_area.end(),
|
//std::vector<size_t> sorted_area; // vector of indices
|
||||||
[&area](size_t a, size_t b) { return std::abs(area[a]) > std::abs(area[b]); });
|
//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
|
//// we don't perform a safety offset now because it might reverse cw loops
|
||||||
Polygons p_slices;
|
//Polygons p_slices;
|
||||||
for (std::vector<size_t>::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) {
|
//for (std::vector<size_t>::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) {
|
||||||
/* we rely on the already computed area to determine the winding order
|
// /* we rely on the already computed area to determine the winding order
|
||||||
of the loops, since the Orientation() function provided by Clipper
|
// of the loops, since the Orientation() function provided by Clipper
|
||||||
would do the same, thus repeating the calculation */
|
// would do the same, thus repeating the calculation */
|
||||||
Polygons::const_iterator loop = loops.begin() + *loop_idx;
|
// Polygons::const_iterator loop = loops.begin() + *loop_idx;
|
||||||
if (area[*loop_idx] > +EPSILON)
|
// if (area[*loop_idx] > +EPSILON)
|
||||||
p_slices.push_back(*loop);
|
// p_slices.push_back(*loop);
|
||||||
else if (area[*loop_idx] < -EPSILON)
|
// else if (area[*loop_idx] < -EPSILON)
|
||||||
//FIXME This is arbitrary and possibly very slow.
|
// //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 is inside a polygon, then there is no need to diff.
|
||||||
// If the hole intersects a polygon boundary, then diff it, but then
|
// // If the hole intersects a polygon boundary, then diff it, but then
|
||||||
// there is no guarantee of an ordering of the loops.
|
// // there is no guarantee of an ordering of the loops.
|
||||||
// Maybe we can test for the intersection before running the expensive diff algorithm?
|
// // Maybe we can test for the intersection before running the expensive diff algorithm?
|
||||||
p_slices = diff(p_slices, *loop);
|
// 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
|
||||||
|
Loading…
Reference in New Issue
Block a user