Skip to content

Commit

Permalink
✨ feat: update chili-wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangechen committed Sep 13, 2024
1 parent 1fefb83 commit bd19007
Show file tree
Hide file tree
Showing 23 changed files with 1,386 additions and 728 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"source.organizeImports": "explicit"
},
"editor.inlineSuggest.showToolbar": "onHover",
"cmake.sourceDirectory": "${workspaceFolder}/cpp"
"cmake.sourceDirectory": "${workspaceFolder}/cpp",
"C_Cpp.default.configurationProvider": "${default}"
}
9 changes: 7 additions & 2 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,24 @@ set(OCCT_LIBS
if (CMAKE_SYSTEM_NAME STREQUAL Emscripten)
message(STATUS "EMSCRIPTEN: ${EMSCRIPTEN}")

add_executable(${TARGET} src/faceMesh.cpp src/occ.cpp src/shapeFactory.cpp)
add_executable(${TARGET} src/mesher.cpp src/opencascade.cpp src/shapeFactory.cpp)

target_compile_options (${TARGET} PUBLIC -O3)
target_compile_options (${TARGET} PUBLIC -flto)
target_compile_options (${TARGET} PUBLIC -fexceptions)
target_compile_options (${TARGET} PUBLIC -sDISABLE_EXCEPTION_CATCHING=1)
target_compile_options (${TARGET} PUBLIC -DIGNORE_NO_ATOMICS=1)
target_compile_options (${TARGET} PUBLIC -frtti)

target_link_options (${TARGET} PUBLIC -O3)
target_link_options (${TARGET} PUBLIC -flto)
target_link_options (${TARGET} PUBLIC -sEXPORT_ES6=1)
target_link_options (${TARGET} PUBLIC -sMODULARIZE=1)
target_link_options (${TARGET} PUBLIC -sENVIRONMENT="web")
target_link_options (${TARGET} PUBLIC -sEXPORT_NAME='ChiliWasm')
target_link_options (${TARGET} PUBLIC -sSTACK_SIZE=100MB)
target_link_options (${TARGET} PUBLIC -sALLOW_MEMORY_GROWTH=1)
target_link_options (${TARGET} PUBLIC -sDISABLE_EXCEPTION_CATCHING=1)
target_link_options (${TARGET} PUBLIC -sEXPORTED_RUNTIME_METHODS=["FS"])
target_link_options (${TARGET} PUBLIC --bind)
target_link_options (${TARGET} PUBLIC --emit-tsd "${TARGET}.d.ts")

Expand Down
4 changes: 0 additions & 4 deletions cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ Running this command will clone emscripten and install all dependencies, while a
To build the current project, please execute

```bash
# The reason for executing mv node_modules is to resolve a conflict with WebXR when generating .d.ts files. Are there any other solutions?

mv node_modules node_modules_backup
npm run build:wasm
mv node_modules_backup node_modules
```

After the compilation is completed, the target will be copied to the **packages/chili-wasm/lib** directory.
147 changes: 119 additions & 28 deletions cpp/src/faceMesh.cpp → cpp/src/mesher.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,96 @@
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepLib_ToolTriangulatedShape.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepTools.hxx>
#include <emscripten/bind.h>
#include <emscripten/val.h>
#include <BRep_Tool.hxx>
#include <gp_Pnt.hxx>
#include <GCPnts_TangentialDeflection.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Face.hxx>
#include <Poly_Triangulation.hxx>
#include <Standard_Handle.hxx>
#include <TopoDS.hxx>
#include <TopLoc_Location.hxx>
#include <TopExp_Explorer.hxx>
#include <Poly_Triangulation.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepLib_ToolTriangulatedShape.hxx>
#include <BRepTools.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS.hxx>
#include <TopExp.hxx>

using namespace emscripten;
using namespace std;

class FaceMesh
const double ANGLE_DEFLECTION = 0.5;

class EdgeMesher
{
private:
TopoDS_Shape shape;
double lineDeflection;
std::vector<float> position;
/// @brief start1,count1,material1,start2,count2,material2...
std::vector<int> group;
std::vector<TopoDS_Edge> edges;

void generateEdgeMeshs()
{
auto transform = shape.Location().Transformation().Inverted();

TopTools_IndexedMapOfShape edgeMap;
TopExp::MapShapes(this->shape, TopAbs_EDGE, edgeMap);
for (TopTools_IndexedMapOfShape::Iterator anIt(edgeMap); anIt.More(); anIt.Next())
{
auto start = this->position.size() / 3;

TopoDS_Edge edge = TopoDS::Edge(anIt.Value());
edges.push_back(edge);
generateEdgeMesh(edge, transform);

this->group.push_back(start);
this->group.push_back(this->position.size() / 3 - start);
this->group.push_back(0);
}
}

void generateEdgeMesh(const TopoDS_Edge& edge, const gp_Trsf &transform)
{
BRepAdaptor_Curve curve(edge);
GCPnts_TangentialDeflection pnts(curve, ANGLE_DEFLECTION, this->lineDeflection);
for (int i = 0; i < pnts.NbPoints(); i++)
{
auto pnt = pnts.Value(i + 1).Transformed(transform);
position.push_back(pnt.X());
position.push_back(pnt.Y());
position.push_back(pnt.Z());
}
}

public:
EdgeMesher(const TopoDS_Shape& shape, double lineDeflection) : shape(shape), lineDeflection(lineDeflection)
{
generateEdgeMeshs();
}

val getPosition()
{
return val(typed_memory_view(position.size(), position.data()));
}

val getGroups()
{
return val(typed_memory_view(group.size(), group.data()));
}

val getEdges()
{
return val::array(edges.begin(), edges.end());
}

};

class FaceMesher
{
private:
TopoDS_Shape shape;
Expand All @@ -28,16 +100,19 @@ class FaceMesh
std::vector<int> index;
/// @brief start1,count1,material1,start2,count2,material2...
std::vector<int> group;
std::vector<TopoDS_Face> faces;

void generateMeshs()
void generateFaceMeshs()
{
auto transform = shape.Location().Transformation().Inverted();
TopExp_Explorer explorer(this->shape, TopAbs_FACE);
for (; explorer.More(); explorer.Next())
TopTools_IndexedMapOfShape faceMap;
TopExp::MapShapes(this->shape, TopAbs_FACE, faceMap);
for (TopTools_IndexedMapOfShape::Iterator anIt(faceMap); anIt.More(); anIt.Next())
{
auto start = this->position.size() / 3;

generateFaceMesh(TopoDS::Face(explorer.Current()), transform);
auto face = TopoDS::Face(anIt.Value());
faces.push_back(face);
generateFaceMesh(face, transform);

this->group.push_back(start);
this->group.push_back(this->position.size() / 3 - start);
Expand Down Expand Up @@ -127,12 +202,11 @@ class FaceMesh
}
}


public:
FaceMesh(const TopoDS_Shape &shape) : shape(shape)
FaceMesher(const TopoDS_Shape &shape, double lineDeflection) : shape(shape)
{
BRepMesh_IncrementalMesh mesh(shape, 0.1, 0.5);
generateMeshs();
BRepMesh_IncrementalMesh mesh(shape, lineDeflection, false, 0.1);
generateFaceMeshs();
}

val getPosition()
Expand All @@ -159,16 +233,33 @@ class FaceMesh
{
return val(typed_memory_view(group.size(), group.data()));
}

val getFaces()
{
return val::array(faces.begin(), faces.end());
}
};

EMSCRIPTEN_BINDINGS(FaceMesh)
EMSCRIPTEN_BINDINGS(Mesher)
{
class_<FaceMesher>("FaceMesher")
.constructor<const TopoDS_Shape &, double>()
.function("getPosition", &FaceMesher::getPosition)
.function("getNormal", &FaceMesher::getNormal)
.function("getUV", &FaceMesher::getUV)
.function("getIndex", &FaceMesher::getIndex)
.function("getGroups", &FaceMesher::getGroups)
.function("getFaces", &FaceMesher::getFaces)
;

class_<EdgeMesher>("EdgeMesher")
.constructor<const TopoDS_Shape &, double>()
.function("getPosition", &EdgeMesher::getPosition)
.function("getGroups", &EdgeMesher::getGroups)
.function("getEdges", &EdgeMesher::getEdges)
;

register_vector<TopoDS_Face>("FaceVector");
register_vector<TopoDS_Edge>("EdgeVector");

class_<FaceMesh>("FaceMesh")
.constructor<TopoDS_Shape>()
.function("getPosition", &FaceMesh::getPosition)
.function("getNormal", &FaceMesh::getNormal)
.function("getUV", &FaceMesh::getUV)
.function("getIndex", &FaceMesh::getIndex)
.function("getGroups", &FaceMesh::getGroups);
}
File renamed without changes.
147 changes: 147 additions & 0 deletions cpp/test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>chili wasm test</title>
<style type="text/css">
body {
font-family: Arial, sans-serif;
}

#output {
margin: 20px;
}

