Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair

This commit is contained in:
Enrico Turri 2018-02-26 08:32:04 +01:00
commit eb2d689971
6 changed files with 3944 additions and 231 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

@ -9,149 +9,74 @@
namespace Slic3r { namespace Slic3r {
Polyline FillGyroid::makeLineVert(double xPos, double yPos, double width, double height, double currentXBegin, double segmentSize, coord_t scaleFactor, static inline Polyline make_wave_vertical(
double zCs, double zSn, bool flip, double decal){ double width, double height, double x0,
double maxSlope = abs(abs(zCs)-abs(zSn)); double segmentSize, double scaleFactor,
Polyline polyline; double z_cos, double z_sin, bool flip)
polyline.points.push_back(Point(coord_t((std::max(std::min(currentXBegin, xPos+width),xPos) + decal) * scaleFactor), coord_t(yPos * scaleFactor)));
for(double y=yPos;y<yPos+height+segmentSize;y+=segmentSize){
if(y>yPos+height) y = yPos+height;
double ySn = sin(y +(zCs<0?3.14:0) + 3.14);
double yCs = cos(y +(zCs<0?3.14:0) + 3.14+(!flip?0:3.14));
double a = ySn;
double b = -zCs;
double res = zSn*yCs;
double r = sqrt(a*a + b*b);
double x = asin(a/r) + asin(res/r) +3.14;
x += currentXBegin;
double ydeviation = 0.5*(flip?-1:1)*(zSn>0?-1:1)*decal*(1-maxSlope)*(res/r - a/r);
polyline.points.push_back(Point(coord_t((std::max(std::min(x, xPos+width),xPos)+decal-ydeviation/2) * scaleFactor), coord_t((y + ydeviation) * scaleFactor)));
}
return polyline;
}
Polyline FillGyroid::makeLineHori(double xPos, double yPos, double width, double height, double currentYBegin, double segmentSize, coord_t scaleFactor,
double zCs, double zSn, bool flip, double decal){
double maxSlope = abs(abs(zCs)-abs(zSn));
Polyline polyline;
polyline.points.push_back(Point(coord_t(xPos * scaleFactor), coord_t((std::max(std::min(currentYBegin, yPos+height),yPos)+decal) * scaleFactor)));
for(double x=xPos;x<xPos+width+segmentSize;x+=segmentSize){
if(x>xPos+width) x = xPos+width;
double xSn = sin(x +(zSn<0?3.14:0) +(flip?0:3.14));
double xCs = cos(x +(zSn<0?3.14:0) );
double a = xCs;
double b = -zSn;
double res = zCs*xSn;
double r = sqrt(a*a + b*b);
double y = asin(a/r) + asin(res/r) +3.14/2;
y += currentYBegin;
double xdeviation = 0.5*(flip?-1:1)*(zCs>0?-1:1)*decal*(1-maxSlope)*(res/r - a/r);
polyline.points.push_back(Point(coord_t((x + xdeviation) * scaleFactor), coord_t((std::max(std::min(y, yPos+height),yPos)+decal-xdeviation/2) * scaleFactor)));
}
return polyline;
}
inline void FillGyroid::correctOrderAndAdd(const int num, Polyline poly, Polylines &array){
if(num%2==0){
Points temp(poly.points.rbegin(), poly.points.rend());
poly.points.assign(temp.begin(),temp.end());
}
array.push_back(poly);
}
// Generate a set of curves (array of array of 2d points) that describe a
// horizontal slice of a truncated regular octahedron with a specified
// grid square size.
Polylines FillGyroid::makeGrid(coord_t gridZ, double density, double layer_width, size_t gridWidth, size_t gridHeight, size_t curveType)
{ {
coord_t scaleFactor = coord_t(scale_(layer_width) / density); Polyline polyline;
Polylines result; polyline.points.emplace_back(Point(coord_t(clamp(0., width, x0) * scaleFactor), 0));
Polyline *polyline2; double phase_offset_sin = (z_cos < 0 ? M_PI : 0) + M_PI;
double segmentSize = density/2; double phase_offset_cos = (z_cos < 0 ? M_PI : 0) + M_PI + (flip ? M_PI : 0.);
double decal = layer_width*density; for (double y = 0.; y < height + segmentSize; y += segmentSize) {
double xPos = 0, yPos=0, width=gridWidth, height=gridHeight; y = std::min(y, height);
//scale factor for 5% : 8 712 388 double a = sin(y + phase_offset_sin);
// 1z = 10^-6 mm ? double b = - z_cos;
double z = gridZ/(1.0 * scaleFactor); double res = z_sin * cos(y + phase_offset_cos);
double zSn = sin(z); double r = sqrt(sqr(a) + sqr(b));
double zCs = cos(z); double x = clamp(0., width, asin(a/r) + asin(res/r) + M_PI + x0);
polyline.points.emplace_back(convert_to<Point>(Pointf(x, y) * scaleFactor));
}
int numLine = 0; if (flip)
std::reverse(polyline.points.begin(), polyline.points.end());
if(abs(zSn)<=abs(zCs)){ return polyline;
//vertical }
//begin to first one
int iter = 1; static inline Polyline make_wave_horizontal(
double currentXBegin = xPos - PI/2; double width, double height, double y0,
currentXBegin = PI*(int)(currentXBegin/PI -1); double segmentSize, double scaleFactor,
iter = (int)(currentXBegin/PI +1)%2; double z_cos, double z_sin, bool flip)
bool flip = iter%2==1; {
// bool needNewLine =false; Polyline polyline;
while(currentXBegin<xPos+width-PI/2){ polyline.points.emplace_back(Point(0, coord_t(clamp(0., height, y0) * scaleFactor)));
double phase_offset_sin = (z_sin < 0 ? M_PI : 0) + (flip ? 0 : M_PI);
correctOrderAndAdd(numLine, makeLineVert(xPos, yPos, width, height, currentXBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result); double phase_offset_cos = z_sin < 0 ? M_PI : 0.;
numLine++; for (double x=0.; x < width + segmentSize; x += segmentSize) {
x = std::min(x, width);
//then, return by the other side double a = cos(x + phase_offset_cos);
iter++; double b = - z_sin;
currentXBegin = currentXBegin + PI; double res = z_cos * sin(x + phase_offset_sin);
flip = iter%2==1; double r = sqrt(sqr(a) + sqr(b));
double y = clamp(0., height, asin(a/r) + asin(res/r) + 0.5 * M_PI + y0);
if(currentXBegin < xPos+width-PI/2){ polyline.points.emplace_back(convert_to<Point>(Pointf(x, y) * scaleFactor));
}
correctOrderAndAdd(numLine, makeLineVert(xPos, yPos, width, height, currentXBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result); if (flip)
numLine++; std::reverse(polyline.points.begin(), polyline.points.end());
return polyline;
// relance }
iter++;
currentXBegin = currentXBegin + PI; static Polylines make_gyroid_waves(double gridZ, double density, double layer_width, double width, double height)
flip = iter%2==1; {
} double scaleFactor = scale_(layer_width) / density;
} double segmentSize = 0.5 * density;
}else{ //scale factor for 5% : 8 712 388
//horizontal // 1z = 10^-6 mm ?
double z = gridZ / scaleFactor;
double z_sin = sin(z);
//begin to first one double z_cos = cos(z);
int iter = 1; Polylines result;
//search first line output if (abs(z_sin) <= abs(z_cos)) {
double currentYBegin = yPos ; // Vertical wave
currentYBegin = PI*(int)(currentYBegin/PI -0); double x0 = M_PI * (int)((- 0.5 * M_PI) / M_PI - 1.);
iter = (int)(currentYBegin/PI +1)%2; bool flip = ((int)(x0 / M_PI + 1.) & 1) != 0;
for (; x0 < width - 0.5 * M_PI; x0 += M_PI, flip = ! flip)
bool flip = iter%2==1; result.emplace_back(make_wave_vertical(width, height, x0, segmentSize, scaleFactor, z_cos, z_sin, flip));
} else {
// Horizontal wave
while(currentYBegin < yPos+width){ bool flip = true;
for (double y0 = 0.; y0 < width; y0 += M_PI, flip = !flip)
correctOrderAndAdd(numLine, makeLineHori(xPos, yPos, width, height, currentYBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result); result.emplace_back(make_wave_horizontal(width, height, y0, segmentSize, scaleFactor, z_cos, z_sin, flip));
numLine++;
//then, return by the other side
iter++;
currentYBegin = currentYBegin + PI;
flip = iter%2==1;
if(currentYBegin<yPos+width){
correctOrderAndAdd(numLine, makeLineHori(xPos, yPos, width, height, currentYBegin, segmentSize, scaleFactor, zCs, zSn, flip, 0), result);
numLine++;
//relance
iter++;
currentYBegin = currentYBegin + PI;
flip = iter%2==1;
}
}
} }
return result; return result;
} }
@ -170,18 +95,16 @@ void FillGyroid::_fill_surface_single(
bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance))); bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance)));
// generate pattern // generate pattern
Polylines polylines = makeGrid( Polylines polylines = make_gyroid_waves(
(coord_t)scale_(this->z), scale_(this->z),
params.density*this->scaling, params.density*this->scaling,
this->spacing, this->spacing,
(size_t)(ceil(bb.size().x / distance) + 1), ceil(bb.size().x / distance) + 1.,
(size_t)(ceil(bb.size().y / distance) + 1), ceil(bb.size().y / distance) + 1.);
(size_t)(((this->layer_id/thickness_layers) % 2) + 1) );
// move pattern in place // move pattern in place
for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it) for (Polyline &polyline : polylines)
it->translate(bb.min.x, bb.min.y); polyline.translate(bb.min.x, bb.min.y);
// clip pattern to boundaries // clip pattern to boundaries
polylines = intersection_pl(polylines, (Polygons)expolygon); polylines = intersection_pl(polylines, (Polygons)expolygon);
@ -198,18 +121,14 @@ void FillGyroid::_fill_surface_single(
} }
} }
Polylines chained = PolylineCollection::chained_path_from( Polylines chained = PolylineCollection::chained_path_from(
#if SLIC3R_CPPVER >= 11
std::move(polylines), std::move(polylines),
#else
polylines,
#endif
PolylineCollection::leftmost_point(polylines), false); // reverse allowed PolylineCollection::leftmost_point(polylines), false); // reverse allowed
bool first = true; bool first = true;
for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) { for (Polyline &polyline : chained) {
if (! first) { if (! first) {
// Try to connect the lines. // Try to connect the lines.
Points &pts_end = polylines_out.back().points; Points &pts_end = polylines_out.back().points;
const Point &first_point = it_polyline->points.front(); const Point &first_point = polyline.points.front();
const Point &last_point = pts_end.back(); const Point &last_point = pts_end.back();
// TODO: we should also check that both points are on a fill_boundary to avoid // TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions // connecting paths on the boundaries of internal regions
@ -217,17 +136,12 @@ void FillGyroid::_fill_surface_single(
if (first_point.distance_to(last_point) <= 5 * distance && if (first_point.distance_to(last_point) <= 5 * distance &&
expolygon_off.contains(Line(last_point, first_point))) { expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline. // Append the polyline.
pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end()); pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
continue; continue;
} }
} }
// The lines cannot be connected. // The lines cannot be connected.
#if SLIC3R_CPPVER >= 11 polylines_out.emplace_back(std::move(polyline));
polylines_out.push_back(std::move(*it_polyline));
#else
polylines_out.push_back(Polyline());
std::swap(polylines_out.back(), *it_polyline);
#endif
first = false; first = false;
} }
} }

