[OpenSCAD] Light source and default camera position different on command line

doug moen doug at moens.org
Mon Sep 24 16:25:15 EDT 2018


Okay, here is my code. It's based on boost::filesystem, which OpenSCAD
already uses. It also uses my custom curv::Exception class, but you can
easily replace that part.

I think the only part of this that won't work on Windows is the part where
it splits the PATH variable at ':' characters. I think that should be a ';'
character on Windows, but I don't have a Windows dev environment to test
on. The licence can be replaced by GPL2, but keep the copyright notice.

Actually, here's another possible Windows dependency. If 'openscad.exe'
exists in the current directory, and you type 'openscad', then what
happens? If the existence of openscad.exe in the current directory
overrides the PATH search on Windows, and if argv[0] is set to "openscad"
in that case, then extra code would be required.

// Copyright 2016-2018 Doug Moen
// Licensed under the Apache License, version 2.0
// See https://www.apache.org/licenses/LICENSE-2.0

extern "C" {
#include <stdlib.h>
#include <string.h>
}
#include <libcurv/exception.h>
#include "progdir.h"
namespace fs = boost::filesystem;

/*
 * Compute the absolute pathname of the directory
 * containing the program executable.
 * The storage for the result string is dynamically allocated.
 * argv0 is argv[0] of the argv passed to main().
 * ,,, Unix specific, right now.
 */
fs::path
progdir(const char *argv0)
{
    fs::path cmd(argv0);

    if (cmd.is_absolute())
        return cmd.parent_path();

    if (cmd.has_parent_path())
        return fs::current_path() / cmd.parent_path();

    const char* PATH = getenv("PATH");
    if (PATH == NULL) {
        throw curv::Exception_Base(curv::stringify(
            "Can't determine directory of program ", argv0,
            ": PATH not defined"));
    }

    const char* p = PATH;
    const char* pend = PATH + strlen(PATH);
    while (p < pend) {
        const char* q = strchr(p, ':');
        if (q == nullptr)
            q = pend;
        fs::path file(p, q);
        file /= argv0;
        if (fs::exists(fs::status(file)))
            return file.parent_path();
        p = (q < pend ? q + 1 : pend);
    }

    throw curv::Exception_Base(curv::stringify(
        "Can't determine directory of program ", argv0,
        ": can't find ", argv0, " in $PATH"));
}


On 24 September 2018 at 15:45, nop head <nop.head at gmail.com> wrote:

> I think argv[0] is the full path of the executable on Windows, regardless
> of what you type, but on Linux it is just what you typed. Does your code
> cope with it being a full path like C:/msys64/home/ChrisP/
> openscad/release/openscad.exe?
>
> On 24 September 2018 at 20:23, doug moen <doug at moens.org> wrote:
>
>> const std::string application_path = fs::absolute(boost::filesystem
>> ::path(argv[0]).parent_path()).generic_string();
>>
>> This code won't work. Suppose that you git clone the OpenSCAD repository,
>> build it, and install it in some place like /usr/local/bin. Then, when you
>> type 'openscad' from a bash prompt, then argv[0] will just be the string
>> "openscad", with no directory component. application_path should be set to
>> "/usr/local/bin", but this code won't return the correct directory.
>>
>> I have a function called 'progdir()' which computes the application
>> directory, portable between Linux and MacOS. However, I've never tested my
>> code on Windows. You can have the code if you want it. progdir() works by
>> searching the PATH environment variable, when necessary, to determine the
>> application path.
>>
>> How important is it for OpenSCAD to work correctly if it is built without
>> linking to Qt?
>>
>> On 24 September 2018 at 14:33, nop head <nop.head at gmail.com> wrote:
>>
>>> #ifdef OPENSCAD_QTGUI
>>>     const std::string application_path = QCoreApplication::applicationD
>>> irPath().toLocal8Bit().constData();
>>> #else
>>>     const std::string application_path = fs::absolute(boost::filesystem
>>> ::path(argv[0]).parent_path()).generic_string();
>>> #endif
>>>      PlatformUtils::registerApplicationPath(application_path);
>>>
>>> Much nicer!
>>>
>>> On 24 September 2018 at 19:29, nop head <nop.head at gmail.com> wrote:
>>>
>>>> Actually QCoreApplication::applicationDirPath() is static so I don't
>>>> need an instance.
>>>>
>>>> On 24 September 2018 at 19:27, nop head <nop.head at gmail.com> wrote:
>>>>
>>>>> The way it currently works is if it runs the GUI then it gets the
>>>>> application path from the OpenSCADApp instance. If it runs the command line
>>>>> version it instantiates a QCoreApplication app and uses that. Only if it is
>>>>> compiled without QT does it use the boost version.
>>>>>
>>>>> To get the color schemes in the command line description it needs the
>>>>> app path before it has processed the command line. I bodged it by always
>>>>> creating a QCoreApplicationapp on the heap, using it to get the app path
>>>>> and then deleting it. That seems to fix the problem and still uses QT if
>>>>> compiled with QT.
>>>>>
>>>>> #ifdef OPENSCAD_QTGUI
>>>>>     QCoreApplication *app = new QCoreApplication(argc, argv);
>>>>>     const std::string application_path = QCoreApplication::instance()->
>>>>> applicationDirPath().toLocal8Bit().constData();
>>>>>     delete app;
>>>>> #else
>>>>>     const std::string application_path = fs::absolute(boost::filesystem
>>>>> ::path(argv[0]).parent_path()).generic_string();
>>>>> #endif
>>>>>     PlatformUtils::registerApplicationPath(application_path);
>>>>>
>>>>> Can anybody see a problem with this hack?
>>>>>
>>>>>
>>>>> On 24 September 2018 at 18:28, Torsten Paul <Torsten.Paul at gmx.de>
>>>>> wrote:
>>>>>
>>>>>> On 09/24/2018 04:03 PM, nop head wrote:
>>>>>>
>>>>>>> Having two QT app instances seems to be a problem, no surprise there!
>>>>>>> Is there a reason for preferring the QT version? The boost version
>>>>>>> produces the same path on my system so using that solves the problem.
>>>>>>>
>>>>>>> The current code might be just for legacy reasons, but there are
>>>>>> various
>>>>>> issues with boost on Windows regarding hard-links and non-ascii path.
>>>>>> I don't know if the toLocal8Bit() from Qt is better, but it might
>>>>>> actually
>>>>>> help in those cases. Otherwise it would be nicer to just have a single
>>>>>> way to determine the path.
>>>>>>
>>>>>> The command line help change looks very nice. I think that using the
>>>>>> generated version is much better as this pretty much removes the risk
>>>>>> of information missing in the output in case of future changes to the
>>>>>> options.
>>>>>>
>>>>>> ciao,
>>>>>>   Torsten.
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> OpenSCAD mailing list
>>>>>> Discuss at lists.openscad.org
>>>>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> Discuss at lists.openscad.org
>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>>
>>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss at lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss at lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20180924/a7cec69c/attachment.html>


More information about the Discuss mailing list