WASM binding v1

This commit is contained in:
Louis Gombert 2024-08-22 12:21:27 +00:00
parent 2bebe506c3
commit 8d229bbd1f
5 changed files with 208 additions and 1 deletions

View File

@ -64,10 +64,15 @@ IF(SALOME_BUILD_GUI)
)
ENDIF(SALOME_BUILD_GUI)
IF (DEFINED EMSCRIPTEN)
SET(SUBDIRS_WASM webassembly)
ENDIF()
SET(SUBDIRS
${SUBDIRS_COMMON}
${SUBDIRS_CGNS}
${SUBDIRS_GUI}
${SUBDIRS_WASM}
)
FOREACH(dir ${SUBDIRS})

View File

@ -186,7 +186,6 @@ class SMESH_EXPORT SMESH_Mesh
SMESH_Mesh* FindMesh( int meshId ) const;
SMESHDS_Mesh * GetMeshDS() { return _meshDS; }
const SMESHDS_Mesh * GetMeshDS() const { return _meshDS; }
SMESH_Gen *GetGen() { return _gen; }

View File

@ -0,0 +1,109 @@
#include "GEOMImpl_Gen.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "StdMeshers_Hexa_3D.hxx"
#include "StdMeshers_NumberOfSegments.hxx"
#include "StdMeshers_Quadrangle_2D.hxx"
#include "StdMeshers_Regular_1D.hxx"
#include <emscripten/bind.h>
/**
* Compute the total volume of the mesh
*/
double getTotalVolume(SMESH::Controls::Volume &volControl, SMESH_Mesh *mesh) {
std::cout << "Getting total volume" << std::endl;
double vol = 0;
SMDS_Mesh* ds = static_cast<SMDS_Mesh*>(mesh->GetMeshDS());
std::cout << "DS has " << ds->NbElements() << " elements" << std::endl;
volControl.SetMesh(ds);
for (int elemID = 0; elemID <= ds->NbElements(); elemID++) {
vol += volControl.GetValue(elemID);
}
return vol;
}
const std::string addHypothesis(SMESH_Mesh &mesh, TopoDS_Shape &shape, int id) {
std::string e;
mesh.AddHypothesis(shape, id, &e);
return e;
}
bool compute(SMESH_Gen& gen, SMESH_Mesh* mesh, TopoDS_Shape& shape) {
return gen.Compute(*mesh, shape);
}
// Required wrapping because SMESH_Mesh::GetMeshDS has 2 overloads, one const
// and one not const, so the reference cannot decide which one to choose
// SMDS_Mesh *getMeshDS(SMESH_Mesh &mesh) {
// return static_cast<SMDS_Mesh *>(mesh.GetMeshDS());
// }
// void setMesh(SMESH::Controls::Volume &vol, SMDS_Mesh* mesh) {
// vol.SetMesh(mesh);
// }
EMSCRIPTEN_BINDINGS(smesh) {
// OCCT bindings
emscripten::class_<TopoDS_Shape>("CAS_Shape").constructor<>();
// GEOM Bindings
emscripten::class_<GEOMImpl_Gen>("GEOM_Gen")
.constructor<>()
.function("GetI3DPrimOperations", &GEOMImpl_Gen::GetI3DPrimOperations,
emscripten::allow_raw_pointers());
// CAS Pointer
emscripten::class_<Handle_GEOM_Object>("Handle_GEOM_Object")
.function("get", &Handle_GEOM_Object::get,
emscripten::allow_raw_pointers());
emscripten::class_<GEOM_Object>("GEOM_Object")
.function("GetValue", &GEOM_Object::GetValue);
emscripten::class_<GEOMImpl_I3DPrimOperations>("GEOM_PrimOperations")
.function("MakeBoxDXDYDZ", &GEOMImpl_I3DPrimOperations::MakeBoxDXDYDZ);
// SMESH Bindings
emscripten::class_<SMESH_Gen>("SMESH_Gen")
.constructor<>()
.function("CreateMesh", &SMESH_Gen::CreateMesh,
emscripten::allow_raw_pointers())
.function("Compute", &compute,
emscripten::allow_raw_pointers());
emscripten::class_<SMESHDS_Mesh>("SMESH_DS_Mesh")
.function("NbElements", &SMESHDS_Mesh::NbElements);
emscripten::class_<SMDS_Mesh>("SMESH_SMDS_Mesh");
emscripten::class_<SMESH_Hypothesis>("SMESH_Hypothesis")
.class_function("IsStatusFatal", &SMESH_Hypothesis::IsStatusFatal);
emscripten::class_<SMESH_Mesh>("SMESH_Mesh")
.function("ShapeToMesh", &SMESH_Mesh::ShapeToMesh)
.function("AddHypothesis", &addHypothesis,
emscripten::allow_raw_pointers());
// .function("GetMeshDS", &getMeshDS, emscripten::allow_raw_pointers());
// Meshers
emscripten::class_<StdMeshers_Regular_1D>("SMESH_Meshers_Regular_1D")
.constructor<int, SMESH_Gen *>();
emscripten::class_<StdMeshers_NumberOfSegments>(
"SMESH_Meshers_NumberOfSegments")
.constructor<int, SMESH_Gen *>()
.function("SetNumberOfSegments",
&StdMeshers_NumberOfSegments::SetNumberOfSegments);
emscripten::class_<StdMeshers_Quadrangle_2D>("SMESH_Meshers_Quadrangle_2D")
.constructor<int, SMESH_Gen *>();
emscripten::class_<StdMeshers_Hexa_3D>("SMESH_Meshers_Hexa_3D")
.constructor<int, SMESH_Gen *>();
// Measurements
emscripten::class_<SMESH::Controls::Volume>("SMESH_Controls_Volume")
.constructor<>()
// .function("SetMesh", &setMesh, emscripten::allow_raw_pointers())
// .function("GetValue", &SMESH::Controls::Volume::GetValue)
.function("GetTotal", &getTotalVolume, emscripten::allow_raw_pointers());
}

