Skip to content

Commit

Permalink
Use relative chord tolerance instead of absolute.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Evil-Spirit authored and whitequark committed Feb 13, 2016
1 parent fc68804 commit 34a5d87
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/confscreen.cpp
Expand Up @@ -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",
Expand Down
25 changes: 19 additions & 6 deletions src/generate.cpp
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -364,7 +377,7 @@ void SolveSpaceUI::GenerateAll(int first, int last, bool andFindFree) {
SK.param.Clear();
prev.MoveSelfInto(&(SK.param));
// Try again
GenerateAll(first, last);
GenerateAll(first, last, andFindFree, genForBBox);
}

void SolveSpaceUI::ForceReferences(void) {
Expand Down
6 changes: 3 additions & 3 deletions src/solvespace.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/solvespace.h
Expand Up @@ -753,6 +753,7 @@ class SolveSpaceUI {
double lightIntensity[2];
double ambientIntensity;
double chordTol;
double chordTolCalculated;
int maxSegments;
double exportChordTol;
int exportMaxSegments;
Expand Down Expand Up @@ -941,7 +942,7 @@ class SolveSpaceUI {

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);
Expand Down

0 comments on commit 34a5d87

Please sign in to comment.