Skip to content

Commit

Permalink
python module: export 3D render
Browse files Browse the repository at this point in the history
  • Loading branch information
carrotIndustries committed Apr 25, 2020
1 parent 0a4cbc4 commit 619b74b
Show file tree
Hide file tree
Showing 9 changed files with 570 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: apt-get update -y && apt-get install libsqlite3-dev util-linux librsvg2-dev libcairomm-1.0-dev libepoxy-dev libgtkmm-3.0-dev uuid-dev libboost-dev libzmq5 libzmq3-dev libglm-dev libgit2-dev libcurl4-gnutls-dev liboce-ocaf-dev libpodofo-dev python3-dev libzip-dev git -y
run: apt-get update -y && apt-get install libsqlite3-dev util-linux librsvg2-dev libcairomm-1.0-dev libepoxy-dev libgtkmm-3.0-dev uuid-dev libboost-dev libzmq5 libzmq3-dev libglm-dev libgit2-dev libcurl4-gnutls-dev liboce-ocaf-dev libpodofo-dev python3-dev libzip-dev git python3-cairo-dev libosmesa6-dev -y
- name: Build
run: make -j2 build/horizon.so
- name: Test python module
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ FROM debian:buster AS build
COPY src /src
RUN apt-get update
RUN apt-get upgrade
RUN apt-get install -y build-essential libsqlite3-dev util-linux librsvg2-dev libcairomm-1.0-dev libepoxy-dev libgtkmm-3.0-dev uuid-dev libboost-dev libzmq5 libzmq3-dev libglm-dev libgit2-dev libcurl4-gnutls-dev liboce-ocaf-dev libpodofo-dev python3-dev libzip-dev git
RUN apt-get install -y build-essential libsqlite3-dev util-linux librsvg2-dev libcairomm-1.0-dev libepoxy-dev libgtkmm-3.0-dev uuid-dev libboost-dev libzmq5 libzmq3-dev libglm-dev libgit2-dev libcurl4-gnutls-dev liboce-ocaf-dev libpodofo-dev python3-dev libzip-dev git python3-cairo-dev libosmesa6-dev
WORKDIR /src
RUN make -j$(nproc) build/horizon.so
RUN strip build/horizon.so

FROM debian:buster
RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y --no-install-recommends python3 libzip4 libpython3.7 libglibmm-2.4-1v5 libpodofo0.9.6 liboce-ocaf11 python3-pygit2 git ca-certificates
RUN apt-get install -y --no-install-recommends python3 libzip4 libpython3.7 libglibmm-2.4-1v5 libpodofo0.9.6 liboce-ocaf11 python3-pygit2 git ca-certificates python3-cairo libosmesa6
COPY --from=build /src/build/horizon.so /usr/local/lib/python3.7/dist-packages
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -614,9 +614,11 @@ SRC_PYTHON = \
src/python_module/board.cpp \
src/python_module/pool_manager.cpp \
src/python_module/pool.cpp \
src/python_module/3d_image_exporter.cpp \

SRC_OCE_EXPORT = \
src/export_step/export_step.cpp\
src/util/step_importer.cpp\

SRC_ALL = $(sort $(SRC_COMMON) $(SRC_IMP) $(SRC_POOL_UTIL) $(SRC_PRJ_UTIL) $(SRC_POOL_UPDATE_PARA) $(SRC_PGM_TEST) $(SRC_POOL_PRJ_MGR) $(SRC_GEN_PKG))

Expand Down Expand Up @@ -690,6 +692,14 @@ SRC_SHARED = $(SRC_COMMON) \
src/pool-update/pool-update.cpp \
src/pool-update/pool-update_parametric.cpp\
src/pool-update/graph.cpp\
src/export_3d_image/export_3d_image.cpp\
src/canvas3d/canvas3d_base.cpp\
src/canvas3d/canvas_mesh.cpp\
src/canvas3d/background.cpp\
src/canvas3d/wall.cpp\
src/canvas3d/cover.cpp\
src/canvas3d/face.cpp\
src/canvas/gl_util.cpp\

SRC_SHARED_GEN = $(SRC_COMMON_GEN)

Expand Down Expand Up @@ -725,7 +735,7 @@ OBJ_GEN_PKG = $(addprefix $(OBJDIR)/,$(SRC_GEN_PKG:.cpp=.o))

INC_ROUTER = -I3rd_party/router/include/ -I3rd_party/router -I3rd_party
INC_OCE ?= -I/opt/opencascade/inc/ -I/mingw64/include/oce/ -I/usr/include/oce -I/usr/include/opencascade -I${CASROOT}/include/opencascade -I/usr/local/include/OpenCASCADE
INC_PYTHON = $(shell $(PKGCONFIG) --cflags python3)
INC_PYTHON = $(shell $(PKGCONFIG) --cflags python3 py3cairo)
OCE_LIBDIRS = -L/opt/opencascade/lib/ -L${CASROOT}/lib
LDFLAGS_OCE = $(OCE_LIBDIRS) -lTKSTEP -lTKernel -lTKXCAF -lTKXSBase -lTKBRep -lTKCDF -lTKXDESTEP -lTKLCAF -lTKMath -lTKMesh -lTKTopAlgo -lTKPrim -lTKBO
ifeq ($(OS),Windows_NT)
Expand Down Expand Up @@ -784,7 +794,7 @@ $(BUILDDIR)/horizon-gen-pkg: $(OBJ_COMMON) $(OBJ_GEN_PKG)

