GeezerVison is showing github.com — Use a separate value of chord tolerance for exporting. · realthunder/solvespace@89eb208
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: src/confscreen.cpp +37-5Lines changed: 37 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -26,13 +26,27 @@ void TextWindow::ScreenChangeColor(int link, uint32_t v) { | 26 | 26 | } | 27 | 27 |
| 28 | 28 | void TextWindow::ScreenChangeChordTolerance(int link, uint32_t v) { | 29 | | - SS.TW.ShowEditControl(3, ssprintf("%.2f", SS.chordTol)); | | 29 | + SS.TW.ShowEditControl(3, ssprintf("%lg", SS.chordTol)); | 30 | 30 | SS.TW.edit.meaning = EDIT_CHORD_TOLERANCE; | | 31 | + SS.TW.edit.i = 0; | 31 | 32 | } | 32 | 33 |
| 33 | 34 | void TextWindow::ScreenChangeMaxSegments(int link, uint32_t v) { | 34 | 35 | SS.TW.ShowEditControl(3, ssprintf("%d", SS.maxSegments)); | 35 | 36 | SS.TW.edit.meaning = EDIT_MAX_SEGMENTS; | | 37 | + SS.TW.edit.i = 0; | | 38 | +} | | 39 | + | | 40 | +void TextWindow::ScreenChangeExportChordTolerance(int link, uint32_t v) { | | 41 | + SS.TW.ShowEditControl(3, ssprintf("%lg", SS.exportChordTol)); | | 42 | + SS.TW.edit.meaning = EDIT_CHORD_TOLERANCE; | | 43 | + SS.TW.edit.i = 1; | | 44 | +} | | 45 | + | | 46 | +void TextWindow::ScreenChangeExportMaxSegments(int link, uint32_t v) { | | 47 | + SS.TW.ShowEditControl(3, ssprintf("%d", SS.exportMaxSegments)); | | 48 | + SS.TW.edit.meaning = EDIT_MAX_SEGMENTS; | | 49 | + SS.TW.edit.i = 1; | 36 | 50 | } | 37 | 51 |
| 38 | 52 | void TextWindow::ScreenChangeCameraTangent(int link, uint32_t v) { | @@ -182,6 +196,16 @@ void TextWindow::ShowConfiguration(void) { | 182 | 196 | SS.maxSegments, | 183 | 197 | &ScreenChangeMaxSegments); | 184 | 198 |
| | 199 | + Printf(false, ""); | | 200 | + Printf(false, "%Ft export chord tolerance (in mm)%E"); | | 201 | + Printf(false, "%Ba %@ %Fl%Ll%f%D[change]%E", | | 202 | + SS.exportChordTol, | | 203 | + &ScreenChangeExportChordTolerance, 0); | | 204 | + Printf(false, "%Ft export max piecewise linear segments%E"); | | 205 | + Printf(false, "%Ba %d %Fl%Ll%f[change]%E", | | 206 | + SS.exportMaxSegments, | | 207 | + &ScreenChangeExportMaxSegments); | | 208 | + | 185 | 209 | Printf(false, ""); | 186 | 210 | Printf(false, "%Ft perspective factor (0 for parallel)%E"); | 187 | 211 | Printf(false, "%Ba %# %Fl%Ll%f%D[change]%E", | @@ -312,13 +336,21 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) { | 312 | 336 | break; | 313 | 337 | } | 314 | 338 | case EDIT_CHORD_TOLERANCE: { | 315 | | - SS.chordTol = min(10.0, max(0.1, atof(s))); | 316 | | - SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); | | 339 | + if(edit.i == 0) { | | 340 | + SS.chordTol = max(0.0, atof(s)); | | 341 | + SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); | | 342 | + } else { | | 343 | + SS.exportChordTol = max(0.0, atof(s)); | | 344 | + } | 317 | 345 | break; | 318 | 346 | } | 319 | 347 | case EDIT_MAX_SEGMENTS: { | 320 | | - SS.maxSegments = min(1000, max(7, atoi(s))); | 321 | | - SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); | | 348 | + if(edit.i == 0) { | | 349 | + SS.maxSegments = min(1000, max(7, atoi(s))); | | 350 | + SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); | | 351 | + } else { | | 352 | + SS.exportMaxSegments = min(1000, max(7, atoi(s))); | | 353 | + } | 322 | 354 | break; | 323 | 355 | } | 324 | 356 | case EDIT_CAMERA_TANGENT: { | |
Collapse file Copy file name to clipboardExpand all lines: src/draw.cpp +28-17Lines changed: 28 additions & 17 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -796,28 +796,39 @@ nogrid:; | 796 | 796 |
| 797 | 797 | // A note to indicate the origin in the just-exported file. | 798 | 798 | if(SS.justExportedInfo.draw) { | 799 | | - ssglColorRGB(Style::Color(Style::DATUM)); | 800 | | - Vector p = SS.justExportedInfo.pt, | 801 | | - u = SS.justExportedInfo.u, | 802 | | - v = SS.justExportedInfo.v; | | 799 | + Vector p, u, v; | | 800 | + if(SS.justExportedInfo.showOrigin) { | | 801 | + p = SS.justExportedInfo.pt, | | 802 | + u = SS.justExportedInfo.u, | | 803 | + v = SS.justExportedInfo.v; | | 804 | + } else { | | 805 | + p = SS.GW.offset.ScaledBy(-1); | | 806 | + u = SS.GW.projRight; | | 807 | + v = SS.GW.projUp; | | 808 | + } | 803 | 809 |
| 804 | | - ssglLineWidth(1.5); | 805 | | - glBegin(GL_LINES); | 806 | | - ssglVertex3v(p.Plus(u.WithMagnitude(-15/scale))); | 807 | | - ssglVertex3v(p.Plus(u.WithMagnitude(30/scale))); | 808 | | - ssglVertex3v(p.Plus(v.WithMagnitude(-15/scale))); | 809 | | - ssglVertex3v(p.Plus(v.WithMagnitude(30/scale))); | 810 | | - glEnd(); | | 810 | + ssglColorRGB(Style::Color(Style::DATUM)); | 811 | 811 |
| 812 | | - ssglWriteText("(x, y) = (0, 0) for file just exported", | | 812 | + ssglWriteText("previewing exported geometry; press Esc to return", | 813 | 813 | DEFAULT_TEXT_HEIGHT, | 814 | 814 | p.Plus(u.ScaledBy(10/scale)).Plus(v.ScaledBy(10/scale)), | 815 | 815 | u, v, NULL, NULL); | 816 | | - ssglWriteText("press Esc to clear this message", | 817 | | - DEFAULT_TEXT_HEIGHT, | 818 | | - p.Plus(u.ScaledBy(40/scale)).Plus( | 819 | | - v.ScaledBy(-(DEFAULT_TEXT_HEIGHT)/scale)), | 820 | | - u, v, NULL, NULL); | | 816 | + | | 817 | + if(SS.justExportedInfo.showOrigin) { | | 818 | + ssglLineWidth(1.5); | | 819 | + glBegin(GL_LINES); | | 820 | + ssglVertex3v(p.Plus(u.WithMagnitude(-15/scale))); | | 821 | + ssglVertex3v(p.Plus(u.WithMagnitude(30/scale))); | | 822 | + ssglVertex3v(p.Plus(v.WithMagnitude(-15/scale))); | | 823 | + ssglVertex3v(p.Plus(v.WithMagnitude(30/scale))); | | 824 | + glEnd(); | | 825 | + | | 826 | + ssglWriteText("(x, y) = (0, 0) for file just exported", | | 827 | + DEFAULT_TEXT_HEIGHT, | | 828 | + p.Plus(u.ScaledBy(40/scale)).Plus( | | 829 | + v.ScaledBy(-(DEFAULT_TEXT_HEIGHT)/scale)), | | 830 | + u, v, NULL, NULL); | | 831 | + } | 821 | 832 | } | 822 | 833 |
| 823 | 834 | // And finally the toolbar. | |
Collapse file Copy file name to clipboardExpand all lines: src/export.cpp +22-5Lines changed: 22 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -112,6 +112,9 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool wir | 112 | 112 | SEdgeList edges = {}; | 113 | 113 | SBezierList beziers = {}; | 114 | 114 |
| | 115 | + SS.exportMode = true; | | 116 | + GenerateAll(GENERATE_ALL); | | 117 | + | 115 | 118 | SMesh *sm = NULL; | 116 | 119 | if(SS.GW.showShaded) { | 117 | 120 | Group *g = SK.GetGroup(SS.GW.activeGroup); | @@ -178,12 +181,16 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool wir | 178 | 181 | // These file formats don't have a canvas size, so they just | 179 | 182 | // get exported in the raw coordinate system. So indicate what | 180 | 183 | // that was on-screen. | 181 | | - SS.justExportedInfo.draw = true; | | 184 | + SS.justExportedInfo.showOrigin = true; | 182 | 185 | SS.justExportedInfo.pt = origin; | 183 | 186 | SS.justExportedInfo.u = u; | 184 | 187 | SS.justExportedInfo.v = v; | 185 | | - InvalidateGraphics(); | | 188 | + } else { | | 189 | + SS.justExportedInfo.showOrigin = false; | 186 | 190 | } | | 191 | + | | 192 | + SS.justExportedInfo.draw = true; | | 193 | + InvalidateGraphics(); | 187 | 194 | } | 188 | 195 |
| 189 | 196 | edges.Clear(); | @@ -365,7 +372,7 @@ void SolveSpaceUI::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *s | 365 | 372 | SEdge notClosedAt; | 366 | 373 | sbl->l.ClearTags(); | 367 | 374 | sblss.FindOuterFacesFrom(sbl, &spxyz, &srf, | 368 | | - SS.ChordTolMm()*s, | | 375 | + SS.ExportChordTolMm(), | 369 | 376 | &allClosed, ¬ClosedAt, | 370 | 377 | NULL, NULL, | 371 | 378 | &leftovers); | @@ -509,7 +516,7 @@ void VectorFileWriter::Output(SBezierLoopSetSet *sblss, SMesh *sm) { | 509 | 516 |
| 510 | 517 | void VectorFileWriter::BezierAsPwl(SBezier *sb) { | 511 | 518 | List<Vector> lv = {}; | 512 | | - sb->MakePwlInto(&lv, SS.ChordTolMm() / SS.exportScale); | | 519 | + sb->MakePwlInto(&lv, SS.ExportChordTolMm()); | 513 | 520 | int i; | 514 | 521 | for(i = 1; i < lv.n; i++) { | 515 | 522 | SBezier sb = SBezier::From(lv.elem[i-1], lv.elem[i]); | @@ -528,7 +535,7 @@ void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) { | 528 | 535 | sb->Finish().Minus(t1.ScaledBy(1.0/3)), | 529 | 536 | sb->Finish()); | 530 | 537 |
| 531 | | - double tol = SS.ChordTolMm() / SS.exportScale; | | 538 | + double tol = SS.ExportChordTolMm(); | 532 | 539 | // Arbitrary choice, but make it a little finer than pwl tolerance since | 533 | 540 | // it should be easier to achieve that with the smooth curves. | 534 | 541 | tol /= 2; | @@ -559,6 +566,12 @@ void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) { | 559 | 566 | // Export a triangle mesh, in the requested format. | 560 | 567 | //----------------------------------------------------------------------------- | 561 | 568 | void SolveSpaceUI::ExportMeshTo(const std::string &filename) { | | 569 | + SS.exportMode = true; | | 570 | + GenerateAll(GENERATE_ALL); | | 571 | + | | 572 | + Group *g = SK.GetGroup(SS.GW.activeGroup); | | 573 | + g->GenerateDisplayItems(); | | 574 | + | 562 | 575 | SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh); | 563 | 576 | if(m->IsEmpty()) { | 564 | 577 | Error("Active group mesh is empty; nothing to export."); | @@ -585,6 +598,10 @@ void SolveSpaceUI::ExportMeshTo(const std::string &filename) { | 585 | 598 | } | 586 | 599 |
| 587 | 600 | fclose(f); | | 601 | + | | 602 | + SS.justExportedInfo.showOrigin = false; | | 603 | + SS.justExportedInfo.draw = true; | | 604 | + InvalidateGraphics(); | 588 | 605 | } | 589 | 606 |
| 590 | 607 | //----------------------------------------------------------------------------- | |
Collapse file Copy file name to clipboardExpand all lines: src/exportstep.cpp +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -237,7 +237,7 @@ void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) { | 237 | 237 | // tolerance are required, because they are used to calculate the | 238 | 238 | // contour directions and determine inner vs. outer contours. | 239 | 239 | sblss.FindOuterFacesFrom(sbl, &spxyz, ss, | 240 | | - SS.ChordTolMm() / SS.exportScale, | | 240 | + SS.ExportChordTolMm(), | 241 | 241 | &allClosed, ¬ClosedAt, | 242 | 242 | NULL, NULL, | 243 | 243 | NULL); | |
Collapse file Copy file name to clipboardExpand all lines: src/graphicswin.cpp +4Lines changed: 4 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -732,6 +732,10 @@ void GraphicsWindow::MenuEdit(int id) { | 732 | 732 | for(p = SK.param.First(); p; p = SK.param.NextAfter(p)) { | 733 | 733 | p->free = false; | 734 | 734 | } | | 735 | + if(SS.exportMode) { | | 736 | + SS.exportMode = false; | | 737 | + SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); | | 738 | + } | 735 | 739 | break; | 736 | 740 |
| 737 | 741 | case MNU_SELECT_ALL: { | |
Collapse file Copy file name to clipboardExpand all lines: src/solvespace.cpp +19-1Lines changed: 19 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -36,10 +36,16 @@ void SolveSpaceUI::Init() { | 36 | 36 | lightDir[1].x = CnfThawFloat( 1.0f, "LightDir_1_Right" ); | 37 | 37 | lightDir[1].y = CnfThawFloat( 0.0f, "LightDir_1_Up" ); | 38 | 38 | lightDir[1].z = CnfThawFloat( 0.0f, "LightDir_1_Forward" ); | | 39 | + | | 40 | + exportMode = false; | 39 | 41 | // Chord tolerance | 40 | 42 | chordTol = CnfThawFloat(2.0f, "ChordTolerance"); | 41 | 43 | // Max pwl segments to generate | 42 | 44 | maxSegments = CnfThawInt(10, "MaxSegments"); | | 45 | + // Chord tolerance | | 46 | + exportChordTol = CnfThawFloat(0.1f, "ExportChordTolerance"); | | 47 | + // Max pwl segments to generate | | 48 | + exportMaxSegments = CnfThawInt(64, "ExportMaxSegments"); | 43 | 49 | // View units | 44 | 50 | viewUnits = (Unit)CnfThawInt((uint32_t)UNIT_MM, "ViewUnits"); | 45 | 51 | // Number of digits after the decimal point | @@ -157,6 +163,10 @@ void SolveSpaceUI::Exit(void) { | 157 | 163 | CnfFreezeFloat((float)chordTol, "ChordTolerance"); | 158 | 164 | // Max pwl segments to generate | 159 | 165 | CnfFreezeInt((uint32_t)maxSegments, "MaxSegments"); | | 166 | + // Export Chord tolerance | | 167 | + CnfFreezeFloat((float)exportChordTol, "ExportChordTolerance"); | | 168 | + // Export Max pwl segments to generate | | 169 | + CnfFreezeInt((uint32_t)exportMaxSegments, "ExportMaxSegments"); | 160 | 170 | // View units | 161 | 171 | CnfFreezeInt((uint32_t)viewUnits, "ViewUnits"); | 162 | 172 | // Number of digits after the decimal point | @@ -259,7 +269,15 @@ double SolveSpaceUI::StringToMm(const std::string &str) { | 259 | 269 | return std::stod(str) * MmPerUnit(); | 260 | 270 | } | 261 | 271 | double SolveSpaceUI::ChordTolMm(void) { | 262 | | - return SS.chordTol / SS.GW.scale; | | 272 | + if(exportMode) return ExportChordTolMm(); | | 273 | + return chordTol / GW.scale; | | 274 | +} | | 275 | +double SolveSpaceUI::ExportChordTolMm(void) { | | 276 | + return exportChordTol / exportScale; | | 277 | +} | | 278 | +int SolveSpaceUI::GetMaxSegments(void) { | | 279 | + if(exportMode) return exportMaxSegments; | | 280 | + return maxSegments; | 263 | 281 | } | 264 | 282 | int SolveSpaceUI::UnitDigitsAfterDecimal(void) { | 265 | 283 | return (viewUnits == UNIT_INCHES) ? afterDecimalInch : afterDecimalMm; | |
Collapse file Copy file name to clipboardExpand all lines: src/solvespace.h +6-1Lines changed: 6 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -752,6 +752,8 @@ class SolveSpaceUI { | 752 | 752 | double ambientIntensity; | 753 | 753 | double chordTol; | 754 | 754 | int maxSegments; | | 755 | + double exportChordTol; | | 756 | + int exportMaxSegments; | 755 | 757 | double cameraTangent; | 756 | 758 | float gridSpacing; | 757 | 759 | float exportScale; | @@ -764,6 +766,7 @@ class SolveSpaceUI { | 764 | 766 | bool exportShadedTriangles; | 765 | 767 | bool exportPwlCurves; | 766 | 768 | bool exportCanvasSizeAuto; | | 769 | + bool exportMode; | 767 | 770 | struct { | 768 | 771 | float left; | 769 | 772 | float right; | @@ -800,6 +803,8 @@ class SolveSpaceUI { | 800 | 803 | int UnitDigitsAfterDecimal(void); | 801 | 804 | void SetUnitDigitsAfterDecimal(int v); | 802 | 805 | double ChordTolMm(void); | | 806 | + double ExportChordTolMm(void); | | 807 | + int GetMaxSegments(void); | 803 | 808 | bool usePerspectiveProj; | 804 | 809 | double CameraTangent(void); | 805 | 810 |
| @@ -892,7 +897,7 @@ class SolveSpaceUI { | 892 | 897 | Vector origin; | 893 | 898 | } bgImage; | 894 | 899 | struct { | 895 | | - bool draw; | | 900 | + bool draw, showOrigin; | 896 | 901 | Vector pt, u, v; | 897 | 902 | } justExportedInfo; | 898 | 903 |
| |
Collapse file Copy file name to clipboardExpand all lines: src/srf/ratpoly.cpp +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -281,7 +281,7 @@ void SBezier::MakePwlWorker(List<Vector> *l, double ta, double tb, double chordT | 281 | 281 | Vector pm = PointAt((ta + tb) / 2.0); | 282 | 282 | double d = pm.DistanceToLine(pa, pb.Minus(pa)); | 283 | 283 |
| 284 | | - double step = 1.0/SS.maxSegments; | | 284 | + double step = 1.0/SS.GetMaxSegments(); | 285 | 285 | if((tb - ta) < step || d < chordTol) { | 286 | 286 | // A previous call has already added the beginning of our interval. | 287 | 287 | l->Add(&pb); | @@ -311,7 +311,7 @@ void SBezier::MakePwlInitialWorker(List<Vector> *l, double ta, double tb, double | 311 | 311 | pm3.DistanceToLine(pa, dir) | 312 | 312 | }); | 313 | 313 |
| 314 | | - double step = 1.0/SS.maxSegments; | | 314 | + double step = 1.0/SS.GetMaxSegments(); | 315 | 315 | if((tb - ta) < step || d < chordTol) { | 316 | 316 | // A previous call has already added the beginning of our interval. | 317 | 317 | l->Add(&pb); | |
Collapse file Copy file name to clipboardExpand all lines: src/srf/surfinter.cpp +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -376,7 +376,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, | 376 | 376 |
| 377 | 377 | // Our chord tolerance is whatever the user specified | 378 | 378 | double maxtol = SS.ChordTolMm(); | 379 | | - int maxsteps = max(300, SS.maxSegments*3); | | 379 | + int maxsteps = max(300, SS.GetMaxSegments()*3); | 380 | 380 |
| 381 | 381 | // The curve starts at our starting point. | 382 | 382 | SCurvePt padd = {}; | |
Collapse file Copy file name to clipboardExpand all lines: src/srf/triangulate.cpp +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -409,7 +409,7 @@ void SSurface::MakeTriangulationGridInto(List<double> *l, double vs, double vf, | 409 | 409 | worst = max(worst, pm2.DistanceToLine(ps, pf.Minus(ps))); | 410 | 410 | } | 411 | 411 |
| 412 | | - double step = 1.0/SS.maxSegments; | | 412 | + double step = 1.0/SS.GetMaxSegments(); | 413 | 413 | if((vf - vs) < step || worst < SS.ChordTolMm()) { | 414 | 414 | l->Add(&vf); | 415 | 415 | } else { | |
|