View File

@ -0,0 +1,39 @@
add_executable(smeshjs Bindings.cxx)
set_target_properties(smeshjs PROPERTIES
OUTPUT_NAME smesh
)
target_link_libraries(smeshjs PRIVATE SalomeIDLKernel GEOMImpl SMESHDS SMESHimpl StdMeshers SMESHEngine)
target_include_directories(smeshjs PRIVATE
${OpenCASCADE_INCLUDE_DIR}
${KERNEL_INCLUDE_DIRS}
${KERNEL_INCLUDE_DIRS}
${MEDFILE_INCLUDE_DIRS}
${MEDCOUPLING_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}/src/Controls
${PROJECT_SOURCE_DIR}/src/SMDS
${PROJECT_SOURCE_DIR}/src/SMESH
${PROJECT_SOURCE_DIR}/src/SMESHDS
${PROJECT_SOURCE_DIR}/src/StdMeshers
${PROJECT_SOURCE_DIR}/src/SMESHUtils
)
target_link_options(smeshjs PRIVATE
"$<IF:$<CONFIG:Release>,-Oz,-O0>"
"--bind"
"--closure 1"
"SHELL:-sEXPORT_NAME=smesh"
"SHELL:-sALLOW_MEMORY_GROWTH=1"
"SHELL:-sEMULATE_FUNCTION_POINTER_CASTS=0"
"SHELL:-sMODULARIZE=1"
"SHELL:-sWASM=1"
"SHELL:-sFORCE_FILESYSTEM"
"SHELL:-sEXPORTED_RUNTIME_METHODS=FS"
"SHELL:-sWASM_BIGINT"
"SHELL:-sNO_DISABLE_EXCEPTION_CATCHING"
)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/app.html"
"${CMAKE_BINARY_DIR}/src/webassembly/index.html"
COPYONLY)

55
src/webassembly/app.html Normal file
View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html class="theme-dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SMESH Web</title>
<style>
</style>
</head>
<body>
<section class="section">
</section>
<script type="text/javascript" src="smesh.js"></script>
<script type="text/javascript">
smesh()
.then((Module) => {
// Create a Geometric box of size 10^3
Module.geom = new Module.GEOM_Gen();
Module.prim = Module.geom.GetI3DPrimOperations();
Module.box = Module.prim.MakeBoxDXDYDZ(10.0, 10.0, 10.0);
Module.shape = Module.box.get().GetValue();
// Create a mesh for this shape
Module.smesh = new Module.SMESH_Gen();
Module.mesh = Module.smesh.CreateMesh(false);
Module.mesh.ShapeToMesh(Module.shape);
// Define hypothesis in 1D, 2D, 3D
Module.seg = new Module.SMESH_Meshers_Regular_1D(0, Module.smesh);
var err = Module.mesh.AddHypothesis(Module.shape, 0);
Module.segs = new Module.SMESH_Meshers_NumberOfSegments(1, Module.smesh);
Module.segs.SetNumberOfSegments(5);
err = Module.mesh.AddHypothesis(Module.shape, 1);
Module.segs = new Module.SMESH_Meshers_Quadrangle_2D(2, Module.smesh);
err = Module.mesh.AddHypothesis(Module.shape, 2);
Module.segs = new Module.SMESH_Meshers_Hexa_3D(3, Module.smesh);
err = Module.mesh.AddHypothesis(Module.shape, 3);
// Compute volume
Module.smesh.Compute(Module.mesh, Module.shape);
Module.volume = new Module.SMESH_Controls_Volume();
const vol = Module.volume.GetTotal(Module.mesh);
console.log(`Volume is ${vol}`);
})
.catch(error => console.error("Internal exception: " + error));
</script>
</body>
</html>