Use relative chord tolerance instead of absolute.
Commit 89eb208
has improved the overall situation with chord
tolerance, but it changed the display chord tolerance to use
an absolute value in millimeters as a stopgap measure.
This commit changes the display chord tolerance to be specified
in percents of entity bounding box instead of millimeters.
As a result, the linearized curves are both zoom level and sketch
scale independent.
In order to compute the bounding box, all entities are generated
twice. However, this shouldn't result in a noticeable slowdown,
since the bounding box calculation does not need the expensive
triangle mesh generation and the solver will converge immediately
on the second run.
Since the meaning of the preference has changed, a new name is
used (ChordTolerancePct instead of ChordTolerance), so that it
would be reset to the default value after updating SolveSpace.
The default value, 0.5%, was selected using trial and error by
judging whether cylinders of moderate dimensions were looking
aesthetically pleasing enough.
After this change, the only real function of the spacebar
shortcut is to reload imported groups, since manual regeneration
should not change anything anymore unless there is a bug.
pull/4/head
parent
fc68804f65
commit
34a5d87011
|
@ -186,10 +186,10 @@ void TextWindow::ShowConfiguration(void) {
|
|||
}
|
||||
|
||||
Printf(false, "");
|
||||
Printf(false, "%Ft chord tolerance (in screen pixels)%E");
|
||||
Printf(false, "%Ba %@ %Fl%Ll%f%D[change]%E; now %d triangles",
|
||||
Printf(false, "%Ft chord tolerance (in percents)%E");
|
||||
Printf(false, "%Ba %@ %% %Fl%Ll%f%D[change]%E; %@ mm, %d triangles",
|
||||
SS.chordTol,
|
||||
&ScreenChangeChordTolerance, 0,
|
||||
&ScreenChangeChordTolerance, 0, SS.chordTolCalculated,
|
||||
SK.GetGroup(SS.GW.activeGroup)->displayMesh.l.n);
|
||||
Printf(false, "%Ft max piecewise linear segments%E");
|
||||
Printf(false, "%Ba %d %Fl%Ll%f[change]%E",
|
||||
|
|
|
@ -174,7 +174,7 @@ void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree) {
|
|||
}
|
||||
}
|
||||
|
||||
void SolveSpaceUI::GenerateAll(int first, int last, bool andFindFree) {
|
||||
void SolveSpaceUI::GenerateAll(int first, int last, bool andFindFree, bool genForBBox) {
|
||||
int i, j;
|
||||
|
||||
// generate until active group
|
||||
|
@ -183,6 +183,16 @@ void SolveSpaceUI::GenerateAll(int first, int last, bool andFindFree) {
|
|||
if(last == -1) last = INT_MAX;
|
||||
}
|
||||
|
||||
// If we're generating entities for display, first we need to find
|
||||
// the bounding box to turn relative chord tolerance to absolute.
|
||||
if(!SS.exportMode && !genForBBox) {
|
||||
GenerateAll(first, last, false, true);
|
||||
BBox box = SK.CalculateEntityBBox(false);
|
||||
Vector size = box.maxp.Minus(box.minp);
|
||||
double maxSize = std::max({ size.x, size.y, size.z });
|
||||
chordTolCalculated = maxSize * chordTol / 100.0;
|
||||
}
|
||||
|
||||
// Remove any requests or constraints that refer to a nonexistent
|
||||
// group; can check those immediately, since we know what the list
|
||||
// of groups should be.
|
||||
|
@ -275,10 +285,13 @@ void SolveSpaceUI::GenerateAll(int first, int last, bool andFindFree) {
|
|||
if(i >= first && i <= last) {
|
||||
// The group falls inside the range, so really solve it,
|
||||
// and then regenerate the mesh based on the solved stuff.
|
||||
SolveGroup(g->h, andFindFree);
|
||||
g->GenerateLoops();
|
||||
g->GenerateShellAndMesh();
|
||||
g->clean = true;
|
||||
if(genForBBox) {
|
||||
SolveGroup(g->h, andFindFree);
|
||||
} else {
|
||||
g->GenerateLoops();
|
||||
g->GenerateShellAndMesh();
|
||||
g->clean = true;
|
||||
}
|
||||
} else {
|
||||
// The group falls outside the range, so just assume that
|
||||
// it's good wherever we left it. The mesh is unchanged,
|
||||
|
@ -364,7 +377,7 @@ pruned:
|
|||
SK.param.Clear();
|
||||
prev.MoveSelfInto(&(SK.param));
|
||||
// Try again
|
||||
GenerateAll(first, last);
|
||||
GenerateAll(first, last, andFindFree, genForBBox);
|
||||
}
|
||||
|
||||
void SolveSpaceUI::ForceReferences(void) {
|
||||
|
|
|
@ -39,7 +39,7 @@ void SolveSpaceUI::Init() {
|
|||
|
||||
exportMode = false;
|
||||
// Chord tolerance
|
||||
chordTol = CnfThawFloat(2.0f, "ChordTolerance");
|
||||
chordTol = CnfThawFloat(0.5f, "ChordTolerancePct");
|
||||
// Max pwl segments to generate
|
||||
maxSegments = CnfThawInt(10, "MaxSegments");
|
||||
// Chord tolerance
|
||||
|
@ -160,7 +160,7 @@ void SolveSpaceUI::Exit(void) {
|
|||
CnfFreezeFloat((float)lightDir[1].y, "LightDir_1_Up");
|
||||
CnfFreezeFloat((float)lightDir[1].z, "LightDir_1_Forward");
|
||||
// Chord tolerance
|
||||
CnfFreezeFloat((float)chordTol, "ChordTolerance");
|
||||
CnfFreezeFloat((float)chordTol, "ChordTolerancePct");
|
||||
// Max pwl segments to generate
|
||||
CnfFreezeInt((uint32_t)maxSegments, "MaxSegments");
|
||||
// Export Chord tolerance
|
||||
|
@ -270,7 +270,7 @@ double SolveSpaceUI::StringToMm(const std::string &str) {
|
|||
}
|
||||
double SolveSpaceUI::ChordTolMm(void) {
|
||||
if(exportMode) return ExportChordTolMm();
|
||||
return chordTol / GW.scale;
|
||||
return chordTolCalculated;
|
||||
}
|
||||
double SolveSpaceUI::ExportChordTolMm(void) {
|
||||
return exportChordTol / exportScale;
|
||||
|
|
|
@ -753,6 +753,7 @@ public:
|
|||
double lightIntensity[2];
|
||||
double ambientIntensity;
|
||||
double chordTol;
|
||||
double chordTolCalculated;
|
||||
int maxSegments;
|
||||
double exportChordTol;
|
||||
int exportMaxSegments;
|
||||
|
@ -941,7 +942,7 @@ public:
|
|||
|
||||
void GenerateAll(GenerateType type, bool andFindFree = false);
|
||||
void GenerateAll(void);
|
||||
void GenerateAll(int first, int last, bool andFindFree=false);
|
||||
void GenerateAll(int first, int last, bool andFindFree = false, bool genForBBox = false);
|
||||
void SolveGroup(hGroup hg, bool andFindFree);
|
||||
void MarkDraggedParams(void);
|
||||
void ForceReferences(void);
|
||||
|
|
Loading…
Reference in New Issue