h2 {
margin-top: 20px;
}

p {
margin: 0;
margin-left: 20px;
}

.failed {
color: red;
}

.result {
margin-top: 10px;
font-weight: bold;
}
</style>
</style>

</head>

<body>
<div id="output"></div>
<script type="text/javascript">
function resultMessage(passed, failed, time) {
let p = document.createElement('p');
p.className = 'result';
p.innerHTML = `Passed: ${passed}, Failed: ${failed}, Time: ${time}`;
if (failed > 0) {
p.className += ' failed';
}
return p;
}

function failedMessage(actual, expected) {
let p = document.createElement('p');
p.innerHTML = `Expected ${expected}, but got ${actual}`;
p.className = 'failed';
return p;
}

async function test(name, fn) {
var passed = 0, failed = 0;
const expect = (actual) => {
return {
toBe(expected) {
if (actual !== expected) {
div.append(failedMessage(actual, expected));
failed++;
} else {
passed++;
}
}
};
};

let div = document.createElement('div');
div.className = 'test';
output.append(div);
let title = document.createElement('h2');
div.innerHTML = name
output.append(title);
let start = performance.now();
fn(expect);
let end = performance.now();
div.append(resultMessage(passed, failed, end - start));
}

</script>
<script type="module">
window.onload = async () => {
let output = document.getElementById('output');
let initWasm = await import('../build/chili/chili-wasm.js');
console.log(initWasm);

let wasm = await initWasm.default();

test("test face mesh", (expect) => {
let point1 = new wasm.gp_Pnt(0, 0, 0);
let direction = new wasm.gp_Dir(0, 0, 1);
let ax2 = new wasm.gp_Ax2(point1, direction);
let box = wasm.ShapeFactory.makeBox(ax2, 1, 1, 1);
let mesh = new wasm.FaceMesher(box, 0.1);

expect(mesh.getPosition().length).toBe(72);
expect(mesh.getIndex().length).toBe(36);
expect(mesh.getGroups().length).toBe(18);
expect(mesh.getNormal().length).toBe(72);
expect(mesh.getUV().length).toBe(48);
expect(mesh.getFaces().length).toBe(6);
})

test("test edge mesh", (expect) => {
let point1 = new wasm.gp_Pnt(0, 0, 0);
let direction = new wasm.gp_Dir(0, 0, 1);
let ax2 = new wasm.gp_Ax2(point1, direction);
let box = wasm.ShapeFactory.makeBox(ax2, 1, 1, 1);
let mesh = new wasm.EdgeMesher(box, 0.1);

expect(mesh.getEdges().length).toBe(12);
expect(mesh.getPosition().length).toBe(72);
expect(mesh.getGroups().length).toBe(36);
})

test("test mesh 8000", (expect) => {
let count = 0;
for (let i = 0; i < 8000; i++) {
let point1 = new wasm.gp_Pnt(0, 0, 0);
let direction = new wasm.gp_Dir(0, 0, 1);
let ax2 = new wasm.gp_Ax2(point1, direction);
let box = wasm.ShapeFactory.makeBox(ax2, 10, 10, 10);
let fm = new wasm.FaceMesher(box, 0.1);
let em = new wasm.EdgeMesher(box, 0.1);
// count += fm.getPosition().length;
point1.delete();
direction.delete();
ax2.delete();
box.delete();
fm.delete();
em.delete();
}

})

}
</script>

</body>

</html>
Loading

0 comments on commit bd19007

Please sign in to comment.