2020-05-04 12:10:16 -04:00
|
|
|
//#define use_int32
|
|
|
|
|
|
|
|
|
|
#include <emscripten.h>
|
|
|
|
|
#include "clipper.hpp"
|
|
|
|
|
|
|
|
|
|
typedef unsigned char Uint8;
|
|
|
|
|
typedef unsigned short Uint16;
|
|
|
|
|
typedef unsigned int Uint32;
|
|
|
|
|
typedef int int32;
|
|
|
|
|
|
2021-06-22 21:33:46 -04:00
|
|
|
using namespace ClipperLib;
|
|
|
|
|
|
2020-05-04 12:10:16 -04:00
|
|
|
Uint8 *mem = 0;
|
2021-06-22 22:04:26 -04:00
|
|
|
Uint8 debug = 0;
|
2020-05-04 12:10:16 -04:00
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
extern void polygon(Uint32 points, Uint32 inners);
|
|
|
|
|
extern void point(Uint32 x, Uint32 y);
|
2021-07-11 12:41:24 -04:00
|
|
|
extern void ostr(Uint32 len, std::string str);
|
2020-05-04 12:10:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct length16 {
|
|
|
|
|
Uint16 length;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct point32 {
|
|
|
|
|
int32 x;
|
|
|
|
|
int32 y;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
__attribute__ ((export_name("mem_get")))
|
|
|
|
|
Uint32 mem_get(Uint32 size) {
|
|
|
|
|
return (Uint32)malloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__attribute__ ((export_name("mem_clr")))
|
|
|
|
|
void mem_clr(Uint32 loc) {
|
|
|
|
|
free((void *)loc);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
Uint32 readPoly(Path &path, Uint32 pos) {
|
2021-06-22 22:04:26 -04:00
|
|
|
struct length16 *ls = (struct length16 *)(mem + pos);
|
|
|
|
|
Uint16 points = ls->length;
|
2021-06-23 00:05:40 -04:00
|
|
|
// if (debug) polygon(points, 0);
|
2021-06-22 22:04:26 -04:00
|
|
|
pos += 2;
|
2021-06-25 21:43:47 -04:00
|
|
|
while (points > 0) {
|
2021-06-22 22:04:26 -04:00
|
|
|
struct point32 *ip = (struct point32 *)(mem + pos);
|
|
|
|
|
pos += 8;
|
|
|
|
|
path << IntPoint(ip->x, ip->y);
|
2021-06-23 00:05:40 -04:00
|
|
|
// if (debug) point(ip->x, ip->y);
|
2021-06-25 21:43:47 -04:00
|
|
|
points--;
|
2021-06-22 22:04:26 -04:00
|
|
|
}
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
Uint32 readPolys(Paths &paths, Uint32 pos, Uint32 count) {
|
2021-06-22 21:33:46 -04:00
|
|
|
Uint32 poly = 0;
|
2021-06-25 21:43:47 -04:00
|
|
|
while (count > 0) {
|
2021-06-22 22:04:26 -04:00
|
|
|
pos = readPoly(paths[poly++], pos);
|
2021-06-25 21:43:47 -04:00
|
|
|
count--;
|
2021-06-22 21:33:46 -04:00
|
|
|
}
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
Uint32 writePolys(Paths &outs, Uint32 pos) {
|
|
|
|
|
for (Path po : outs) {
|
|
|
|
|
// if (debug) polygon(po.size(), 1);
|
|
|
|
|
struct length16 *ls = (struct length16 *)(mem + pos);
|
|
|
|
|
ls->length = po.size();
|
|
|
|
|
pos += 2;
|
|
|
|
|
for (IntPoint pt : po) {
|
|
|
|
|
// if (debug) point(pt.X, pt.Y);
|
|
|
|
|
struct point32 *ip = (struct point32 *)(mem + pos);
|
|
|
|
|
ip->x = (int)pt.X;
|
|
|
|
|
ip->y = (int)pt.Y;
|
|
|
|
|
pos += 8;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// null terminate
|
|
|
|
|
struct length16 *ls = (struct length16 *)(mem + pos);
|
|
|
|
|
ls->length = 0;
|
|
|
|
|
return pos + 2;
|
2021-06-22 22:04:26 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-04 12:10:16 -04:00
|
|
|
__attribute__ ((export_name("poly_offset")))
|
2021-07-10 22:20:07 -04:00
|
|
|
Uint32 poly_offset(Uint32 memat, Uint32 polys, float offset, float clean, Uint8 simple) {
|
2020-05-04 12:10:16 -04:00
|
|
|
|
|
|
|
|
Paths ins(polys);
|
|
|
|
|
Paths outs;
|
|
|
|
|
Uint32 pos = memat;
|
|
|
|
|
Uint16 poly = 0;
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
pos = readPolys(ins, pos, polys);
|
2021-06-22 21:33:46 -04:00
|
|
|
|
2021-07-10 22:20:07 -04:00
|
|
|
if (clean > 0) {
|
|
|
|
|
Paths cleans;
|
|
|
|
|
CleanPolygons(ins, cleans, clean);
|
|
|
|
|
ins = cleans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (simple > 0) {
|
|
|
|
|
Paths simples;
|
|
|
|
|
SimplifyPolygons(ins, simples);
|
|
|
|
|
ins = simples;
|
|
|
|
|
}
|
2020-05-04 20:08:22 -04:00
|
|
|
|
2020-05-04 12:10:16 -04:00
|
|
|
ClipperOffset co;
|
|
|
|
|
co.AddPaths(ins, jtMiter, etClosedPolygon);
|
|
|
|
|
co.Execute(outs, offset);
|
|
|
|
|
|
|
|
|
|
Uint32 resat = pos;
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
pos = writePolys(outs, pos);
|
2020-05-04 20:08:22 -04:00
|
|
|
|
2020-05-04 12:10:16 -04:00
|
|
|
co.Clear();
|
|
|
|
|
|
|
|
|
|
return resat;
|
|
|
|
|
}
|
2021-06-21 23:26:54 -04:00
|
|
|
|
|
|
|
|
__attribute__ ((export_name("poly_union")))
|
2021-06-22 17:16:01 -04:00
|
|
|
Uint32 poly_union(Uint32 memat, Uint32 polys, float offset) {
|
2021-06-21 23:26:54 -04:00
|
|
|
|
|
|
|
|
Paths ins(polys);
|
|
|
|
|
Paths outs;
|
|
|
|
|
Uint32 pos = memat;
|
|
|
|
|
Uint16 poly = 0;
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
pos = readPolys(ins, pos, polys);
|
2021-06-21 23:26:54 -04:00
|
|
|
|
|
|
|
|
Clipper clip;
|
2021-06-22 17:16:01 -04:00
|
|
|
clip.AddPaths(ins, ptSubject, true);
|
|
|
|
|
clip.Execute(ctUnion, outs);
|
|
|
|
|
|
|
|
|
|
Uint32 resat = pos;
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
pos = writePolys(outs, pos);
|
2021-06-22 17:16:01 -04:00
|
|
|
|
|
|
|
|
clip.Clear();
|
|
|
|
|
|
|
|
|
|
return resat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__attribute__ ((export_name("poly_diff")))
|
2021-07-11 11:04:52 -04:00
|
|
|
Uint32 poly_diff(Uint32 memat, Uint32 polysA, Uint32 polysB, Uint8 AB, Uint8 BA, float clean) {
|
2021-06-22 17:16:01 -04:00
|
|
|
|
|
|
|
|
Paths inA(polysA);
|
|
|
|
|
Paths inB(polysB);
|
|
|
|
|
Uint32 pos = memat;
|
|
|
|
|
|
2021-06-23 00:05:40 -04:00
|
|
|
pos = readPolys(inA, pos, polysA);
|
|
|
|
|
pos = readPolys(inB, pos, polysB);
|
2021-06-22 17:16:01 -04:00
|
|
|
|
2021-06-21 23:26:54 -04:00
|
|
|
Uint32 resat = pos;
|
|
|
|
|
|
2021-07-11 11:04:52 -04:00
|
|
|
if (AB > 0) {
|
2021-06-23 00:34:19 -04:00
|
|
|
Paths outs;
|
|
|
|
|
Clipper clip;
|
|
|
|
|
clip.AddPaths(inA, ptSubject, true);
|
|
|
|
|
clip.AddPaths(inB, ptClip, true);
|
|
|
|
|
clip.Execute(ctDifference, outs, pftEvenOdd, pftEvenOdd);
|
2021-06-23 11:13:45 -04:00
|
|
|
if (clean > 0) {
|
2021-07-11 11:04:52 -04:00
|
|
|
// CleanPolygons(outs, clean);
|
|
|
|
|
for (Path po : outs) {
|
|
|
|
|
CleanPolygon(po, clean);
|
|
|
|
|
}
|
2021-06-23 11:13:45 -04:00
|
|
|
}
|
2021-06-23 00:34:19 -04:00
|
|
|
pos = writePolys(outs, pos);
|
|
|
|
|
clip.Clear();
|
|
|
|
|
}
|
2021-06-21 23:26:54 -04:00
|
|
|
|
2021-07-11 11:04:52 -04:00
|
|
|
if (BA > 0) {
|
2021-06-23 00:34:19 -04:00
|
|
|
Paths outs;
|
|
|
|
|
Clipper clip;
|
|
|
|
|
clip.AddPaths(inB, ptSubject, true);
|
|
|
|
|
clip.AddPaths(inA, ptClip, true);
|
|
|
|
|
clip.Execute(ctDifference, outs, pftEvenOdd, pftEvenOdd);
|
2021-06-23 11:13:45 -04:00
|
|
|
if (clean > 0) {
|
2021-07-11 11:04:52 -04:00
|
|
|
// CleanPolygons(outs, clean);
|
|
|
|
|
for (Path po : outs) {
|
|
|
|
|
CleanPolygon(po, clean);
|
|
|
|
|
}
|
2021-06-23 11:13:45 -04:00
|
|
|
}
|
2021-06-23 00:34:19 -04:00
|
|
|
pos = writePolys(outs, pos);
|
|
|
|
|
clip.Clear();
|
|
|
|
|
}
|
2021-06-21 23:26:54 -04:00
|
|
|
|
|
|
|
|
return resat;
|
|
|
|
|
}
|
2021-06-23 00:05:40 -04:00
|
|
|
|
|
|
|
|
__attribute__ ((export_name("set_debug")))
|
|
|
|
|
void set_debug(Uint8 value) {
|
|
|
|
|
debug = value;
|
|
|
|
|
}
|
2021-07-11 12:41:24 -04:00
|
|
|
|
|
|
|
|
__attribute__ ((export_name("test_string")))
|
|
|
|
|
void test_string(Uint8 value) {
|
|
|
|
|
// Creating a string from const char*
|
|
|
|
|
std::string str1 = "hello";
|
|
|
|
|
//std::string str1 = std::format("{} {}", "hello", value);
|
|
|
|
|
|
|
|
|
|
ostr(str1.length(), str1);
|
|
|
|
|
}
|