From 34a5d87011748dcf07943f29726a73cc04fbfaaf Mon Sep 17 00:00:00 2001 From: EvilSpirit Date: Fri, 29 Jan 2016 16:33:56 +0600 Subject: [PATCH] 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. --- src/confscreen.cpp | 6 +++--- src/generate.cpp | 25 +++++++++++++++++++------ src/solvespace.cpp | 6 +++--- src/solvespace.h | 3 ++- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/confscreen.cpp b/src/confscreen.cpp index 8f01108a3..e518e1bd5 100644 --- a/src/confscreen.cpp +++ b/src/confscreen.cpp @@ -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", diff --git a/src/generate.cpp b/src/generate.cpp index 6cd3579e9..4e248b57d 100644 --- a/src/generate.cpp +++ b/src/generate.cpp @@ -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 @@ 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) { diff --git a/src/solvespace.cpp b/src/solvespace.cpp index fdc3d45f9..e4b646cb2 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -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; diff --git a/src/solvespace.h b/src/solvespace.h index 4ee1775f6..c7e251d83 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -753,6 +753,7 @@ class SolveSpaceUI { double lightIntensity[2]; double ambientIntensity; double chordTol; + double chordTolCalculated; int maxSegments; double exportChordTol; int exportMaxSegments; @@ -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);