Fix WASM build of skeleton tool

This commit is contained in:
jaseg 2025-12-15 14:25:57 +01:00
parent 0d44db1398
commit 2f6f35591e
4 changed files with 171 additions and 0 deletions

1
cgal_skeleton_core/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
cache

View file

@ -0,0 +1,67 @@
CXX ?= clang++
BUILDDIR ?= build
CACHEDIR ?= cache
CGAL ?= CGAL-6.1
CGAL_URL ?= https://github.com/CGAL/cgal/releases/download/v6.1/CGAL-6.1-library.tar.xz
BOOST ?= boost_1_90_0
BOOST_URL ?= https://archives.boost.io/release/1.90.0/source/boost_1_90_0.tar.gz
WASI_SDK_URL ?= https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-29/wasi-sdk-29.0-x86_64-linux.tar.gz
WASI_SDK ?= $(CACHEDIR)/wasi-sdk-29.0-x86_64-linux
SOURCES := \
skeleton_wrapper.cpp
WASI_SOURCES := \
$(SOURCES) \
exception_stubs.cpp \
INCLUDES := -I$(CACHEDIR)/$(CGAL)/include -I$(CACHEDIR)/$(BOOST)
CXXFLAGS := -std=c++20 -g -Wall -Wextra -O2
WASI_CXXFLAGS := -DCGAL_ALWAYS_ROUND_TO_NEAREST -DCGAL_CORE_USE_BOOST_BACKEND -DCGAL_DISABLE_GMP -DCGAL_USE_BOOST_MP -DFE_UPWARD=FE_TONEAREST -D_WASI_EMULATED_PROCESS_CLOCKS $(CXXFLAGS)
LDFLAGS :=
HOST_LDFLAGS := $(LDFLAGS) -lgmp -lmpfr
WASI_LDFLAGS := $(LDFLAGS) -lwasi-emulated-process-clocks
WASI_CXX ?= $(WASI_SDK)/bin/clang++
BINARY := skeleton
all: $(BUILDDIR)/$(BINARY) wasm
.PHONY: wasm
wasm: $(BUILDDIR)/$(BINARY).wasm
$(BUILDDIR)/$(BINARY): $(SOURCES)
$(CXX) $(CXXFLAGS) $(HOST_LDFLAGS) -o $@ $^
$(WASI_SDK):
mkdir -p $(dir $@)
cd $(dir $@); curl -L ${WASI_SDK_URL} | tar xzf -
$(CACHEDIR)/$(BOOST):
cd $(dir $@); curl -L ${BOOST_URL} | tar xzf -
$(CACHEDIR)/$(CGAL):
cd $(dir $@); curl -L ${CGAL_URL} | tar xJf -
$(BUILDDIR)/wasi/%.o: %.cpp $(WASI_SDK)
@mkdir -p $(dir $@)
$(WASI_CXX) -c $(WASI_CXXFLAGS) $(INCLUDES) -o $@ $<
$(BUILDDIR)/$(BINARY).wasm: $(patsubst %.cpp,$(BUILDDIR)/wasi/%.o,$(WASI_SOURCES))
@mkdir -p $(dir $@)
$(WASI_CXX) $(WASI_LDFLAGS) -o $@ $^
.PHONY: clean
clean:
rm -rf $(BUILDDIR)
.PHONY: mrproper
mrproper: clean
rm -rf $(CACHEDIR)

View file

@ -0,0 +1,13 @@
#include <stdlib.h>
extern "C" {
void* __cxa_allocate_exception(size_t) {
abort();
}
void __cxa_throw(void *, void *, void (*)(void *)) {
abort();
}
}

View file

@ -0,0 +1,90 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/create_straight_skeleton_2.h>
#include <iostream>
#include <sstream>
#include <string>
#include <memory>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Polygon_2<K> Polygon_2;
typedef CGAL::Straight_skeleton_2<K> Ss;
typedef std::shared_ptr<Ss> SsPtr;
int main()
{
// Read polygon from stdin
Polygon_2 poly;
std::string line;
while (std::getline(std::cin, line)) {
if (line.empty()) {
continue;
}
std::istringstream iss(line);
double x, y;
if (iss >> x >> y) {
poly.push_back(Point(x, y));
} else {
std::cerr << "Error: Invalid input line: " << line << std::endl;
return EXIT_FAILURE;
}
}
if (poly.size() < 3) {
std::cerr << "Error: Polygon must have at least 3 vertices" << std::endl;
return EXIT_FAILURE;
}
// Ensure counter-clockwise orientation
if (!poly.is_counterclockwise_oriented()) {
poly.reverse_orientation();
}
// Create interior straight skeleton
SsPtr ss = CGAL::create_interior_straight_skeleton_2(poly.vertices_begin(), poly.vertices_end());
if (!ss) {
std::cerr << "Error: Failed to create straight skeleton" << std::endl;
return EXIT_FAILURE;
}
// Output skeleton edges
// Iterate through all halfedges in the skeleton
for (auto he = ss->halfedges_begin(); he != ss->halfedges_end(); ++he) {
// Only output each edge once (skip the opposite halfedge)
if (he->id() < he->opposite()->id()) {
continue;
}
// Get the vertices at both ends of the halfedge
auto v_source = he->vertex();
auto v_target = he->opposite()->vertex();
// Get times (distance from boundary)
double t1 = CGAL::to_double(v_source->time());
double t2 = CGAL::to_double(v_target->time());
// Skip contour edges (outline of the input polygon)
// Contour edges have both vertices at time 0
if (t1 == 0.0 && t2 == 0.0) {
continue;
}
// Get coordinates
double x1 = CGAL::to_double(v_source->point().x());
double y1 = CGAL::to_double(v_source->point().y());
double x2 = CGAL::to_double(v_target->point().x());
double y2 = CGAL::to_double(v_target->point().y());
// Output: start_x start_y end_x end_y start_time end_time
std::cout << std::setprecision(12) << x1 << " " << y1 << " "
<< x2 << " " << y2 << " "
<< t1 << " " << t2 << std::endl;
}
return EXIT_SUCCESS;
}