AngusJohnson / Clipper2

Polygon Clipping and Offsetting - C++, C# and Delphi
Boost Software License 1.0
1.34k stars 248 forks source link

Minkowski in export header #836

Closed julvdb closed 2 months ago

julvdb commented 2 months ago

Hello!

First of all, kudos for your work on this project! It seems to have exactly what I need.

However, I noticed that the Minkowski sum/difference part of the library is not included in the export header. Is this something that can be added in the future?

I'm working on a project that is coded in C and I'd like to link to this library to use the Minkowski sum and difference. Is it a matter of adding some extern "C" lines in the export header or does it require more tedious programming? Let me know!

Thanks in advance, Jul

julvdb commented 2 months ago

I managed to get it working in C and the addition of the Minkowski operators was rather easy. I simply added these lines to clipper.export.h:

EXTERN_DLL_EXPORT CPaths64 MinkowskiSum64(
    const CPath64 cpattern, const CPath64 cpath, bool is_closed
)
{
    Path64 pattern = ConvertCPath(cpattern);
    Path64 path = ConvertCPath(cpath);
    Paths64 sum = MinkowskiSum(pattern, path, is_closed);
    return CreateCPaths(sum);
}

EXTERN_DLL_EXPORT CPaths64 MinkowskiDiff64(
    const CPath64 cpattern, const CPath64 cpath, bool is_closed
)
{
    Path64 pattern = ConvertCPath(cpattern);
    Path64 path = ConvertCPath(cpath);
    Paths64 diff = MinkowskiDiff(pattern, path, is_closed);
    return CreateCPaths(diff);
}

I added the conversion for a single path for convenience:

template <typename T>
static T *CreateCPath(const Path<T> &path)
{
    size_t path_len = path.size();
    if (path_len == 0) return nullptr;
    T *result = new T[2*(1+path_len)], *v = result;
    *v++ = path_len;
    *v++ = 0;
    for (const Point<T>& pt : path)
    {
        *v++ = pt.x;
        *v++ = pt.y;
    }
    return result;
}

template <typename T>
static Path<T> ConvertCPath(T *path)
{
    Path<T> result;
    if (!path) return result;
    T *v = path;
    size_t cnt = static_cast<size_t>(*v);
    v += 2;
    result.reserve(cnt);
    for (size_t j = 0; j < cnt; ++j)
    {
        T x = *v++, y = *v++;
        result.push_back(Point<T>(x, y));
    }
    return result;
}
julvdb commented 2 months ago

I'd love to contribute these changes, but I've never done this. How can I apply this addition to the repo, or a branch for example?

reunanen commented 2 months ago

@julvdb: Generally speaking, in order to contribute code, you want to 1) fork this "upstream" repo in GitHub (if you didn't already), 2) create a new branch in your fork, 3) commit your changes to the new branch, 4) push the new branch to GitHub, and finally 5) open a pull request from your fork's branch to the upstream repo's main branch.

Does that make sense? Any particular step you are struggling with?

AngusJohnson commented 2 months ago

Is this something that can be added in the future?

Hi Jul. Sure, it just hasn't been a high priority. I will get around to it at some stage, I'm just not sure when.