$(BUILDDIR)/horizon.so: $(OBJ_PYTHON) $(OBJ_SHARED) $(OBJ_SHARED_OCE)
$(ECHO) " $@"
$(QUIET)$(CXX) $^ $(LDFLAGS) $(INC) $(CXXFLAGS) $(shell $(PKGCONFIG) --libs $(LIBS_COMMON) python3 glibmm-2.4 giomm-2.4) -lpodofo $(OCE_LIBDIRS) -lTKXDESTEP -shared -o $@
$(QUIET)$(CXX) $^ $(LDFLAGS) $(INC) $(CXXFLAGS) $(shell $(PKGCONFIG) --libs $(LIBS_COMMON) python3 glibmm-2.4 giomm-2.4 cairomm-1.0 py3cairo) -lpodofo $(OCE_LIBDIRS) -lTKXDESTEP -lOSMesa -shared -o $@

$(OBJDIR)/%.o: %.c
$(QUIET)$(MKDIR) $(dir $@)
Expand All @@ -804,7 +814,7 @@ $(OBJ_SHARED_OCE): INC += $(INC_OCE)
$(PICOBJDIR)/%.o: %.cpp
$(QUIET)$(MKDIR) $(dir $@)
$(ECHO) " $@"
$(QUIET)$(CXX) -c $(INC) $(CXXFLAGS) -fPIC $< -o $@
$(QUIET)$(CXX) -c $(INC) $(CXXFLAGS) -fPIC -DOFFSCREEN=1 $< -o $@

$(OBJ_PYTHON): INC += $(INC_PYTHON)

Expand Down
99 changes: 99 additions & 0 deletions src/export_3d_image/export_3d_image.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "export_3d_image.hpp"
#include "canvas3d/canvas3d_base.hpp"
#include "GL/osmesa.h"
#include <cairomm/cairomm.h>

namespace horizon {

Image3DExporter::Image3DExporter(const class Board &abrd, class Pool &apool, unsigned int awidth, unsigned int aheight)
: pool(apool)
{
width = awidth;
height = aheight;

{
std::vector<int> attribs;
attribs.push_back(OSMESA_DEPTH_BITS);
attribs.push_back(16);

attribs.push_back(OSMESA_PROFILE);
attribs.push_back(OSMESA_CORE_PROFILE);

attribs.push_back(OSMESA_CONTEXT_MAJOR_VERSION);
attribs.push_back(3);

attribs.push_back(0);
attribs.push_back(0);
ctx = OSMesaCreateContextAttribs(attribs.data(), NULL);
}
if (!ctx) {
throw std::runtime_error("couldn't create context");
}
buffer.resize(width * height * 4);
if (!OSMesaMakeCurrent(static_cast<OSMesaContext>(ctx), buffer.data(), GL_UNSIGNED_BYTE, width, height)) {
throw std::runtime_error("couldn't make current");
}
a_realize();

brd = &abrd;
ca.update(*brd);
prepare_packages();
prepare();
push();
}

void Image3DExporter::check_ctx()
{
if (ctx != OSMesaGetCurrentContext()) {
throw std::runtime_error("lost context");
}
}

void Image3DExporter::load_3d_models()
{
check_ctx();
clear_3d_models();
auto model_filenames = get_model_filenames(pool);
for (const auto &it : model_filenames) {
std::cout << "load " << it.first << std::endl;
load_3d_model(it.first, it.second);
}
package_height_max = 0;
for (const auto &it : face_vertex_buffer) {
package_height_max = std::max(it.z, package_height_max);
}
face_renderer.push();
}


Cairo::RefPtr<Cairo::Surface> Image3DExporter::render_to_surface()
{
check_ctx();
render(render_background ? RenderBackground::YES : RenderBackground::NO);
glFinish();

auto buf = buffer.data();
unsigned int iwidth = width;
unsigned int iheight = height;
auto surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, iwidth, iheight);
unsigned char *data = surf->get_data();
for (size_t y = 0; y < iheight; y++) {
auto offset = (iheight - y - 1) * surf->get_stride();
for (size_t x = 0; x < iwidth; x++) {
auto p = &data[x * 4 + offset];
auto pb = &buf[(y * iwidth + x) * 4];
p[0] = pb[2];
p[1] = pb[1];
p[2] = pb[0];
p[3] = pb[3];
}
}
surf->mark_dirty();
return surf;
}

Image3DExporter::~Image3DExporter()
{
OSMesaDestroyContext(static_cast<OSMesaContext>(ctx));
}
} // namespace horizon
25 changes: 25 additions & 0 deletions src/export_3d_image/export_3d_image.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once
#include <string>
#include <vector>
#include "canvas3d/canvas3d_base.hpp"
#include <cairomm/cairomm.h>

namespace horizon {

class Image3DExporter : public Canvas3DBase {
public:
Image3DExporter(const class Board &brd, class Pool &pool, unsigned int width, unsigned int height);

void load_3d_models();
Cairo::RefPtr<Cairo::Surface> render_to_surface();
virtual ~Image3DExporter();
bool render_background = false;

private:
class Pool &pool;
void *ctx = nullptr; // to get around including osmesa here
std::vector<unsigned char> buffer;
void check_ctx();
};

} // namespace horizon

0 comments on commit 619b74b

Please sign in to comment.