diff --git a/python/py_igl_viewer.cpp b/python/py_igl_viewer.cpp index d7e560e30..15f5c300b 100644 --- a/python/py_igl_viewer.cpp +++ b/python/py_igl_viewer.cpp @@ -4,6 +4,7 @@ #include "python.h" #include #include +#include void python_export_igl_viewer(py::module &m) { @@ -13,18 +14,106 @@ void python_export_igl_viewer(py::module &m) /////////////////////// DATA - py::class_ viewerdata_class(me, "ViewerData"); +py::class_ viewerdata_class(me, "ViewerData"); + +py::enum_(viewerdata_class, "DirtyFlags") + .value("DIRTY_NONE", igl::viewer::ViewerData::DIRTY_NONE) + .value("DIRTY_POSITION", igl::viewer::ViewerData::DIRTY_POSITION) + .value("DIRTY_UV", igl::viewer::ViewerData::DIRTY_UV) + .value("DIRTY_NORMAL", igl::viewer::ViewerData::DIRTY_NORMAL) + .value("DIRTY_AMBIENT", igl::viewer::ViewerData::DIRTY_AMBIENT) + .value("DIRTY_DIFFUSE", igl::viewer::ViewerData::DIRTY_DIFFUSE) + .value("DIRTY_SPECULAR", igl::viewer::ViewerData::DIRTY_SPECULAR) + .value("DIRTY_TEXTURE", igl::viewer::ViewerData::DIRTY_TEXTURE) + .value("DIRTY_FACE", igl::viewer::ViewerData::DIRTY_FACE) + .value("DIRTY_MESH", igl::viewer::ViewerData::DIRTY_MESH) + .value("DIRTY_OVERLAY_LINES", igl::viewer::ViewerData::DIRTY_OVERLAY_LINES) + .value("DIRTY_OVERLAY_POINTS", igl::viewer::ViewerData::DIRTY_OVERLAY_POINTS) + .value("DIRTY_ALL", igl::viewer::ViewerData::DIRTY_ALL) + .export_values(); + + viewerdata_class .def(py::init<>()) .def("set_mesh", &igl::viewer::ViewerData::set_mesh) .def("set_colors", &igl::viewer::ViewerData::set_colors) .def("clear", &igl::viewer::ViewerData::clear) - ; + .def("set_face_based", &igl::viewer::ViewerData::set_face_based) + .def("set_vertices", &igl::viewer::ViewerData::set_vertices) + .def("set_normals", &igl::viewer::ViewerData::set_normals) + + .def("set_uv", + (void (igl::viewer::ViewerData::*) (const Eigen::MatrixXd &)) &igl::viewer::ViewerData::set_uv + ) + + .def("set_uv", + (void (igl::viewer::ViewerData::*) (const Eigen::MatrixXd &, const Eigen::MatrixXi&)) &igl::viewer::ViewerData::set_uv + ) + + .def("set_texture", &igl::viewer::ViewerData::set_texture) + .def("set_points", &igl::viewer::ViewerData::set_points) + .def("add_points", &igl::viewer::ViewerData::add_points) + .def("set_edges", &igl::viewer::ViewerData::set_edges) + .def("add_edges", &igl::viewer::ViewerData::add_edges) + + .def("add_label", [] (igl::viewer::ViewerData& data, const Eigen::MatrixXd& P, const std::string& str) + { + assert_is_VectorXd("P",P); + data.add_label(P,str); + }) + + .def("compute_normals", &igl::viewer::ViewerData::compute_normals) + + .def("uniform_colors", [] (igl::viewer::ViewerData& data, const Eigen::MatrixXd& ambient, const Eigen::MatrixXd& diffuse, const Eigen::MatrixXd& specular) + { + assert_is_Vector3d("ambient",ambient); + assert_is_Vector3d("diffuse",diffuse); + assert_is_Vector3d("specular",specular); + data.uniform_colors(ambient,diffuse, specular); + }) + + .def("grid_texture", &igl::viewer::ViewerData::grid_texture) + + .def_readwrite("V", &igl::viewer::ViewerData::V) + .def_readwrite("F", &igl::viewer::ViewerData::F) + + .def_readwrite("F_normals", &igl::viewer::ViewerData::F_normals) + .def_readwrite("F_material_ambient", &igl::viewer::ViewerData::F_material_ambient) + .def_readwrite("F_material_diffuse", &igl::viewer::ViewerData::F_material_diffuse) + .def_readwrite("F_material_specular", &igl::viewer::ViewerData::F_material_specular) + + .def_readwrite("V_normals", &igl::viewer::ViewerData::V_normals) + .def_readwrite("V_material_ambient", &igl::viewer::ViewerData::V_material_ambient) + .def_readwrite("V_material_diffuse", &igl::viewer::ViewerData::V_material_diffuse) + .def_readwrite("V_material_specular", &igl::viewer::ViewerData::V_material_specular) + + .def_readwrite("V_uv", &igl::viewer::ViewerData::V_uv) + .def_readwrite("F_uv", &igl::viewer::ViewerData::F_uv) + + .def_readwrite("texture_R", &igl::viewer::ViewerData::texture_R) + .def_readwrite("texture_G", &igl::viewer::ViewerData::texture_G) + .def_readwrite("texture_B", &igl::viewer::ViewerData::texture_B) + + .def_readwrite("lines", &igl::viewer::ViewerData::lines) + .def_readwrite("points", &igl::viewer::ViewerData::points) + .def_readwrite("labels_positions", &igl::viewer::ViewerData::labels_positions) + .def_readwrite("labels_strings", &igl::viewer::ViewerData::labels_strings) + .def_readwrite("dirty", &igl::viewer::ViewerData::dirty) + .def_readwrite("face_based", &igl::viewer::ViewerData::face_based) + + ; //////////////////////// CORE - py::class_ viewercore_class(me, "ViewerCore"); +py::class_ viewercore_class(me, "ViewerCore"); + + py::enum_(viewercore_class, "RotationType") + .value("ROTATION_TYPE_TRACKBALL", igl::viewer::ViewerCore::ROTATION_TYPE_TRACKBALL) + .value("ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP", igl::viewer::ViewerCore::ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP) + .value("NUM_ROTATION_TYPES", igl::viewer::ViewerCore::NUM_ROTATION_TYPES) + .export_values(); + viewercore_class .def(py::init<>()) //.def("align_camera_center", [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& V, const Eigen::MatrixXi& F){return core.align_camera_center(V,F);}) @@ -47,88 +136,181 @@ void python_export_igl_viewer(py::module &m) .def_readwrite("shininess",&igl::viewer::ViewerCore::shininess) .def_property("background_color", - [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.background_color);}, + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.background_color.cast());}, [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) { assert_is_Vector3d("background_color",v); - core.background_color = Vector3f(v.cast()); + core.background_color = Eigen::Vector3f(v.cast()); }) - // // Colors - // Eigen::Vector3f background_color; - // Eigen::Vector3f line_color; - // - // // Lighting - // Eigen::Vector3f light_position; - // float lighting_factor; - // - // // Trackball angle (quaternion) - // enum RotationType - // { - // ROTATION_TYPE_TRACKBALL = 0, - // ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP = 1, - // NUM_ROTATION_TYPES = 2 - // } rotation_type; - // Eigen::Quaternionf trackball_angle; - // - // // Model viewing parameters - // float model_zoom; - // Eigen::Vector3f model_translation; - // - // // Model viewing paramters (uv coordinates) - // float model_zoom_uv; - // Eigen::Vector3f model_translation_uv; - // - // // Camera parameters - // float camera_zoom; - // bool orthographic; - // Eigen::Vector3f camera_eye; - // Eigen::Vector3f camera_up; - // Eigen::Vector3f camera_center; - // float camera_view_angle; - // float camera_dnear; - // float camera_dfar; - // - // // Visualization options - // bool show_overlay; - // bool show_overlay_depth; - // bool show_texture; - // bool show_faces; - // bool show_lines; - // bool show_vertid; - // bool show_faceid; - // bool invert_normals; - // bool depth_test; - // - // // Point size / line width - // float point_size; - // float line_width; - // - // // Animation - // bool is_animating; - // double animation_max_fps; - // - // // Caches the two-norm between the min/max point of the bounding box - // float object_scale; - // - // // Viewport size - // Eigen::Vector4f viewport; - // - // // Save the OpenGL transformation matrices used for the previous rendering pass - // Eigen::Matrix4f view; - // Eigen::Matrix4f model; - // Eigen::Matrix4f proj; + .def_property("line_color", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.line_color.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector3d("line_color",v); + core.line_color = Eigen::Vector3f(v.cast()); + }) - /// + .def_property("light_position", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.light_position.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector3d("light_position",v); + core.light_position = Eigen::Vector3f(v.cast()); + }) + + .def_readwrite("lighting_factor",&igl::viewer::ViewerCore::lighting_factor) + + .def_readwrite("model_zoom",&igl::viewer::ViewerCore::model_zoom) + + .def_property("model_translation", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.model_translation.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector3d("model_translation",v); + core.model_translation = Eigen::Vector3f(v.cast()); + }) + + .def_readwrite("model_zoom_uv",&igl::viewer::ViewerCore::model_zoom_uv) + + .def_property("model_translation_uv", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.model_translation_uv.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector3d("model_translation_uv",v); + core.model_translation_uv = Eigen::Vector3f(v.cast()); + }) + + .def_readwrite("camera_zoom",&igl::viewer::ViewerCore::camera_zoom) + .def_readwrite("orthographic",&igl::viewer::ViewerCore::orthographic) + + .def_property("camera_eye", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.camera_eye.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector3d("camera_eye",v); + core.camera_eye = Eigen::Vector3f(v.cast()); + }) + + .def_property("camera_up", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.camera_up.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector3d("camera_up",v); + core.camera_up = Eigen::Vector3f(v.cast()); + }) + + .def_property("camera_center", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.camera_center.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector3d("camera_center",v); + core.camera_center = Eigen::Vector3f(v.cast()); + }) + + .def_readwrite("camera_view_angle",&igl::viewer::ViewerCore::camera_view_angle) + + .def_readwrite("camera_dnear",&igl::viewer::ViewerCore::camera_dnear) + .def_readwrite("camera_dfar",&igl::viewer::ViewerCore::camera_dfar) + + .def_readwrite("show_overlay",&igl::viewer::ViewerCore::show_overlay) + .def_readwrite("show_overlay_depth",&igl::viewer::ViewerCore::show_overlay_depth) + .def_readwrite("show_texture",&igl::viewer::ViewerCore::show_texture) + .def_readwrite("show_faces",&igl::viewer::ViewerCore::show_faces) + + .def_readwrite("show_lines",&igl::viewer::ViewerCore::show_lines) + .def_readwrite("show_vertid",&igl::viewer::ViewerCore::show_vertid) + .def_readwrite("show_faceid",&igl::viewer::ViewerCore::show_faceid) + .def_readwrite("invert_normals",&igl::viewer::ViewerCore::invert_normals) + .def_readwrite("depth_test",&igl::viewer::ViewerCore::depth_test) + + .def_readwrite("point_size",&igl::viewer::ViewerCore::point_size) + .def_readwrite("line_width",&igl::viewer::ViewerCore::line_width) + + .def_readwrite("is_animating",&igl::viewer::ViewerCore::is_animating) + .def_readwrite("animation_max_fps",&igl::viewer::ViewerCore::animation_max_fps) + + .def_readwrite("object_scale",&igl::viewer::ViewerCore::object_scale) + + .def_property("viewport", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.viewport.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Vector4d("viewport",v); + core.viewport = Eigen::Vector4f(v.cast()); + }) + + .def_property("view", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.view.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Matrix4d("view",v); + core.view = Eigen::Matrix4f(v.cast()); + }) + + .def_property("model", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.model.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Matrix4d("model",v); + core.model = Eigen::Matrix4f(v.cast()); + }) + + .def_property("proj", + [](const igl::viewer::ViewerCore& core) {return Eigen::MatrixXd(core.proj.cast());}, + [](igl::viewer::ViewerCore& core, const Eigen::MatrixXd& v) + { + assert_is_Matrix4d("proj",v); + core.proj = Eigen::Matrix4f(v.cast()); + }) + + .def_readwrite("rotation_type",&igl::viewer::ViewerCore::rotation_type) + + // TODO: wrap this! + // Eigen::Quaternionf trackball_angle; ; ///////////////////////// VIEWER - py::class_(me, "Viewer") +// UI Enumerations + py::class_ viewer_class(me, "Viewer"); + + py::enum_(viewer_class, "MouseButton") + .value("Left", igl::viewer::Viewer::MouseButton::Left) + .value("Middle", igl::viewer::Viewer::MouseButton::Middle) + .value("Right", igl::viewer::Viewer::MouseButton::Right) + .export_values(); + + viewercore_class .def(py::init<>()) .def_readwrite("data", &igl::viewer::Viewer::data) .def_readwrite("core", &igl::viewer::Viewer::core) .def("launch", &igl::viewer::Viewer::launch, py::arg("resizable") = true, py::arg("fullscreen") = false) + .def("init", &igl::viewer::Viewer::init) + + // Scene IO + .def("load_scene", [](igl::viewer::Viewer& viewer) + { + viewer.load_scene(); + }) + + .def("load_scene", [](igl::viewer::Viewer& viewer, std::string str) + { + viewer.load_scene(str); + }) + + .def("save_scene", &igl::viewer::Viewer::save_scene) + + // Draw everything + .def("draw", &igl::viewer::Viewer::draw) + + // OpenGL context resize + .def("resize", &igl::viewer::Viewer::resize) + + // Helper functions + .def("snap_to_canonical_quaternion", &igl::viewer::Viewer::snap_to_canonical_quaternion) + .def("open_dialog_load_mesh", &igl::viewer::Viewer::open_dialog_load_mesh) + .def("open_dialog_save_mesh", &igl::viewer::Viewer::open_dialog_save_mesh) // Callbacks .def_readwrite("callback_init", &igl::viewer::Viewer::callback_init) diff --git a/python/py_vector.cpp b/python/py_vector.cpp index 641b8172f..d130bd990 100644 --- a/python/py_vector.cpp +++ b/python/py_vector.cpp @@ -597,6 +597,11 @@ void python_export_vector(py::module &m) { py::implicitly_convertible(); py::implicitly_convertible(); + /* Bindings for MatrixXuc */ + bind_eigen_2 > (me, "MatrixXuc"); + py::implicitly_convertible >(); + py::implicitly_convertible >(); + // /* Bindings for Vector3d */ // auto vector3 = bind_eigen_1_3(me, "Vector3d"); // vector3 diff --git a/python/python.cpp b/python/python.cpp index a3ceeb0b7..fc77177c0 100644 --- a/python/python.cpp +++ b/python/python.cpp @@ -27,6 +27,24 @@ void assert_is_RowVector3d(const std::string name, const Eigen::MatrixXd& v) throw std::runtime_error(name + " must be a row vector with 3 entries."); } +void assert_is_Vector4d(const std::string name, const Eigen::MatrixXd& v) +{ + if ((v.cols() != 1) || (v.rows() != 4)) + throw std::runtime_error(name + " must be a column vector with 4 entries."); +} + +void assert_is_RowVector4d(const std::string name, const Eigen::MatrixXd& v) +{ + if ((v.cols() != 4) || (v.rows() != 1)) + throw std::runtime_error(name + " must be a row vector with 4 entries."); +} + +void assert_is_Matrix4d(const std::string name, const Eigen::MatrixXd& v) +{ + if ((v.cols() != 4) || (v.rows() != 4)) + throw std::runtime_error(name + " must be a 4x4 matrix."); +} + extern void python_export_vector(py::module &); extern void python_export_igl(py::module &); extern void python_export_igl_viewer(py::module &); diff --git a/python/python.h b/python/python.h index 7faa96902..65dc5841a 100644 --- a/python/python.h +++ b/python/python.h @@ -15,5 +15,9 @@ void assert_is_VectorXd(const std::string name, const Eigen::MatrixXd& v); void assert_is_RowVectorXd(const std::string name, const Eigen::MatrixXd& v); void assert_is_Vector3d(const std::string name, const Eigen::MatrixXd& v); void assert_is_RowVector3d(const std::string name, const Eigen::MatrixXd& v); +void assert_is_Vector4d(const std::string name, const Eigen::MatrixXd& v); +void assert_is_RowVector4d(const std::string name, const Eigen::MatrixXd& v); +void assert_is_Matrix4d(const std::string name, const Eigen::MatrixXd& v); + namespace py = pybind;