View File

@ -1,8 +1,6 @@
#ifndef slic3r_FillGyroid_hpp_ #ifndef slic3r_FillGyroid_hpp_
#define slic3r_FillGyroid_hpp_ #define slic3r_FillGyroid_hpp_
#include <map>
#include "../libslic3r.h" #include "../libslic3r.h"
#include "FillBase.hpp" #include "FillBase.hpp"
@ -12,10 +10,8 @@ namespace Slic3r {
class FillGyroid : public Fill class FillGyroid : public Fill
{ {
public: public:
FillGyroid() {}
FillGyroid(){ scaling = 1.75; } virtual Fill* clone() const { return new FillGyroid(*this); }
virtual Fill* clone() const { return new FillGyroid(*this); };
virtual ~FillGyroid() {}
// require bridge flow since most of this pattern hangs in air // require bridge flow since most of this pattern hangs in air
virtual bool use_bridge_flow() const { return true; } virtual bool use_bridge_flow() const { return true; }
@ -23,8 +19,7 @@ public:
protected: protected:
// mult of density, to have a good %of weight for each density parameter // mult of density, to have a good %of weight for each density parameter
float scaling; float scaling = 1.75;
virtual void _fill_surface_single( virtual void _fill_surface_single(
const FillParams &params, const FillParams &params,
@ -32,22 +27,6 @@ protected:
const std::pair<float, Point> &direction, const std::pair<float, Point> &direction,
ExPolygon &expolygon, ExPolygon &expolygon,
Polylines &polylines_out); Polylines &polylines_out);
// create the gyroid grid to clip.
Polylines makeGrid(coord_t gridZ, double density, double layer_width, size_t gridWidth, size_t gridHeight, size_t curveType);
//add line poly in reverse if needed into array
inline void correctOrderAndAdd(const int num, Polyline poly, Polylines &array);
//create a curved horinzontal line (for each x, compute y)
Polyline makeLineHori(double xPos, double yPos, double width, double height,
double currentYBegin, double segmentSize, coord_t scaleFactor,
double zCs, double zSn,
bool flip, double decal=0);
//create a curved vertival line (for each y, compute x)
Polyline makeLineVert(double xPos, double yPos, double width, double height,
double currentXBegin, double segmentSize, coord_t scaleFactor,
double zCs, double zSn,
bool flip, double decal=0);
}; };
} // namespace Slic3r } // namespace Slic3r