[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/vthriller/solvespace/unmimalloc/src/solvespace.cpp [Back]  [Original]

//-----------------------------------------------------------------------------
// Entry point in to the program, our registry-stored settings and top-level
// housekeeping when we open, save, and create new files.
//
// Copyright 2008-2013 Jonathan Westhues.
//-----------------------------------------------------------------------------
#include "solvespace.h"
#include "config.h"

namespace SolveSpace {

SolveSpaceUI SS = {};
Sketch SK = {};

void SolveSpaceUI::Init() {
#if !defined(HEADLESS)
    // Check that the resource system works.
    dbp("%s", LoadString("banner.txt").data());
#endif

    Platform::SettingsRef settings = Platform::GetSettings();

    SS.tangentArcRadius = 10.0;
    SS.explodeDistance = 1.0;

    // Then, load the registry settings.
    // Default list of colors for the model material
    modelColor[0] = settings->ThawColor("ModelColor_0", RGBi(150, 150, 150));
    modelColor[1] = settings->ThawColor("ModelColor_1", RGBi(100, 100, 100));
    modelColor[2] = settings->ThawColor("ModelColor_2", RGBi( 30,  30,  30));
    modelColor[3] = settings->ThawColor("ModelColor_3", RGBi(150,   0,   0));
    modelColor[4] = settings->ThawColor("ModelColor_4", RGBi(  0, 100,   0));
    modelColor[5] = settings->ThawColor("ModelColor_5", RGBi(  0,  80,  80));
    modelColor[6] = settings->ThawColor("ModelColor_6", RGBi(  0,   0, 130));
    modelColor[7] = settings->ThawColor("ModelColor_7", RGBi( 80,   0,  80));
    // Light intensities
    lightIntensity[0] = settings->ThawFloat("LightIntensity_0", 1.0);
    lightIntensity[1] = settings->ThawFloat("LightIntensity_1", 0.5);
    ambientIntensity = settings->ThawFloat("Light_Ambient", 0.3);
    // Light positions
    lightDir[0].x = settings->ThawFloat("LightDir_0_Right",   -1.0);
    lightDir[0].y = settings->ThawFloat("LightDir_0_Up",       1.0);
    lightDir[0].z = settings->ThawFloat("LightDir_0_Forward",  0.0);
    lightDir[1].x = settings->ThawFloat("LightDir_1_Right",    1.0);
    lightDir[1].y = settings->ThawFloat("LightDir_1_Up",       0.0);
    lightDir[1].z = settings->ThawFloat("LightDir_1_Forward",  0.0);

    exportMode = false;
    // Chord tolerance
    chordTol = settings->ThawFloat("ChordTolerancePct", 0.1);
    // Max pwl segments to generate
    maxSegments = settings->ThawInt("MaxSegments", 20);
    // Chord tolerance
    exportChordTol = settings->ThawFloat("ExportChordTolerance", 0.1);
    // Max pwl segments to generate
    exportMaxSegments = settings->ThawInt("ExportMaxSegments", 64);
    // Timeout value for finding redundant constrains (ms)
    timeoutRedundantConstr = settings->ThawInt("TimeoutRedundantConstraints", 1000);
    // Animation speed calculation base time (ms)
    animationSpeed = settings->ThawInt("AnimationSpeed", 800);
    // View units
    viewUnits = (Unit)settings->ThawInt("ViewUnits", (uint32_t)Unit::MM);
    // Number of digits after the decimal point
    afterDecimalMm = settings->ThawInt("AfterDecimalMm", 2);
    afterDecimalInch = settings->ThawInt("AfterDecimalInch", 3);
    afterDecimalDegree = settings->ThawInt("AfterDecimalDegree", 2);
    useSIPrefixes = settings->ThawBool("UseSIPrefixes", false);
    // Camera tangent (determines perspective)
    cameraTangent = settings->ThawFloat("CameraTangent", 0.3f/1e3);
    // Grid spacing
    gridSpacing = settings->ThawFloat("GridSpacing", 5.0);
    // Export scale factor
    exportScale = settings->ThawFloat("ExportScale", 1.0);
    // Export offset (cutter radius comp)
    exportOffset = settings->ThawFloat("ExportOffset", 0.0);
    // Dimensions on arcs default to diameter vs radius
    arcDimDefaultDiameter = settings->ThawBool("ArcDimDefaultDiameter", false);
    // Show full file path in the menu bar
    showFullFilePath = settings->ThawBool("ShowFullFilePath", true);
    // Rewrite exported colors close to white into black (assuming white bg)
    fixExportColors = settings->ThawBool("FixExportColors", true);
    // Export background color
    exportBackgroundColor = settings->ThawBool("ExportBackgroundColor", false);
    // Draw back faces of triangles (when mesh is leaky/self-intersecting)
    drawBackFaces = settings->ThawBool("DrawBackFaces", true);
    // Use camera mouse navigation
    cameraNav = settings->ThawBool("CameraNav", false);
    // Use turntable mouse navigation
    turntableNav = settings->ThawBool("TurntableNav", false);
    // Immediately edit dimension
    immediatelyEditDimension = settings->ThawBool("ImmediatelyEditDimension", true);
    // Check that contours are closed and not self-intersecting
    checkClosedContour = settings->ThawBool("CheckClosedContour", true);
    // Enable automatic constrains for lines
    automaticLineConstraints = settings->ThawBool("AutomaticLineConstraints", true);
    // Draw closed polygons areas
    showContourAreas = settings->ThawBool("ShowContourAreas", false);
    // Export shaded triangles in a 2d view
    exportShadedTriangles = settings->ThawBool("ExportShadedTriangles", true);
    // Export pwl curves (instead of exact) always
    exportPwlCurves = settings->ThawBool("ExportPwlCurves", false);
    // Background color on-screen
    backgroundColor = settings->ThawColor("BackgroundColor", RGBi(0, 0, 0));
    // Whether export canvas size is fixed or derived from bbox
    exportCanvasSizeAuto = settings->ThawBool("ExportCanvasSizeAuto", true);
    // Margins for automatic canvas size
    exportMargin.left   = settings->ThawFloat("ExportMargin_Left",   5.0);
    exportMargin.right  = settings->ThawFloat("ExportMargin_Right",  5.0);
    exportMargin.bottom = settings->ThawFloat("ExportMargin_Bottom", 5.0);
    exportMargin.top    = settings->ThawFloat("ExportMargin_Top",    5.0);
    // Dimensions for fixed canvas size
    exportCanvas.width  = settings->ThawFloat("ExportCanvas_Width",  100.0);
    exportCanvas.height = settings->ThawFloat("ExportCanvas_Height", 100.0);
    exportCanvas.dx     = settings->ThawFloat("ExportCanvas_Dx",     5.0);
    exportCanvas.dy     = settings->ThawFloat("ExportCanvas_Dy",     5.0);
    // Extra parameters when exporting G code
    gCode.depth         = settings->ThawFloat("GCode_Depth", 10.0);
    gCode.safeHeight    = settings->ThawFloat("GCode_SafeHeight", 5.0);
    gCode.passes        = settings->ThawInt("GCode_Passes", 1);
    gCode.feed          = settings->ThawFloat("GCode_Feed", 10.0);
    gCode.plungeFeed    = settings->ThawFloat("GCode_PlungeFeed", 10.0);
    // Show toolbar in the graphics window
    showToolbar = settings->ThawBool("ShowToolbar", true);
    // Recent files menus
    for(size_t i = 0; i < MAX_RECENT; i++) {
        std::string rawPath = settings->ThawString("RecentFile_" + std::to_string(i), "");
        if(rawPath.empty()) continue;
        recentFiles.push_back(Platform::Path::From(rawPath));
    }
    // Autosave timer
    autosaveInterval = settings->ThawInt("AutosaveInterval", 5);
    // Locale
    std::string locale = settings->ThawString("Locale", "");
    if(!locale.empty()) {
        SetLocale(locale);
    }

    refreshTimer = Platform::CreateTimer();
    refreshTimer->onTimeout = std::bind(&SolveSpaceUI::Refresh, &SS);

    autosaveTimer = Platform::CreateTimer();
    autosaveTimer->onTimeout = std::bind(&SolveSpaceUI::Autosave, &SS);

    // The default styles (colors, line widths, etc.) are also stored in the
    // configuration file, but we will automatically load those as we need
    // them.

    ScheduleAutosave();

    NewFile();
    AfterNewFile();

    if(TW.window && GW.window) {
        TW.window->ThawPosition(settings, "TextWindow");
        GW.window->ThawPosition(settings, "GraphicsWindow");
        TW.window->SetVisible(true);
        GW.window->SetVisible(true);
        GW.window->Focus();

        // Do this once the window is created.
        Request3DConnexionEventsForWindow(GW.window);
    }
}

bool SolveSpaceUI::LoadAutosaveFor(const Platform::Path &filename) {
    Platform::Path autosaveFile = filename.WithExtension(BACKUP_EXT);

    FILE *f = OpenFile(autosaveFile, "rb");
    if(!f)
        return false;
    fclose(f);

    Platform::MessageDialogRef dialog = CreateMessageDialog(GW.window);

    using Platform::MessageDialog;
    dialog->SetType(MessageDialog::Type::QUESTION);
    dialog->SetTitle(C_("title", "Autosave Available"));
    dialog->SetMessage(C_("dialog", "An autosave file is available for this sketch."));
    dialog->SetDescription(C_("dialog", "Do you want to load the autosave file instead?"));
    dialog->AddButton(C_("button", "&Load autosave"), MessageDialog::Response::YES,
                      /*isDefault=*/true);
    dialog->AddButton(C_("button", "Do&n't Load"), MessageDialog::Response::NO);

    // FIXME(async): asyncify this call
    if(dialog->RunModal() == MessageDialog::Response::YES) {
        unsaved = true;
        return LoadFromFile(autosaveFile, /*canCancel=*/true);
    }

    return false;
}

bool SolveSpaceUI::Load(const Platform::Path &filename) {
    bool autosaveLoaded = LoadAutosaveFor(filename);
    bool fileLoaded = autosaveLoaded || LoadFromFile(filename, /*canCancel=*/true);
    if(fileLoaded) {
        saveFile = filename;
        AddToRecentList(filename);
    } else {
        saveFile.Clear();
        NewFile();
    }
    // Capture whether loading modified the document (e.g. the user relocated
    // a missing image, which sets unsaved in ReloadLinkedImage) before
    // AfterNewFile() resets it (issue #1238).
    bool unsavedDuringLoad = unsaved;
    AfterNewFile();
    unsaved = autosaveLoaded || unsavedDuringLoad;
    return fileLoaded;
}

void SolveSpaceUI::Exit() {
    Platform::SettingsRef settings = Platform::GetSettings();

    GW.window->FreezePosition(settings, "GraphicsWindow");
    TW.window->FreezePosition(settings, "TextWindow");

    // Recent files
    for(size_t i = 0; i < MAX_RECENT; i++) {
        std::string rawPath;
        if(recentFiles.size() > i) {
            rawPath = recentFiles[i].raw;
        }
        settings->FreezeString("RecentFile_" + std::to_string(i), rawPath);
    }
    // Model colors
    for(size_t i = 0; i < MODEL_COLORS; i++)
        settings->FreezeColor("ModelColor_" + std::to_string(i), modelColor[i]);
    // Light intensities
    settings->FreezeFloat("LightIntensity_0", (float)lightIntensity[0]);
    settings->FreezeFloat("LightIntensity_1", (float)lightIntensity[1]);
    settings->FreezeFloat("Light_Ambient", (float)ambientIntensity);
    // Light directions
    settings->FreezeFloat("LightDir_0_Right",   (float)lightDir[0].x);
    settings->FreezeFloat("LightDir_0_Up",      (float)lightDir[0].y);
    settings->FreezeFloat("LightDir_0_Forward", (float)lightDir[0].z);
    settings->FreezeFloat("LightDir_1_Right",   (float)lightDir[1].x);
    settings->FreezeFloat("LightDir_1_Up",      (float)lightDir[1].y);
    settings->FreezeFloat("LightDir_1_Forward", (float)lightDir[1].z);
    // Chord tolerance
    settings->FreezeFloat("ChordTolerancePct", (float)chordTol);
    // Max pwl segments to generate
    settings->FreezeInt("MaxSegments", (uint32_t)maxSegments);
    // Export Chord tolerance
    settings->FreezeFloat("ExportChordTolerance", (float)exportChordTol);
    // Export Max pwl segments to generate
    settings->FreezeInt("ExportMaxSegments", (uint32_t)exportMaxSegments);
    // Timeout for finding which constraints to fix Jacobian
    settings->FreezeInt("TimeoutRedundantConstraints", (uint32_t)timeoutRedundantConstr);
    // Animation speed
    settings->FreezeInt("AnimationSpeed", (uint32_t)animationSpeed);
    // View units
    settings->FreezeInt("ViewUnits", (uint32_t)viewUnits);
    // Number of digits after the decimal point
    settings->FreezeInt("AfterDecimalMm",   (uint32_t)afterDecimalMm);
    settings->FreezeInt("AfterDecimalInch", (uint32_t)afterDecimalInch);
    settings->FreezeInt("AfterDecimalDegree", (uint32_t)afterDecimalDegree);
    settings->FreezeBool("UseSIPrefixes", useSIPrefixes);
    // Camera tangent (determines perspective)
    settings->FreezeFloat("CameraTangent", (float)cameraTangent);
    // Grid spacing
    settings->FreezeFloat("GridSpacing", gridSpacing);
    // Export scale
    settings->FreezeFloat("ExportScale", exportScale);
    // Export offset (cutter radius comp)
    settings->FreezeFloat("ExportOffset", exportOffset);
    // Rewrite the default arc dimension setting
    settings->FreezeBool("ArcDimDefaultDiameter", arcDimDefaultDiameter);
    // Show full file path in the menu bar
    settings->FreezeBool("ShowFullFilePath", showFullFilePath);
    // Rewrite exported colors close to white into black (assuming white bg)
    settings->FreezeBool("FixExportColors", fixExportColors);
    // Export background color
    settings->FreezeBool("ExportBackgroundColor", exportBackgroundColor);
    // Draw back faces of triangles (when mesh is leaky/self-intersecting)
    settings->FreezeBool("DrawBackFaces", drawBackFaces);
    // Draw closed polygons areas
    settings->FreezeBool("ShowContourAreas", showContourAreas);
    // Check that contours are closed and not self-intersecting
    settings->FreezeBool("CheckClosedContour", checkClosedContour);
    // Use camera mouse navigation
    settings->FreezeBool("CameraNav", cameraNav);
    // Use turntable mouse navigation
    settings->FreezeBool("TurntableNav", turntableNav);
    // Immediately edit dimensions
    settings->FreezeBool("ImmediatelyEditDimension", immediatelyEditDimension);
    // Enable automatic constrains for lines
    settings->FreezeBool("AutomaticLineConstraints", automaticLineConstraints);
    // Export shaded triangles in a 2d view
    settings->FreezeBool("ExportShadedTriangles", exportShadedTriangles);
    // Export pwl curves (instead of exact) always
    settings->FreezeBool("ExportPwlCurves", exportPwlCurves);
    // Background color on-screen
    settings->FreezeColor("BackgroundColor", backgroundColor);
    // Whether export canvas size is fixed or derived from bbox
    settings->FreezeBool("ExportCanvasSizeAuto", exportCanvasSizeAuto);
    // Margins for automatic canvas size
    settings->FreezeFloat("ExportMargin_Left",   exportMargin.left);
    settings->FreezeFloat("ExportMargin_Right",  exportMargin.right);
    settings->FreezeFloat("ExportMargin_Bottom", exportMargin.bottom);
    settings->FreezeFloat("ExportMargin_Top",    exportMargin.top);
    // Dimensions for fixed canvas size
    settings->FreezeFloat("ExportCanvas_Width",  exportCanvas.width);
    settings->FreezeFloat("ExportCanvas_Height", exportCanvas.height);
    settings->FreezeFloat("ExportCanvas_Dx",     exportCanvas.dx);
    settings->FreezeFloat("ExportCanvas_Dy",     exportCanvas.dy);
     // Extra parameters when exporting G code
    settings->FreezeFloat("GCode_Depth", gCode.depth);
    settings->FreezeInt("GCode_Passes", gCode.passes);
    settings->FreezeFloat("GCode_Feed", gCode.feed);
    settings->FreezeFloat("GCode_PlungeFeed", gCode.plungeFeed);
    // Show toolbar in the graphics window
    settings->FreezeBool("ShowToolbar", showToolbar);
    // Autosave timer
    settings->FreezeInt("AutosaveInterval", autosaveInterval);

    // And the default styles, colors and line widths and such.
    Style::FreezeDefaultStyles(settings);

    Platform::ExitGui();
}

void SolveSpaceUI::Refresh() {
    // generateAll must happen bfore updating displays
    if(scheduledGenerateAll) {
		// Clear the flag so that if the call to GenerateAll is blocked by a Message or Error, 
		// subsequent refreshes do not try to Generate again.
        scheduledGenerateAll = false;
        GenerateAll(Generate::DIRTY, /*andFindFree=*/false, /*genForBBox=*/false);   
    }
    if(scheduledShowTW) {
        scheduledShowTW = false;
        TW.Show();
    }
}

void SolveSpaceUI::ScheduleGenerateAll() {
    scheduledGenerateAll = true;
    refreshTimer->RunAfterProcessingEvents();
}

void SolveSpaceUI::ScheduleShowTW() {
    scheduledShowTW = true;
    refreshTimer->RunAfterProcessingEvents();
}

void SolveSpaceUI::ScheduleAutosave() {
    autosaveTimer->RunAfter(autosaveInterval * 60 * 1000);
}

double SolveSpaceUI::MmPerUnit() {
    switch(viewUnits) {
        case Unit::INCHES: return 25.4;
        case Unit::FEET_INCHES: return 25.4; // The 'unit' is still inches
        case Unit::METERS: return 1000.0;
        case Unit::MM: return 1.0;
    }
    return 1.0;
}
const char *SolveSpaceUI::UnitName() {
    switch(viewUnits) {
        case Unit::INCHES: return "in";
        case Unit::FEET_INCHES: return "in";
        case Unit::METERS: return "m";
        case Unit::MM: return "mm";
    }
    return "";
}

std::string SolveSpaceUI::MmToString(double v, bool editable) {
    v /= MmPerUnit();
    // The syntax 2' 6" for feet and inches is not something we can (currently)
    // parse back from a string so if editable is true, we treat FEET_INCHES the
    // same as INCHES and just return the unadorned decimal number of inches.
    if(viewUnits == Unit::FEET_INCHES && !editable) {
        // Now convert v from inches to 64'ths of an inch, to make rounding easier.
        v = floor((v + (1.0 / 128.0)) * 64.0);
        int feet = (int)(v / (12.0 * 64.0));
        v = v - (feet * 12.0 * 64.0);
        // v is now the feet-less remainder in 1/64 inches
        int inches = (int)(v / 64.0);
        int numerator = (int)(v - ((double)inches * 64.0));
        int denominator = 64;
        // Divide down to smallest denominator where the numerator is still a whole number
        while ((numerator != 0) && ((numerator & 1) == 0)) {
            numerator /= 2;
            denominator /= 2;
        }
        std::ostringstream str;
        if(feet != 0) {
            str 

Web Proxy Viewer  |  New URL  |  Original Page