Skip to content

Commit

Permalink
clean
Browse files Browse the repository at this point in the history
  • Loading branch information
LiangliangNan committed Dec 24, 2024
1 parent eb7ee45 commit c706056
Show file tree
Hide file tree
Showing 43 changed files with 47 additions and 113 deletions.
27 changes: 25 additions & 2 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

![3D model generated and rendered by Easy3D](resources/images/logo.jpg)

#### Easy3D is an open-source library for 3D modeling, geometry processing, and rendering. It is implemented in C++ and designed with an emphasis on simplicity and efficiency. Easy3D is intended for research and educational purposes, but it is also a good starting point for developing sophisticated 3D applications.
#### An open-source library for 3D modeling, geometry processing, and rendering, designed with an emphasis on simplicity and efficiency.
Easy3D is implemented in C++ and extended with **Python bindings**. It is intended for research and educational purposes, but it is also a good starting point for developing sophisticated 3D applications.
Compared to existing geometry processing libraries (such as [PMP](http://www.pmp-library.org/) and [libigl](https://github.com/libigl/libigl/)) that focus on the algorithm aspect, Easy3D also provides a wider range of functionalities for user interactions and rendering.

<p align="center">
Expand Down Expand Up @@ -42,6 +43,9 @@ Compared to existing geometry processing libraries (such as [PMP](http://www.pmp

* A handy tool <b>Mapple</b> created out of the Easy3D library for rendering and processing 3D data.

* Python bindings for Easy3D, which allow you to use Easy3D in Python scripts. The Python bindings are generated using
[pybind11](https://pybind11.readthedocs.io/en/stable/index.html). **Note**: the Python bindings (and examples) are still under active development.

| Scalar field | Polyhedral mesh | Keyframe animation |
|------------------------------------------|-------------------------------------------|--------------------------------------------|
| ![](resources/images/mapple-scalar.jpg) | ![](resources/images/mapple-polymesh.gif) | ![](resources/images/mapple-animation.gif) |
Expand Down Expand Up @@ -85,6 +89,7 @@ configuring and building programs, as well as a set of subfolders:
* [`renderer`](https://github.com/LiangliangNan/Easy3D/tree/main/easy3d/renderer) - functionalities and algorithms for rendering and visualization.
* [`gui`](https://github.com/LiangliangNan/Easy3D/tree/main/easy3d/gui) - tools for user interactions, e.g., picking points, faces, or models.
* [`viewer`](https://github.com/LiangliangNan/Easy3D/tree/main/easy3d/viewer) - a simple viewer and a composite viewer.
* [`python`](https://github.com/LiangliangNan/Easy3D/tree/main/python) - Python bindings for Easy3D, and examples.
* [`resources`](https://github.com/LiangliangNan/Easy3D/tree/main/resources) - test data, images, shaders, textures, etc.
* [`tests`](https://github.com/LiangliangNan/Easy3D/tree/main/tests) - a collection of test cases
* [`tutorials`](https://github.com/LiangliangNan/Easy3D/tree/main/tutorials) - a collection of examples (with detailed explanations in code)
Expand Down Expand Up @@ -143,7 +148,15 @@ There are many options to build Easy3D. Choose one of the following (not an exha
- Option 3: Use CMake-Gui to generate project files for your IDE. Then load the project to your IDE and build it. For Windows users: your IDE must be set for `x64`.
Don't have any experience with C/C++ programming?
#### Build and install Python bindings
- Make sure you have Python and [pybind11](https://pybind11.readthedocs.io/en/stable/index.html) installed.
Then switch on the CMake option `Easy3D_ENABLE_PYTHON` and run CMake. After building Easy3D, you can find the Python bindings in `YOUR_BUILD_DIRECTORY/lib/python`.
- To install the Python bindings, you can use the following command:
```
pip install YOUR_BUILD_DIRECTORY/lib/python/setup.py
```
Do not have any experience with C/C++ programming?
Have a look at <a href="https://github.com/LiangliangNan/Easy3D/blob/main/HowToBuild.md">How to build Easy3D step by
step</a>.
Expand Down Expand Up @@ -181,6 +194,16 @@ int main(int argc, char** argv) {
}
```
Using the Python bindings is also straightforward, for example:
``` python
import easy3d
easy3d.initialize()
viewer = easy3d.Viewer("Test")
viewer.add_model("path-to-your-model")
viewer.run()
```

### Documentation
The documentation for Easy3D is available [here](https://3d.bk.tudelft.nl/liangliang/software/easy3d_doc/html/index.html).

Expand Down
40 changes: 1 addition & 39 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12)
project(PyEasy3D)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 11) # If you use pybind11::overload_cast<...>, then it requires compiling in C++14 mode

find_package(pybind11 REQUIRED)

Expand Down Expand Up @@ -56,7 +56,6 @@ set(BINDING_SOURCES
"bindings/easy3d/core/poly_mesh.cpp"
"bindings/easy3d/core/property.cpp"
"bindings/easy3d/core/random.cpp"
"bindings/easy3d/core/signal.cpp"
"bindings/easy3d/core/surface_mesh.cpp"
"bindings/easy3d/core/surface_mesh_builder.cpp"
"bindings/easy3d/core/types.cpp"
Expand All @@ -76,56 +75,19 @@ set(BINDING_SOURCES

"bindings/easy3d/renderer/camera.cpp"

"bindings/easy3d/util/console_style.cpp"
"bindings/easy3d/util/dialog.cpp"
"bindings/easy3d/util/file_system.cpp"
"bindings/easy3d/util/initializer.cpp"
"bindings/easy3d/util/line_stream.cpp"
"bindings/easy3d/util/logging.cpp"
"bindings/easy3d/util/progress.cpp"
"bindings/easy3d/util/resource.cpp"
"bindings/easy3d/util/setting.cpp"
"bindings/easy3d/util/stop_watch.cpp"
"bindings/easy3d/util/string.cpp"
"bindings/easy3d/util/timer.cpp"
"bindings/easy3d/util/tokenizer.cpp"
"bindings/easy3d/util/version.cpp"

"bindings/easy3d/viewer/multi_viewer.cpp"
"bindings/easy3d/viewer/offscreen.cpp"
"bindings/easy3d/viewer/viewer.cpp"

# Seems never needed
# "bindings/easy3d/gui/picker.cpp"
# "bindings/easy3d/gui/picker_model.cpp"
# "bindings/easy3d/gui/picker_point_cloud.cpp"
# "bindings/easy3d/gui/picker_surface_mesh.cpp"
# "bindings/easy3d/renderer/ambient_occlusion.cpp"
# "bindings/easy3d/renderer/buffer.cpp"
# "bindings/easy3d/renderer/clipping_plane.cpp"
# "bindings/easy3d/renderer/constraint.cpp"
# "bindings/easy3d/renderer/drawable_lines.cpp"
# "bindings/easy3d/renderer/eye_dome_lighting.cpp"
# "bindings/easy3d/renderer/framebuffer_object.cpp"
# "bindings/easy3d/renderer/frustum.cpp"
# "bindings/easy3d/renderer/key_frame_interpolator.cpp"
# "bindings/easy3d/renderer/manipulated_frame.cpp"
# "bindings/easy3d/renderer/opengl_error.cpp"
# "bindings/easy3d/renderer/opengl_timer.cpp"
# "bindings/easy3d/renderer/read_pixel.cpp"
# "bindings/easy3d/renderer/renderer.cpp"
# "bindings/easy3d/renderer/shader_manager.cpp"
# "bindings/easy3d/renderer/shader_program.cpp"
# "bindings/easy3d/renderer/shadow.cpp"
# "bindings/easy3d/renderer/shape.cpp"
# "bindings/easy3d/renderer/soft_shadow.cpp"
# "bindings/easy3d/renderer/state.cpp"
# "bindings/easy3d/renderer/text_renderer.cpp"
# "bindings/easy3d/renderer/texture.cpp"
# "bindings/easy3d/renderer/texture_manager.cpp"
# "bindings/easy3d/renderer/transform.cpp"
# "bindings/easy3d/renderer/transparency.cpp"
# "bindings/easy3d/renderer/vertex_array_object.cpp"
)

if(Easy3D_HAS_CGAL)
Expand Down
37 changes: 1 addition & 36 deletions python/bindings/easy3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ void bind_easy3d_core_point_cloud(pybind11::module_ &m);
void bind_easy3d_core_poly_mesh(pybind11::module_ &m);
void bind_easy3d_core_property(pybind11::module_ &m);
void bind_easy3d_core_random(pybind11::module_ &m);
void bind_easy3d_core_signal(pybind11::module_ &m);
void bind_easy3d_core_surface_mesh(pybind11::module_ &m);
void bind_easy3d_core_surface_mesh_builder(pybind11::module_ &m);
void bind_easy3d_core_types(pybind11::module_ &m);
Expand Down Expand Up @@ -65,49 +64,21 @@ void bind_easy3d_fileio_poly_mesh_io(pybind11::module_ &m);
void bind_easy3d_fileio_surface_mesh_io(pybind11::module_ &m);
void bind_easy3d_fileio_translator(pybind11::module_ &m);

//void bind_easy3d_gui_picker(pybind11::module_ &m);
//void bind_easy3d_gui_picker_model(pybind11::module_ &m);
//void bind_easy3d_gui_picker_point_cloud(pybind11::module_ &m);
//void bind_easy3d_gui_picker_surface_mesh(pybind11::module_ &m);

void bind_easy3d_kdtree_kdtree_search_ann(pybind11::module_ &m);
void bind_easy3d_kdtree_kdtree_search_eth(pybind11::module_ &m);
void bind_easy3d_kdtree_kdtree_search_flann(pybind11::module_ &m);
void bind_easy3d_kdtree_kdtree_search_nanoflann(pybind11::module_ &m);

//void bind_easy3d_renderer_constraint(pybind11::module_ &m);
void bind_easy3d_renderer_camera(pybind11::module_ &m);
//void bind_easy3d_renderer_buffer(pybind11::module_ &m);
//void bind_easy3d_renderer_clipping_plane(pybind11::module_ &m);
//void bind_easy3d_renderer_drawable_lines(pybind11::module_ &m);
//void bind_easy3d_renderer_framebuffer_object(pybind11::module_ &m);
//void bind_easy3d_renderer_frustum(pybind11::module_ &m);
//void bind_easy3d_renderer_manipulated_frame(pybind11::module_ &m);
//void bind_easy3d_renderer_opengl_error(pybind11::module_ &m);
//void bind_easy3d_renderer_opengl_timer(pybind11::module_ &m);
//void bind_easy3d_renderer_read_pixel(pybind11::module_ &m);
//void bind_easy3d_renderer_renderer(pybind11::module_ &m);
//void bind_easy3d_renderer_shader_manager(pybind11::module_ &m);
//void bind_easy3d_renderer_shape(pybind11::module_ &m);
//void bind_easy3d_renderer_shape_1(pybind11::module_ &m);
//void bind_easy3d_renderer_soft_shadow(pybind11::module_ &m);
//void bind_easy3d_renderer_texture_manager(pybind11::module_ &m);
//void bind_easy3d_renderer_transform(pybind11::module_ &m);
//void bind_easy3d_renderer_vertex_array_object(pybind11::module_ &m);

void bind_easy3d_util_console_style(pybind11::module_ &m);

void bind_easy3d_util_dialog(pybind11::module_ &m);
void bind_easy3d_util_file_system(pybind11::module_ &m);
void bind_easy3d_util_initializer(pybind11::module_ &m);
void bind_easy3d_util_line_stream(pybind11::module_ &m);
void bind_easy3d_util_logging(pybind11::module_ &m);
void bind_easy3d_util_progress(pybind11::module_ &m);
void bind_easy3d_util_resource(pybind11::module_ &m);
void bind_easy3d_util_setting(pybind11::module_ &m);
void bind_easy3d_util_stop_watch(pybind11::module_ &m);
void bind_easy3d_util_string(pybind11::module_ &m);
void bind_easy3d_util_timer(pybind11::module_ &m);
void bind_easy3d_util_tokenizer(pybind11::module_ &m);
void bind_easy3d_util_version(pybind11::module_ &m);

void bind_easy3d_viewer_viewer(pybind11::module_ &m);
Expand All @@ -127,7 +98,6 @@ void bind_core(pybind11::module_ &m) {
bind_easy3d_core_plane(m);
bind_easy3d_core_property(m);
bind_easy3d_core_random(m);
bind_easy3d_core_signal(m);
bind_easy3d_core_types(m);
bind_easy3d_core_vec(m);

Expand All @@ -141,19 +111,14 @@ void bind_core(pybind11::module_ &m) {
}

void bind_util(pybind11::module_ &m) {
bind_easy3d_util_console_style(m);
bind_easy3d_util_dialog(m);
bind_easy3d_util_file_system(m);
bind_easy3d_util_initializer(m);
bind_easy3d_util_line_stream(m);
bind_easy3d_util_logging(m);
bind_easy3d_util_progress(m);
bind_easy3d_util_resource(m);
bind_easy3d_util_setting(m);
bind_easy3d_util_stop_watch(m);
bind_easy3d_util_string(m);
bind_easy3d_util_timer(m);
bind_easy3d_util_tokenizer(m);
bind_easy3d_util_version(m);
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 2 additions & 3 deletions python/examples/example_Offscreen.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import sys
sys.path.append("../cmake-build-release/")
# sys.path.append("/Users/lnan/Documents/Projects/PyEasy3D/cmake-build-release")

sys.path.append("../../cmake-build-release/lib/python")
import easy3d


# Initialize Easy3D
easy3d.initialize(True) # True to print detailed log

Expand Down
4 changes: 2 additions & 2 deletions python/examples/example_PointCloudNormalEstimtion.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import sys
sys.path.append("../cmake-build-release/")
# sys.path.append("/Users/lnan/Documents/Projects/PyEasy3D/cmake-build-release")
sys.path.append("../../cmake-build-release/lib/python")

import easy3d


# Initialize Easy3D
easy3d.initialize(True) # True to print detailed log

Expand Down
10 changes: 10 additions & 0 deletions python/examples/example_viewer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sys
sys.path.append("../../cmake-build-release/lib/python")


import easy3d

easy3d.initialize()
viewer = easy3d.Viewer("Test")
viewer.add_model(easy3d.directory() + "/data/bunny.ply")
viewer.run()
37 changes: 6 additions & 31 deletions python/examples/experiment.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,19 @@
import sys
sys.path.append("../../cmake-build-release/lib")
sys.path.append("../../cmake-build-release/lib/python")
# sys.path.append("/Users/lnan/Documents/Projects/PyEasy3D/cmake-build-release")

import PyEasy3D
import easy3d

# Initialize Easy3D
PyEasy3D.initialize(True) # True to print detailed log
easy3d.initialize(True) # True to print detailed log

file_name = PyEasy3D.directory() + "/data/bunny.bin"
print("input file name: " + file_name)

stopwatch = PyEasy3D.StopWatch()
stopwatch.start()
file_name = easy3d.directory() + "/data/bunny.ply"

# Load the point cloud from a file
pc = PyEasy3D.PointCloudIO.load(file_name)
if not pc:
raise ValueError("Failed to load the point cloud.")

# Estimate normals for the point cloud
if not PyEasy3D.PointCloudNormals.estimate(pc, 16, False):
raise ValueError("Normal estimation failed.")

# Optional: Reorient normals if needed
if not PyEasy3D.PointCloudNormals.reorient(pc, 16):
raise ValueError("Normal reorientation failed.")
pc = easy3d.SurfaceMeshIO.load(file_name)

print("Done. Time: " + stopwatch.time_string())

# # Visualize the point cloud
# ToDo: python binding for the viewer is not ready
# The viewer crashes when closing it (due to the ownership of pc?)
# Solution: use std::shared_ptr in Viewer::add_model()
viewer = PyEasy3D.Viewer("Easy3D Viewer")
viewer = easy3d.Viewer("Easy3D Viewer")
viewer.set_usage("")
# print(pc.name())
viewer.add_model(pc)
# viewer.add_model(file_name)
viewer.run()

# Save the point cloud into a file
if not PyEasy3D.PointCloudIO.save(file_name + "-result.ply", pc):
raise ValueError("Saving file failed.")

0 comments on commit c706056

Please sign in to comment.