diff --git a/python/bindings/easy3d/core/point_cloud.cpp b/python/bindings/easy3d/core/point_cloud.cpp index dbf514ea..b3d542e5 100644 --- a/python/bindings/easy3d/core/point_cloud.cpp +++ b/python/bindings/easy3d/core/point_cloud.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -103,6 +102,48 @@ void bind_easy3d_core_point_cloud(pybind11::module_& m) } }, "Add multiple points to the PointCloud from a NumPy array with shape (n, 3)"); + cl.def("add_point", (struct easy3d::PointCloud::Vertex (easy3d::PointCloud::*)(const easy3d::vec3 &)) &easy3d::PointCloud::add_vertex, "add a new vertex with position \n\nC++: easy3d::PointCloud::add_vertex(const easy3d::vec3 &) --> struct easy3d::PointCloud::Vertex", pybind11::arg("p")); + + cl.def("add_point", + [](easy3d::PointCloud &pc, pybind11::object point) { + if (pybind11::isinstance(point)) { + // If the input is an easy3d::vec3 + pc.add_vertex(point.cast()); + } else if (pybind11::isinstance(point)) { + // Convert iterable (like list) to NumPy array + auto iterable = point.cast(); + std::vector values; + for (auto item : iterable) { + values.push_back(item.cast()); + } + + if (values.size() != 3) { + throw std::runtime_error("Iterable must contain exactly 3 elements."); + } + + easy3d::vec3 v(values[0], values[1], values[2]); + pc.add_vertex(v); + } else if (pybind11::isinstance>(point)) { + // If the input is a NumPy array + pybind11::array_t array = point.cast>(); + + // Check array shape + if (array.ndim() != 1 || array.shape(0) != 3) { + throw std::runtime_error("NumPy array must be a 1D array with 3 elements."); + } + + auto buf = array.unchecked<1>(); // Access data buffer + easy3d::vec3 v(buf(0), buf(1), buf(2)); + pc.add_vertex(v); + } else { + throw std::runtime_error( + "Input must be of type easy3d::vec3, a NumPy array with 3 elements, or a list/iterable with 3 elements." + ); + } + }, + "Adds a single point to the point cloud. Input can be easy3d::vec3, a NumPy array, or a list with 3 elements.", + pybind11::arg("point")); + // Retrieve all points as a NumPy array cl.def("to_numpy", [](const easy3d::PointCloud &pc) { // Create a NumPy array with shape (n_points, 3) @@ -124,7 +165,6 @@ void bind_easy3d_core_point_cloud(pybind11::module_& m) cl.def("__iadd__", (class easy3d::PointCloud & (easy3d::PointCloud::*)(const class easy3d::PointCloud &)) &easy3d::PointCloud::operator+=, "Merges another point cloud into the current one.\n Shifts the indices of vertices of the other point cloud by `number_of_vertices() + number_of_removed_vertices()`.\n Copies entries of all property maps which have the same name in both point clouds. That is, property maps which\n are only in `other` are ignored.\n Also copies elements which are marked as removed, and concatenates the freelists of both point clouds.\n\nC++: easy3d::PointCloud::operator+=(const class easy3d::PointCloud &) --> class easy3d::PointCloud &", pybind11::return_value_policy::automatic, pybind11::arg("other")); cl.def("join", (class easy3d::PointCloud & (easy3d::PointCloud::*)(const class easy3d::PointCloud &)) &easy3d::PointCloud::join, "Merges another point cloud into the current one.\n Shifts the indices of vertices of the other point cloud by `number_of_vertices() + number_of_removed_vertices()`.\n Copies entries of all property maps which have the same name in both point cloud. That is, property maps which\n are only in `other` are ignored.\n Also copies elements which are marked as removed, and concatenates the freelists of both point cloud.\n\nC++: easy3d::PointCloud::join(const class easy3d::PointCloud &) --> class easy3d::PointCloud &", pybind11::return_value_policy::automatic, pybind11::arg("other")); cl.def("assign", (class easy3d::PointCloud & (easy3d::PointCloud::*)(const class easy3d::PointCloud &)) &easy3d::PointCloud::assign, "assign to does not copy custom properties.\n\nC++: easy3d::PointCloud::assign(const class easy3d::PointCloud &) --> class easy3d::PointCloud &", pybind11::return_value_policy::automatic, pybind11::arg("rhs")); - cl.def("add_vertex", (struct easy3d::PointCloud::Vertex (easy3d::PointCloud::*)(const easy3d::vec3 &)) &easy3d::PointCloud::add_vertex, "add a new vertex with position \n\nC++: easy3d::PointCloud::add_vertex(const easy3d::vec3 &) --> struct easy3d::PointCloud::Vertex", pybind11::arg("p")); cl.def("vertices_size", (unsigned int (easy3d::PointCloud::*)() const) &easy3d::PointCloud::vertices_size, "returns number of (deleted and valid) vertices in the cloud\n\nC++: easy3d::PointCloud::vertices_size() const --> unsigned int"); cl.def("n_vertices", (unsigned int (easy3d::PointCloud::*)() const) &easy3d::PointCloud::n_vertices, "returns number of vertices in the cloud\n\nC++: easy3d::PointCloud::n_vertices() const --> unsigned int"); cl.def("clear", (void (easy3d::PointCloud::*)()) &easy3d::PointCloud::clear, "clear cloud: remove all vertices\n\nC++: easy3d::PointCloud::clear() --> void"); @@ -150,7 +190,10 @@ void bind_easy3d_core_point_cloud(pybind11::module_& m) cl.def("points", (class std::vector & (easy3d::PointCloud::*)()) &easy3d::PointCloud::points, "vector of vertex positions\n\nC++: easy3d::PointCloud::points() --> class std::vector &", pybind11::return_value_policy::automatic); cl.def("points", (const class std::vector & (easy3d::PointCloud::*)() const) &easy3d::PointCloud::points, "vector of vertex positions\n\nC++: easy3d::PointCloud::points() --> class std::vector &", pybind11::return_value_policy::automatic); - { // easy3d::PointCloud::BaseHandle file:easy3d/core/point_cloud.h line:52 + cl.def("name", [](easy3d::PointCloud& self) { return self.name(); }, pybind11::return_value_policy::copy, "Get the name of the point cloud."); + cl.def("set_name", [](easy3d::PointCloud& self, const std::string& name) { self.set_name(name); }, "Set the name of the point cloud."); + + { // easy3d::PointCloud::BaseHandle file:easy3d/core/point_cloud.h line:52 auto & enclosing_class = cl; pybind11::class_> cl(enclosing_class, "BaseHandle", "Base class for topology types (internally it is basically an index)\n \n\n Vertex"); cl.def( pybind11::init( [](){ return new easy3d::PointCloud::BaseHandle(); } ), "doc" ); diff --git a/python/bindings/easy3d/core/vec.cpp b/python/bindings/easy3d/core/vec.cpp index c5455afe..f32533ff 100644 --- a/python/bindings/easy3d/core/vec.cpp +++ b/python/bindings/easy3d/core/vec.cpp @@ -25,7 +25,12 @@ void bind_easy3d_core_vec(pybind11::module_& m) cl.def( pybind11::init(), pybind11::arg("s") ); cl.def( pybind11::init( [](easy3d::vec2 const &o){ return new easy3d::vec2(o); } ) ); - cl.def("length2", (float (easy3d::vec2::*)() const) &easy3d::vec2::length2, "C++: easy3d::vec2::length2() const --> float"); + + cl.def("to_numpy", [](const easy3d::vec2 &v) { + return pybind11::array_t({2}, {sizeof(float)}, &v.x); + }, "Converts the vector to a NumPy array."); + + cl.def("length2", (float (easy3d::vec2::*)() const) &easy3d::vec2::length2, "C++: easy3d::vec2::length2() const --> float"); cl.def("length", (float (easy3d::vec2::*)() const) &easy3d::vec2::length, "C++: easy3d::vec2::length() const --> float"); cl.def("norm", (float (easy3d::vec2::*)() const) &easy3d::vec2::norm, "C++: easy3d::vec2::norm() const --> float"); cl.def("distance2", (float (easy3d::vec2::*)(const easy3d::vec2 &) const) &easy3d::vec2::distance2, "C++: easy3d::vec2::distance2(const easy3d::vec2 &) const --> float", pybind11::arg("rhs")); @@ -76,6 +81,11 @@ void bind_easy3d_core_vec(pybind11::module_& m) cl.def( pybind11::init(), pybind11::arg("s") ); cl.def( pybind11::init( [](easy3d::vec3 const &o){ return new easy3d::vec3(o); } ) ); + + cl.def("to_numpy", [](const easy3d::vec3 &v) { + return pybind11::array_t({3}, {sizeof(float)}, &v.x); + }, "Converts the vector to a NumPy array."); + cl.def("__imul__", (easy3d::vec3 & (easy3d::vec3::*)(float)) &easy3d::vec3::operator*=, "C++: easy3d::vec3::operator*=(float) --> easy3d::vec3 &", pybind11::return_value_policy::automatic, pybind11::arg("s")); cl.def("__mul__", (easy3d::vec3 (easy3d::vec3::*)(float) const) &easy3d::vec3::operator*, "C++: easy3d::vec3::operator*(float) const --> easy3d::vec3", pybind11::arg("s")); cl.def("length2", (float (easy3d::vec3::*)() const) &easy3d::vec3::length2, "C++: easy3d::vec3::length2() const --> float"); @@ -131,6 +141,11 @@ void bind_easy3d_core_vec(pybind11::module_& m) cl.def( pybind11::init(), pybind11::arg("s") ); cl.def( pybind11::init( [](easy3d::vec4 const &o){ return new easy3d::vec4(o); } ) ); + + cl.def("to_numpy", [](const easy3d::vec4 &v) { + return pybind11::array_t({4}, {sizeof(float)}, &v.x); + }, "Converts the vector to a NumPy array."); + cl.def("length2", (float (easy3d::vec4::*)() const) &easy3d::vec4::length2, "C++: easy3d::vec4::length2() const --> float"); cl.def("length", (float (easy3d::vec4::*)() const) &easy3d::vec4::length, "C++: easy3d::vec4::length() const --> float"); cl.def("norm", (float (easy3d::vec4::*)() const) &easy3d::vec4::norm, "C++: easy3d::vec4::norm() const --> float"); diff --git a/python/examples/example_001-data_types.py b/python/examples/example_001-data_types.py new file mode 100644 index 00000000..c5bd166c --- /dev/null +++ b/python/examples/example_001-data_types.py @@ -0,0 +1,72 @@ +# ------------------------------------------------------------------------------- +# Example: Demonstrating vec2, vec3, and vec4 +# ------------------------------------------------------------------------------- +# This script demonstrates how to use the Easy3D vector classes: +# - `vec2`: Represents 2D points +# - `vec3`: Represents 3D points +# - `vec4`: Represents 4D points +# The script shows how to create these objects and convert them to NumPy arrays +# for easy manipulation in Python. +# ------------------------------------------------------------------------------- + +# ------------------------------------------------------------------------------- +# Adding Easy3D Python Bindings to the System Path +# ------------------------------------------------------------------------------- +# This is required if the bindings are not installed via `pip` but are located in +# a local build directory. To install the bindings, use the following command: +# "pip install YOUR_BUILD_DIRECTORY/lib/python/setup.py" +# ------------------------------------------------------------------------------- +import sys +sys.path.append("../../cmake-build-debug/lib/python") + +# ------------------------------------------------------------------------------- +# Importing Necessary Libraries +# ------------------------------------------------------------------------------- +import easy3d # Easy3D library for 3D visualization and processing +import numpy as np # NumPy library (used for handling data) + +# ------------------------------------------------------------------------------- +# Initializing Easy3D +# ------------------------------------------------------------------------------- +# The `easy3d.initialize(True)` function initializes the Easy3D library. +# The `True` parameter enables detailed logging, which is useful for debugging. +easy3d.initialize(True) + +# ------------------------------------------------------------------------------- +# Creating and Converting a vec2 Object +# ------------------------------------------------------------------------------- +# A `vec2` object represents a 2D point. We create a `vec2` object using two values. +# Optionally, the object can also be created using a list: `vec2([x, y])`. +v2 = easy3d.vec2(2.0, 2.0) # or v2 = easy3d.vec2([2.0, 2.0]) + +# The `to_numpy()` method converts the `vec2` object into a NumPy array. +np_v2 = v2.to_numpy() # Convert to NumPy array + +# Output the NumPy array representation of the `vec2` object. +print("vec2 as NumPy array:", np_v2) # Output: [2. 2.] + +# ------------------------------------------------------------------------------- +# Creating and Converting a vec3 Object +# ------------------------------------------------------------------------------- +# A `vec3` object represents a 3D point. We create a `vec3` object using three values. +# Optionally, the object can also be created using a list: `vec3([x, y, z])`. +v3 = easy3d.vec3(3.0, 3.0, 3.0) # or v3 = easy3d.vec3([3.0, 3.0, 3.0]) + +# The `to_numpy()` method converts the `vec3` object into a NumPy array. +np_v3 = v3.to_numpy() # Convert to NumPy array + +# Output the NumPy array representation of the `vec3` object. +print("vec3 as NumPy array:", np_v3) # Output: [3. 3. 3.] + +# ------------------------------------------------------------------------------- +# Creating and Converting a vec4 Object +# ------------------------------------------------------------------------------- +# A `vec4` object represents a 4D point. We create a `vec4` object using four values. +# Optionally, the object can also be created using a list: `vec4([x, y, z, w])`. +v4 = easy3d.vec4(4.0, 4.0, 4.0, 4.0) # or v4 = easy3d.vec4([4.0, 4.0, 4.0, 4.0]) + +# The `to_numpy()` method converts the `vec4` object into a NumPy array. +np_v4 = v4.to_numpy() # Convert to NumPy array + +# Output the NumPy array representation of the `vec4` object. +print("vec4 as NumPy array:", np_v4) # Output: [4. 4. 4. 4.] diff --git a/python/examples/example_001-point_cloud.py b/python/examples/example_001-point_cloud.py new file mode 100644 index 00000000..09191266 --- /dev/null +++ b/python/examples/example_001-point_cloud.py @@ -0,0 +1,81 @@ +# ------------------------------------------------------------------------------- +# Example: Working with the PointCloud class +# ------------------------------------------------------------------------------- +# This script demonstrates how to use the Easy3D `PointCloud` class: +# - Initialize a `PointCloud` object with a NumPy array of points. +# - Add multiple points at once using a NumPy array. +# - Add individual points using various formats (vec3, lists, NumPy arrays). +# - Export the entire point cloud back to a NumPy array. +# ------------------------------------------------------------------------------- + +# ------------------------------------------------------------------------------- +# Adding Easy3D Python Bindings to the System Path +# ------------------------------------------------------------------------------- +# This is required if the bindings are not installed via `pip` but are located in +# a local build directory. To install the bindings, use the following command: +# "pip install YOUR_BUILD_DIRECTORY/lib/python/setup.py" +# ------------------------------------------------------------------------------- +import sys +sys.path.append("../../cmake-build-debug/lib/python") + +# ------------------------------------------------------------------------------- +# Importing Necessary Libraries +# ------------------------------------------------------------------------------- +import easy3d # Easy3D library for 3D visualization and processing +import numpy as np # NumPy library (used for handling data) + +# ------------------------------------------------------------------------------- +# Initializing Easy3D +# ------------------------------------------------------------------------------- +# The `easy3d.initialize(True)` function initializes the Easy3D library. +# The `True` parameter enables detailed logging, which is useful for debugging. +easy3d.initialize(True) + +# ------------------------------------------------------------------------------- +# Creating a PointCloud Object and Initializing with Points +# ------------------------------------------------------------------------------- +# Create a NumPy array of initial points (each point is represented by [x, y, z]). +initial_points = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) # Initial points + +# Initialize a `PointCloud` object with the array of points. +pc = easy3d.PointCloud(initial_points) + +# Set a name for the point cloud. This helps with identification in complex scenes. +pc.set_name("Small Point Cloud") + +# Output the name of the point cloud. +print(f"Point cloud name: {pc.name()}") # Output: Small Point Cloud + +# ------------------------------------------------------------------------------- +# Adding Multiple Points to the PointCloud +# ------------------------------------------------------------------------------- +# Create a NumPy array of additional points to add to the point cloud. +more_points = np.array([[7.0, 8.0, 9.0], [10.0, 11.0, 12.0]]) # Additional points + +# Add the new points to the point cloud using `add_points`. +pc.add_points(more_points) + +# ------------------------------------------------------------------------------- +# Adding Individual Points Using Various Formats +# ------------------------------------------------------------------------------- +# Add individual points using the `vec3` format. +v3 = easy3d.vec3(3.0, 3.0, 3.0) # Creating a vec3 object +pc.add_point(v3) # Add point using vec3 format +pc.add_point(easy3d.vec3(1, 8, 8)) # Another point using vec3 + +# Add individual points using Python lists. +pc.add_point([20, 20, 20]) # Add point using list format +pc.add_point([5, 5, 5]) # Another point using list format + +# Add individual points using a NumPy array. +point_np = np.array([4.0, 5.0, 6.0], dtype=np.float32) # Point in NumPy array format +pc.add_point(point_np) # Add point using NumPy array format + +# ------------------------------------------------------------------------------- +# Exporting the PointCloud Data to a NumPy Array +# ------------------------------------------------------------------------------- +# Convert the point cloud data back to a NumPy array using the `to_numpy()` method. +points_np = pc.to_numpy() + +# Output the point cloud data in NumPy array format. +print("Point cloud data:\n", points_np) diff --git a/python/examples/example_101-viewer.py b/python/examples/example_101-viewer.py new file mode 100644 index 00000000..8c48aeed --- /dev/null +++ b/python/examples/example_101-viewer.py @@ -0,0 +1,77 @@ +# ------------------------------------------------------------------------------- +# Example: The basic Easy3D viewer +# ------------------------------------------------------------------------------- +# This script demonstrates how to use the Easy3D `Viewer` class to: +# 1. Create a 3D viewer with a custom title. +# 2. Load and visualize a 3D mesh model (`SurfaceMesh`) from a file. +# 3. Load and visualize a 3D point cloud model (`PointCloud`) from a file. +# 4. Run the viewer to interact with the models (e.g., rotate, zoom, pan). + + +# ------------------------------------------------------------------------------- +# Adding Easy3D Python Bindings to the System Path +# ------------------------------------------------------------------------------- +# This is required if the bindings are not installed via `pip` but are located in +# a local build directory. To install the bindings, use the following command: +# "pip install YOUR_BUILD_DIRECTORY/lib/python/setup.py" +# ------------------------------------------------------------------------------- +import sys +sys.path.append("../../cmake-build-debug/lib/python") + +# Importing necessary libraries +import easy3d # Easy3D library for 3D visualization and processing +import numpy as np # NumPy library (used for handling data if needed) + +# ------------------------------------------------------------------------------- +# Initializing Easy3D +# ------------------------------------------------------------------------------- +# The `easy3d.initialize(True)` function initializes the Easy3D library. +# The `True` parameter enables detailed logging, which is useful for debugging. +easy3d.initialize(True) + +# ------------------------------------------------------------------------------- +# Creating a Viewer +# ------------------------------------------------------------------------------- +# The `Viewer` class provides a GUI window for visualizing 3D models. +# Here, we create a viewer instance with a custom title, "Easy3D Viewer". +viewer = easy3d.Viewer("Easy3D Viewer") + +# ------------------------------------------------------------------------------- +# Loading and Adding a 3D Mesh Model +# ------------------------------------------------------------------------------- +# Load a 3D mesh file (e.g., Stanford Bunny in .ply format). +# The `easy3d.directory()` function retrieves the root directory of Easy3D's +# resources. The model is located in the `data` subdirectory. +mesh_file = easy3d.directory() + "/data/bunny.ply" + +# Add the mesh model to the viewer. +# This can be done directly using the file path, as shown below: +viewer.add_model(mesh_file) + +# Alternatively, you can load the model as a `SurfaceMesh` object and add it: +# model = easy3d.SurfaceMeshIO.load(mesh_file) +# viewer.add_model(model) + +# ------------------------------------------------------------------------------- +# Loading and Adding a 3D Point Cloud Model +# ------------------------------------------------------------------------------- +# Load a 3D point cloud file (e.g., a polyhedron in .bin format). +pointcloud_file = easy3d.directory() + "/data/polyhedron.bin" + +# The `PointCloudIO.load()` function reads the point cloud data from the file. +pointcloud = easy3d.PointCloudIO.load(pointcloud_file) + +# Add the point cloud model to the viewer. +# You can add the point cloud object directly as shown below: +viewer.add_model(pointcloud) + +# Alternatively, the point cloud file path can also be added directly: +# viewer.add_model(pointcloud_file) + +# ------------------------------------------------------------------------------- +# Running the Viewer +# ------------------------------------------------------------------------------- +# The `viewer.run()` function launches the viewer window, where users can: +# - Interact with the 3D models (e.g., rotate, zoom, pan). +# - Explore the structure and details of the loaded models. +viewer.run() diff --git a/python/examples/example_DataTypes.py b/python/examples/example_DataTypes.py deleted file mode 100644 index d027777a..00000000 --- a/python/examples/example_DataTypes.py +++ /dev/null @@ -1,23 +0,0 @@ -import sys -sys.path.append("../../cmake-build-release/lib/python") -import easy3d -import numpy as np - - -# Initialize Easy3D -easy3d.initialize(True) # True to print detailed log - -p = easy3d.vec3(1, 2, 3) -print(p.x, p.y, p.z) - -# Initialize PointCloud with points -points = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) -point_cloud = easy3d.PointCloud(points) - -# Add more points -more_points = np.array([[7.0, 8.0, 9.0], [10.0, 11.0, 12.0]]) -point_cloud.add_points(more_points) - -# Export points to NumPy -exported_points = point_cloud.to_numpy() -print("Exported Points:", exported_points) \ No newline at end of file diff --git a/python/examples/example_viewer.py b/python/examples/example_viewer.py deleted file mode 100644 index f142ff8b..00000000 --- a/python/examples/example_viewer.py +++ /dev/null @@ -1,10 +0,0 @@ -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() \ No newline at end of file diff --git a/python/examples/experiment.py b/python/examples/experiment.py deleted file mode 100644 index ef777303..00000000 --- a/python/examples/experiment.py +++ /dev/null @@ -1,10 +0,0 @@ -import sys -# sys.path.append("../../cmake-build-release/lib/python") -sys.path.append("/Users/lnan/Documents/Projects/PyEasy3D/cmake-build-release") - -import easy3d - -easy3d.initialize() -viewer = easy3d.Viewer("Test") -viewer.add_model(easy3d.directory() + "/data/bunny.ply") -viewer.run() \ No newline at end of file diff --git a/python/examples/tmp.py b/python/examples/tmp.py new file mode 100644 index 00000000..8c48aeed --- /dev/null +++ b/python/examples/tmp.py @@ -0,0 +1,77 @@ +# ------------------------------------------------------------------------------- +# Example: The basic Easy3D viewer +# ------------------------------------------------------------------------------- +# This script demonstrates how to use the Easy3D `Viewer` class to: +# 1. Create a 3D viewer with a custom title. +# 2. Load and visualize a 3D mesh model (`SurfaceMesh`) from a file. +# 3. Load and visualize a 3D point cloud model (`PointCloud`) from a file. +# 4. Run the viewer to interact with the models (e.g., rotate, zoom, pan). + + +# ------------------------------------------------------------------------------- +# Adding Easy3D Python Bindings to the System Path +# ------------------------------------------------------------------------------- +# This is required if the bindings are not installed via `pip` but are located in +# a local build directory. To install the bindings, use the following command: +# "pip install YOUR_BUILD_DIRECTORY/lib/python/setup.py" +# ------------------------------------------------------------------------------- +import sys +sys.path.append("../../cmake-build-debug/lib/python") + +# Importing necessary libraries +import easy3d # Easy3D library for 3D visualization and processing +import numpy as np # NumPy library (used for handling data if needed) + +# ------------------------------------------------------------------------------- +# Initializing Easy3D +# ------------------------------------------------------------------------------- +# The `easy3d.initialize(True)` function initializes the Easy3D library. +# The `True` parameter enables detailed logging, which is useful for debugging. +easy3d.initialize(True) + +# ------------------------------------------------------------------------------- +# Creating a Viewer +# ------------------------------------------------------------------------------- +# The `Viewer` class provides a GUI window for visualizing 3D models. +# Here, we create a viewer instance with a custom title, "Easy3D Viewer". +viewer = easy3d.Viewer("Easy3D Viewer") + +# ------------------------------------------------------------------------------- +# Loading and Adding a 3D Mesh Model +# ------------------------------------------------------------------------------- +# Load a 3D mesh file (e.g., Stanford Bunny in .ply format). +# The `easy3d.directory()` function retrieves the root directory of Easy3D's +# resources. The model is located in the `data` subdirectory. +mesh_file = easy3d.directory() + "/data/bunny.ply" + +# Add the mesh model to the viewer. +# This can be done directly using the file path, as shown below: +viewer.add_model(mesh_file) + +# Alternatively, you can load the model as a `SurfaceMesh` object and add it: +# model = easy3d.SurfaceMeshIO.load(mesh_file) +# viewer.add_model(model) + +# ------------------------------------------------------------------------------- +# Loading and Adding a 3D Point Cloud Model +# ------------------------------------------------------------------------------- +# Load a 3D point cloud file (e.g., a polyhedron in .bin format). +pointcloud_file = easy3d.directory() + "/data/polyhedron.bin" + +# The `PointCloudIO.load()` function reads the point cloud data from the file. +pointcloud = easy3d.PointCloudIO.load(pointcloud_file) + +# Add the point cloud model to the viewer. +# You can add the point cloud object directly as shown below: +viewer.add_model(pointcloud) + +# Alternatively, the point cloud file path can also be added directly: +# viewer.add_model(pointcloud_file) + +# ------------------------------------------------------------------------------- +# Running the Viewer +# ------------------------------------------------------------------------------- +# The `viewer.run()` function launches the viewer window, where users can: +# - Interact with the 3D models (e.g., rotate, zoom, pan). +# - Explore the structure and details of the loaded models. +viewer.run()