grid-apps-cmms/wasm/kiri-geo.cpp

230 lines
5.5 KiB
C++
Raw Normal View History

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 21:33:46 -04:00
const 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-06-22 21:33:46 -04:00
extern void abc(Uint32 a, Uint32 b, Uint32 c);
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-22 21:33:46 -04:00
Uint32 readPolys(Paths paths, Uint32 pos, Uint32 count) {
Uint32 poly = 0;
if (debug) abc(poly, count, pos);
while (count > 0) {
struct length16 *ls = (struct length16 *)(mem + pos);
Uint16 points = ls->length;
if (debug) polygon(points, 0);
pos += 2;
while (points-- > 0) {
struct point32 *ip = (struct point32 *)(mem + pos);
pos += 8;
paths[poly] << IntPoint(ip->x, ip->y);
if (debug) point(ip->x, ip->y);
}
poly++;
count--;
}
if (debug) abc(poly, count, pos);
return pos;
}
2020-05-04 12:10:16 -04:00
__attribute__ ((export_name("poly_offset")))
Uint32 poly_offset(Uint32 memat, Uint32 polys, float offset) {
Paths ins(polys);
Paths outs;
Uint32 pos = memat;
Uint16 poly = 0;
2021-06-22 21:33:46 -04:00
// pos = readPolys(ins, pos, polys);
2020-05-04 12:10:16 -04:00
while (poly < polys) {
struct length16 *ls = (struct length16 *)(mem + pos);
Uint16 points = ls->length;
2021-06-22 21:33:46 -04:00
if (debug) polygon(points, 0);
2020-05-04 12:10:16 -04:00
pos += 2;
while (points-- > 0) {
struct point32 *ip = (struct point32 *)(mem + pos);
pos += 8;
ins[poly] << IntPoint(ip->x, ip->y);
2021-06-22 21:33:46 -04:00
if (debug) point(ip->x, ip->y);
2020-05-04 12:10:16 -04:00
}
poly++;
}
2021-06-22 21:33:46 -04:00
if (debug) abc(memat, pos, memat - pos);
2020-05-04 20:08:22 -04:00
// clean and simplify polygons
// Paths cleans, simples;
// CleanPolygons(ins, cleans, 250);
// SimplifyPolygons(cleans, simples, pftNonZero);
// ins = simples;
2020-05-04 12:10:16 -04:00
ClipperOffset co;
co.AddPaths(ins, jtMiter, etClosedPolygon);
co.Execute(outs, offset);
Uint32 resat = pos;
for (Path po : outs) {
2021-06-22 21:33:46 -04:00
if (debug) polygon(po.size(), 1);
2020-05-04 12:10:16 -04:00
struct length16 *ls = (struct length16 *)(mem + pos);
ls->length = po.size();
pos += 2;
for (IntPoint pt : po) {
2021-06-22 21:33:46 -04:00
if (debug) point(pt.X, pt.Y);
2020-05-04 12:10:16 -04:00
struct point32 *ip = (struct point32 *)(mem + pos);
2020-05-04 20:08:22 -04:00
ip->x = (int)pt.X;
ip->y = (int)pt.Y;
2020-05-04 12:10:16 -04:00
pos += 8;
}
}
2020-05-04 20:08:22 -04:00
// null terminate
struct length16 *ls = (struct length16 *)(mem + pos);
ls->length = 0;
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;
while (poly < polys) {
struct length16 *ls = (struct length16 *)(mem + pos);
Uint16 points = ls->length;
pos += 2;
while (points-- > 0) {
struct point32 *ip = (struct point32 *)(mem + pos);
pos += 8;
ins[poly] << IntPoint(ip->x, ip->y);
}
poly++;
}
Clipper clip;
2021-06-22 17:16:01 -04:00
clip.AddPaths(ins, ptSubject, true);
clip.Execute(ctUnion, outs);
Uint32 resat = pos;
for (Path po : outs) {
struct length16 *ls = (struct length16 *)(mem + pos);
ls->length = po.size();
pos += 2;
for (IntPoint pt : po) {
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;
clip.Clear();
return resat;
}
__attribute__ ((export_name("poly_diff")))
Uint32 poly_diff(Uint32 memat, Uint32 polysA, Uint32 polysB, float offset) {
Paths inA(polysA);
Paths inB(polysB);
Paths outs;
Uint32 pos = memat;
for (Uint32 poly = 0; poly < polysA; poly++ ) {
struct length16 *ls = (struct length16 *)(mem + pos);
Uint16 points = ls->length;
pos += 2;
while (points-- > 0) {
struct point32 *ip = (struct point32 *)(mem + pos);
pos += 8;
inA[poly] << IntPoint(ip->x, ip->y);
}
poly++;
}
for (Uint32 poly = 0; poly < polysB; poly++ ) {
struct length16 *ls = (struct length16 *)(mem + pos);
Uint16 points = ls->length;
pos += 2;
while (points-- > 0) {
struct point32 *ip = (struct point32 *)(mem + pos);
pos += 8;
inB[poly] << IntPoint(ip->x, ip->y);
}
poly++;
}
Clipper clip;
clip.AddPaths(inA, ptSubject, true);
clip.AddPaths(inB, ptClip, true);
clip.Execute(ctDifference, outs, pftEvenOdd, pftEvenOdd);
2021-06-21 23:26:54 -04:00
Uint32 resat = pos;
for (Path po : outs) {
struct length16 *ls = (struct length16 *)(mem + pos);
ls->length = po.size();
pos += 2;
for (IntPoint pt : po) {
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;
clip.Clear();
return resat;
}