├── .gitignore ├── LICENSE ├── README.md ├── images └── oct_index.PNG ├── sample_data ├── dodecahedron.ply ├── hexahedron.ply ├── icosahedron.ply ├── octahedron.3ds ├── octahedron.obj ├── octahedron.off ├── octahedron.ply ├── octahedron.stl ├── octahedron_bin.ply ├── octahedron_half.obj ├── stanford_bunny.ply └── stanford_bunny_bin.ply └── samples ├── add_del_vert_face ├── CMakeLists.txt ├── README.md └── main.cpp ├── adjacent ├── CMakeLists.txt ├── README.md └── main.cpp ├── angle_two_vector ├── CMakeLists.txt ├── README.md └── main.cpp ├── conv_deg_and_rad ├── CMakeLists.txt ├── README.md └── main.cpp ├── copy_mesh ├── CMakeLists.txt ├── README.md └── main.cpp ├── create_mesh_manually ├── CMakeLists.txt ├── README.md └── main.cpp ├── create_preset_obj ├── CMakeLists.txt ├── README.md └── main.cpp ├── curvature ├── CMakeLists.txt ├── README.md └── main.cpp ├── dist_point_line ├── CMakeLists.txt ├── README.md └── main.cpp ├── dist_point_plane ├── CMakeLists.txt ├── README.md └── main.cpp ├── dist_two_points ├── CMakeLists.txt ├── README.md └── main.cpp ├── expand_select ├── CMakeLists.txt ├── README.md └── main.cpp ├── flags ├── CMakeLists.txt ├── README.md └── main.cpp ├── hello_mesh ├── CMakeLists.txt ├── README.md └── main.cpp ├── iterator ├── CMakeLists.txt ├── README.md └── main.cpp ├── matrix_with_eigen ├── CMakeLists.txt ├── README.md └── main.cpp ├── ply_with_vert_value ├── CMakeLists.txt ├── README.md └── main.cpp ├── quaternion ├── CMakeLists.txt ├── README.md └── main.cpp ├── read_write_file ├── CMakeLists.txt ├── README.md └── main.cpp ├── remove_non_manifold ├── CMakeLists.txt ├── README.md └── main.cpp ├── set_color ├── CMakeLists.txt ├── README.md └── main.cpp ├── simplification ├── CMakeLists.txt ├── README.md ├── main.cpp ├── quadric_simp.cpp └── quadric_simp.h ├── subdivision ├── CMakeLists.txt ├── README.md └── main.cpp ├── template ├── CMakeLists.txt ├── README.md └── main.cpp ├── template_meshlab ├── CMakeLists.txt ├── README.md └── main.cpp ├── template_pybind ├── CMakeLists.txt ├── README.md ├── main.cpp └── out.ply ├── transformation_matrix ├── CMakeLists.txt ├── README.md └── main.cpp └── user_defined_attr ├── CMakeLists.txt ├── README.md └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.dylib 11 | 12 | # Qt-es 13 | object_script.*.Release 14 | object_script.*.Debug 15 | *_plugin_import.cpp 16 | /.qmake.cache 17 | /.qmake.stash 18 | *.pro.user 19 | *.pro.user.* 20 | *.qbs.user 21 | *.qbs.user.* 22 | *.moc 23 | moc_*.cpp 24 | moc_*.h 25 | qrc_*.cpp 26 | ui_*.h 27 | *.qmlc 28 | *.jsc 29 | Makefile* 30 | *build-* 31 | 32 | # Qt unit tests 33 | target_wrapper.* 34 | 35 | # QtCreator 36 | *.autosave 37 | 38 | # QtCreator Qml 39 | *.qmlproject.user 40 | *.qmlproject.user.* 41 | 42 | # QtCreator CMake 43 | CMakeLists.txt.user* 44 | 45 | *build* 46 | *.exe 47 | *.pdb 48 | *.ilk -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Nitta-K 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vcglib_samples 2 | sample codes of vcglib and MeshLab function. 3 | 4 | # Introduction 5 | 6 | ``` 7 | The Visualization and Computer Graphics Library (VCG for short) is a open source portable C++ templated library for manipulation, processing and displaying with OpenGL of triangle and tetrahedral meshes. 8 | ``` 9 | 10 | - [VCG Library](http://vcg.isti.cnr.it/vcglib/)([Github](https://github.com/cnr-isti-vclab/vcglib)) 11 | - [meshlab](https://www.meshlab.net/)([Github](https://github.com/cnr-isti-vclab/meshlab)) 12 | 13 | # Get started 14 | 15 | ## Requirements 16 | 17 | - [cmake](https://cmake.org/) 18 | - [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page) 19 | - C++ compiler(visual studio, gcc, ... etc.) 20 | - [Qt](https://www.qt.io/jp) (not necessary but it's easy to visualize) 21 | 22 | ## Get library from github 23 | 24 | Clone vcglib from github. You should select `devel`branch (`master` branch is too old). 25 | 26 | ```shell 27 | $ git clone -b devel https://github.com/cnr-isti-vclab/vcglib.git 28 | Cloning into 'vcglib'... 29 | remote: Enumerating objects: 5, done. 30 | remote: Counting objects: 100% (5/5), done. 31 | remote: Compressing objects: 100% (5/5), done. 32 | remote: Total 42007 (delta 0), reused 1 (delta 0), pack-reused 42002 33 | Receiving objects: 100% (42007/42007), 17.24 MiB | 1.23 MiB/s, done. 34 | Resolving deltas: 100% (28087/28087), done. 35 | Checking out files: 100% (1063/1063), done. 36 | 37 | $ cd vcglib 38 | 39 | $ git branch 40 | * devel 41 | ``` 42 | 43 | ## How to build with cmake 44 | 45 | First, you have to set below environment values 46 | 47 | - `VCGLIB_DIR` : path/to/vcglib (e.g. `C:/Users/Public/Documents/GitHub/vcglib`) 48 | - `MESHLAB_DIR` : path/to/MeshLab/source (e.g. `C:/Users/Public/Documents/GitHub/meshlab/src`) 49 | - `EIGEN3_INCLUDE_DIR` : path/to/Eigen3 (e.g. `C:/eigen-3.3.7`) 50 | 51 | see this [sample](./samples/hello_mesh) for details. 52 | 53 | # Samples 54 | 55 | ## Basic data structure 56 | 57 | - template data structure : [CODE](./samples/template) 58 | - template data structure from MeshLab : [CODE](./samples/template_meshlab) 59 | - access mesh vertices/faces : [CODE](./samples/iterator) 60 | - set flag of vertices/faces : [CODE](./samples/flags) 61 | - expand select function : [CODE](./samples/expand_select) 62 | - get adjacent vertices/faces : [CODE](./samples/adjacent) 63 | - create mesh using just a vector of coords and a vector of indexes : [CODE](./samples/create_mesh_manually) 64 | - user defined attribute : [CODE](./samples/user_defined_attr) 65 | - add and delete vertices/faces : [CODE](./samples/add_del_vert_face) 66 | - set color each vertex/face and save as ply: [CODE](./samples/set_color) 67 | - set vertex value and save as ply format : [CODE](./samples/ply_with_vert_value) 68 | - copy and merge mesh data : [CODE](samples/copy_mesh) 69 | 70 | 71 | 72 | ## Read/Write file 73 | 74 | - read and write basic file formats : [CODE](./samples/read_write_file) 75 | - create preset object : [CODE](./samples/create_preset_obj) 76 | 77 | 78 | 79 | 80 | ## Basic algorithm (vcglib functions) 81 | 82 | - convert degree and radian: [CODE](./samples/conv_deg_and_rad) 83 | - distance between two points : [CODE](./samples/dist_two_points) 84 | - distance between point and line : [CODE](./samples/dist_point_line) 85 | - distance between point and plane : [CODE](./samples/dist_point_plane) 86 | - angle between two vectors : [CODE](./samples/angle_two_vector) 87 | - quaternion : [CODE](./samples/quaternion) 88 | - transformation matrix : [CODE](./samples/transformation_matrix) 89 | - translate matrix with Eigen : [CODE](./samples/matrix_with_eigen) 90 | - remove non manifold vertices and faces : [CODE](samples/remove_non_manifold) 未完成 91 | 92 | 93 | 94 | ## Extra algorithm (implemented in MeshLab) 95 | 96 | use MeshLab data structure. 97 | 98 | - template data structure from MeshLab : [CODE](./samples/template_meshlab) 99 | - calculate curvature : [CODE](samples/curvature) 100 | - hole filing : [CODE] 101 | - mesh simplification : [CODE](samples/simplification) 未完成 102 | - calculate Hausdorff distance : [CODE](samples/Hausdorff_distance) 内容整理 sample target 103 | - mesh intersection : [CODE] 104 | - select boundary line : [CODE] 105 | - simplification : [CODE](./samples/simplification) 106 | - subdivision : [CODE](./samples/subdivision) 107 | 108 | 109 | 110 | ## Visualize with Qt 111 | 112 | 113 | 114 | ## Visualize with three.js 115 | 116 | 117 | 118 | # Error handling 119 | 120 | `Missing Component Exception -FFAdjacency-`のようなケース 121 | 122 | ```cpp 123 | // adjacency関連を有効にする(頂点と面でそれぞれ有効化しないといけないものもある) 124 | mesh.vert.EnableVFAdjacency(); 125 | mesh.face.EnableFFAdjacency(); 126 | mesh.vert.EnableCurvature(); 127 | mesh.vert.EnableCurvatureDir(); 128 | ``` 129 | 130 | `Assertion failed: f.cFFp(j) != 0, file C:/Users/Public/Documents/GitHub/vcglib/vcg/simplex/face/topology.h, line 39` のようなケース 131 | 132 | ```cpp 133 | // 初期化時と関係性が変わった場合は更新が必要 134 | tri::UpdateTopology::FaceFace(mesh); 135 | tri::UpdateTopology::VertexFace(mesh); 136 | tri::UpdateNormal::PerFace(mesh); 137 | tri::UpdateNormal::NormalizePerFace(mesh); 138 | ``` 139 | 140 | 141 | 142 | # How to port the function of MeshLab 143 | 144 | MeshLab implements many functions in a plugin format. 145 | A list of plugins can be found [here](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/meshlabplugins). 146 | 147 | Let's take a look at the structure of the [mlsplugin.cpp](https://github.com/cnr-isti-vclab/meshlab/blob/master/src/meshlabplugins/filter_mls/mlsplugin.cpp) file as an example. 148 | The name of the implemented function is defined [here](https://github.com/cnr-isti-vclab/meshlab/blob/master/src/meshlabplugins/filter_mls/mlsplugin.cpp#L87:#L96). 149 | The function for plugins is the [applyFilter](https://github.com/cnr-isti-vclab/meshlab/blob/master/src/meshlabplugins/filter_mls/mlsplugin.cpp#L360) function. 150 | 151 | The process branches according to the ID contained in the `filter` variable. 152 | The `applyFiter` function is the starting point of each plug-in process, so if you follow the process from here, you can check all the implementation details. 153 | 154 | When searching for the function you want to know how to be implemented on MeshLab, it is recommended way that search function name by using grep command in source directory. 155 | 156 | --- 157 | 158 | # 残り 159 | 160 | ## 020_trackball 161 | 162 | トラックボール表示するだけのサンプル 163 | 164 | 視点操作はトラックボール使うと楽にできるが、固定シェーダ前提になる 165 | 166 | ## 021_trackball_mesh 167 | 168 | トラックボールとメッシュデータ表示するサンプル 169 | 170 | 光源用の処理も追加 171 | 172 | ### メッシュ間の干渉判定 173 | 174 | ```cpp 175 | // mesh1においてmesh2との干渉面が選択される(mesh2はそのまま) 176 | mesh2.face.EnableMark(); 177 | int a = vcg::tri::Clean::SelectIntersectingFaces(mesh1, mesh2); 178 | ``` 179 | 180 | ### end 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /images/oct_index.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/images/oct_index.PNG -------------------------------------------------------------------------------- /sample_data/dodecahedron.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/sample_data/dodecahedron.ply -------------------------------------------------------------------------------- /sample_data/hexahedron.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/sample_data/hexahedron.ply -------------------------------------------------------------------------------- /sample_data/icosahedron.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/sample_data/icosahedron.ply -------------------------------------------------------------------------------- /sample_data/octahedron.3ds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/sample_data/octahedron.3ds -------------------------------------------------------------------------------- /sample_data/octahedron.obj: -------------------------------------------------------------------------------- 1 | #### 2 | # 3 | # OBJ File Generated by Meshlab 4 | # 5 | #### 6 | # Object octahedron.obj 7 | # 8 | # Vertices: 6 9 | # Faces: 8 10 | # 11 | #### 12 | v 1.000000 0.000000 0.000000 13 | v 0.000000 1.000000 0.000000 14 | v 0.000000 0.000000 1.000000 15 | v -1.000000 0.000000 0.000000 16 | v 0.000000 -1.000000 0.000000 17 | v 0.000000 0.000000 -1.000000 18 | # 6 vertices, 0 vertices normals 19 | 20 | f 1 2 3 21 | f 1 3 5 22 | f 1 5 6 23 | f 1 6 2 24 | f 4 2 6 25 | f 4 6 5 26 | f 4 5 3 27 | f 4 3 2 28 | # 8 faces, 0 coords texture 29 | 30 | # End of File 31 | -------------------------------------------------------------------------------- /sample_data/octahedron.off: -------------------------------------------------------------------------------- 1 | OFF 2 | 6 8 0 3 | 1 0 0 4 | 0 1 0 5 | 0 0 1 6 | -1 0 0 7 | 0 -1 0 8 | 0 0 -1 9 | 3 0 1 2 10 | 3 0 2 4 11 | 3 0 4 5 12 | 3 0 5 1 13 | 3 3 1 5 14 | 3 3 5 4 15 | 3 3 4 2 16 | 3 3 2 1 17 | -------------------------------------------------------------------------------- /sample_data/octahedron.ply: -------------------------------------------------------------------------------- 1 | ply 2 | format ascii 1.0 3 | comment VCGLIB generated 4 | element vertex 6 5 | property float x 6 | property float y 7 | property float z 8 | element face 8 9 | property list uchar int vertex_indices 10 | end_header 11 | 1 0 0 12 | 0 1 0 13 | 0 0 1 14 | -1 0 0 15 | 0 -1 0 16 | 0 0 -1 17 | 3 0 1 2 18 | 3 0 2 4 19 | 3 0 4 5 20 | 3 0 5 1 21 | 3 3 1 5 22 | 3 3 5 4 23 | 3 3 4 2 24 | 3 3 2 1 25 | -------------------------------------------------------------------------------- /sample_data/octahedron.stl: -------------------------------------------------------------------------------- 1 | solid STL generated by MeshLab 2 | facet normal 5.773503e-01 5.773503e-01 5.773503e-01 3 | outer loop 4 | vertex 1.000000e+00 0.000000e+00 0.000000e+00 5 | vertex 0.000000e+00 1.000000e+00 0.000000e+00 6 | vertex 0.000000e+00 0.000000e+00 1.000000e+00 7 | endloop 8 | endfacet 9 | facet normal 5.773503e-01 -5.773503e-01 5.773503e-01 10 | outer loop 11 | vertex 1.000000e+00 0.000000e+00 0.000000e+00 12 | vertex 0.000000e+00 0.000000e+00 1.000000e+00 13 | vertex 0.000000e+00 -1.000000e+00 0.000000e+00 14 | endloop 15 | endfacet 16 | facet normal 5.773503e-01 -5.773503e-01 -5.773503e-01 17 | outer loop 18 | vertex 1.000000e+00 0.000000e+00 0.000000e+00 19 | vertex 0.000000e+00 -1.000000e+00 0.000000e+00 20 | vertex 0.000000e+00 0.000000e+00 -1.000000e+00 21 | endloop 22 | endfacet 23 | facet normal 5.773503e-01 5.773503e-01 -5.773503e-01 24 | outer loop 25 | vertex 1.000000e+00 0.000000e+00 0.000000e+00 26 | vertex 0.000000e+00 0.000000e+00 -1.000000e+00 27 | vertex 0.000000e+00 1.000000e+00 0.000000e+00 28 | endloop 29 | endfacet 30 | facet normal -5.773503e-01 5.773503e-01 -5.773503e-01 31 | outer loop 32 | vertex -1.000000e+00 0.000000e+00 0.000000e+00 33 | vertex 0.000000e+00 1.000000e+00 0.000000e+00 34 | vertex 0.000000e+00 0.000000e+00 -1.000000e+00 35 | endloop 36 | endfacet 37 | facet normal -5.773503e-01 -5.773503e-01 -5.773503e-01 38 | outer loop 39 | vertex -1.000000e+00 0.000000e+00 0.000000e+00 40 | vertex 0.000000e+00 0.000000e+00 -1.000000e+00 41 | vertex 0.000000e+00 -1.000000e+00 0.000000e+00 42 | endloop 43 | endfacet 44 | facet normal -5.773503e-01 -5.773503e-01 5.773503e-01 45 | outer loop 46 | vertex -1.000000e+00 0.000000e+00 0.000000e+00 47 | vertex 0.000000e+00 -1.000000e+00 0.000000e+00 48 | vertex 0.000000e+00 0.000000e+00 1.000000e+00 49 | endloop 50 | endfacet 51 | facet normal -5.773503e-01 5.773503e-01 5.773503e-01 52 | outer loop 53 | vertex -1.000000e+00 0.000000e+00 0.000000e+00 54 | vertex 0.000000e+00 0.000000e+00 1.000000e+00 55 | vertex 0.000000e+00 1.000000e+00 0.000000e+00 56 | endloop 57 | endfacet 58 | endsolid vcg 59 | -------------------------------------------------------------------------------- /sample_data/octahedron_bin.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/sample_data/octahedron_bin.ply -------------------------------------------------------------------------------- /sample_data/octahedron_half.obj: -------------------------------------------------------------------------------- 1 | #### 2 | # 3 | # OBJ File Generated by Meshlab 4 | # 5 | #### 6 | # Object octahedron_half.obj 7 | # 8 | # Vertices: 6 9 | # Faces: 4 10 | # 11 | #### 12 | v 1.000000 0.000000 0.000000 13 | v 0.000000 1.000000 0.000000 14 | v 0.000000 0.000000 1.000000 15 | v -1.000000 0.000000 0.000000 16 | v 0.000000 -1.000000 0.000000 17 | v 0.000000 0.000000 -1.000000 18 | # 6 vertices, 0 vertices normals 19 | 20 | f 1 2 3 21 | f 1 3 5 22 | f 4 5 3 23 | f 4 3 2 24 | # 4 faces, 0 coords texture 25 | 26 | # End of File 27 | -------------------------------------------------------------------------------- /sample_data/stanford_bunny_bin.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/sample_data/stanford_bunny_bin.ply -------------------------------------------------------------------------------- /samples/add_del_vert_face/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/add_del_vert_face/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ### add 4 | 5 | ```cpp 6 | // add vertices and faces 7 | size_t v_add_num = 3; 8 | CMeshO::VertexIterator vi = tri::Allocator::AddVertices(mesh, v_add_num); 9 | size_t f_add_num = 1; 10 | CMeshO::FaceIterator fi = tri::Allocator::AddFaces(mesh, f_add_num); 11 | 12 | vi[0].P() = Point3f(1,1,1); 13 | vi[1].P() = Point3f(1,0,0); 14 | vi[2].P() = Point3f(2,2,2); 15 | 16 | fi[0].V(0) = &(vi[0]); 17 | fi[0].V(1) = &(vi[1]); 18 | fi[0].V(2) = &(vi[2]); 19 | ``` 20 | 21 | ### delete 22 | 23 | If you want to delete a vertex, you must first delete the face to which it belongs. 24 | 25 | So you need to get the faces that belong to the vertices. 26 | 27 | See get adjacent vertices/faces : [CODE](../adjacent). 28 | 29 | ```cpp 30 | mesh.vert.EnableVFAdjacency(); 31 | mesh.face.EnableFFAdjacency(); 32 | mesh.face.EnableVFAdjacency(); 33 | 34 | CMeshO::VertexPointer vp = &(mesh.vert[0]); 35 | tri::Allocator::DeleteVertex(mesh, *vp); 36 | 37 | // if you delete vertices, you need to consider whether the vertices belong to a face. 38 | for (face::VFIterator vfi(vp); !vfi.End(); ++vfi){ 39 | CMeshO::FacePointer fp = vfi.F(); 40 | tri::Allocator::DeleteFace(mesh, *fp); 41 | } 42 | 43 | // you have to update some informations 44 | tri::Allocator::CompactEveryVector(mesh); 45 | tri::UpdateTopology::FaceFace(mesh); 46 | tri::UpdateTopology::VertexFace(mesh); 47 | ``` 48 | 49 | ### append mesh 50 | 51 | ```cpp 52 | CMeshO mesh1, mesh2; 53 | tri::Hexahedron(mesh1); 54 | tri::Tetrahedron(mesh2); 55 | 56 | bool selected = false; 57 | bool adjFlag = true; 58 | tri::Append::Mesh(mesh1, mesh2, selected, adjFlag); // copy with adj information 59 | ``` 60 | 61 | 62 | 63 | ## output 64 | 65 | ```shell 66 | initial state 67 | vp: 0 1 2 3 68 | fp: 0 1 2 3 69 | added state 70 | vp: 0 1 2 3 4 5 6 71 | fp: 0 1 2 3 4 72 | delete 73 | append mesh 1 74 | append mesh: 12:16 75 | append mesh 2 76 | append mesh: 12:16 77 | ``` 78 | 79 | -------------------------------------------------------------------------------- /samples/add_del_vert_face/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | CMeshO mesh; 10 | tri::Tetrahedron(mesh); 11 | 12 | cout << "initial state" << endl; 13 | cout << "vp: "; 14 | for(auto &&vp:mesh.vert) 15 | cout << vp.Index() << " "; 16 | cout << endl; 17 | cout << "fp: "; 18 | for(auto &&fp:mesh.face) 19 | cout << fp.Index() << " "; 20 | cout << endl; 21 | 22 | // add vertices and faces 23 | size_t v_add_num = 3; 24 | CMeshO::VertexIterator vi = tri::Allocator::AddVertices(mesh, v_add_num); 25 | size_t f_add_num = 1; 26 | CMeshO::FaceIterator fi = tri::Allocator::AddFaces(mesh, f_add_num); 27 | 28 | vi[0].P() = Point3f(1,1,1); 29 | vi[1].P() = Point3f(1,0,0); 30 | vi[2].P() = Point3f(2,2,2); 31 | 32 | fi[0].V(0) = &(vi[0]); 33 | fi[0].V(1) = &(vi[1]); 34 | fi[0].V(2) = &(vi[2]); 35 | 36 | cout << "added state" << endl; 37 | cout << "vp: "; 38 | for(auto &&vp:mesh.vert) 39 | cout << vp.Index() << " "; 40 | cout << endl; 41 | cout << "fp: "; 42 | for(auto &&fp:mesh.face) 43 | cout << fp.Index() << " "; 44 | cout << endl; 45 | 46 | // delete vertices and faces 47 | { 48 | cout << "delete" << endl; 49 | 50 | mesh.vert.EnableVFAdjacency(); 51 | mesh.face.EnableFFAdjacency(); 52 | mesh.face.EnableVFAdjacency(); 53 | 54 | CMeshO::VertexPointer vp = &(mesh.vert[0]); 55 | tri::Allocator::DeleteVertex(mesh, *vp); 56 | 57 | // if you delete vertices, you need to consider whether the vertices belong to a face. 58 | for (face::VFIterator vfi(vp); !vfi.End(); ++vfi){ 59 | CMeshO::FacePointer fp = vfi.F(); 60 | tri::Allocator::DeleteFace(mesh, *fp); 61 | } 62 | 63 | // you have to update some informations 64 | tri::Allocator::CompactEveryVector(mesh); 65 | tri::UpdateTopology::FaceFace(mesh); 66 | tri::UpdateTopology::VertexFace(mesh); 67 | } 68 | 69 | // another sample : add mesh2 to mesh1 70 | { 71 | cout << "append mesh 1" << endl; 72 | CMeshO mesh1, mesh2; 73 | tri::Hexahedron(mesh1); 74 | tri::Tetrahedron(mesh2); 75 | 76 | // vi and fi start from adding position 77 | auto vi = tri::Allocator::AddVertices(mesh1, mesh2.VN()); 78 | auto fi = tri::Allocator::AddFaces(mesh1, mesh2.FN()); 79 | 80 | for(int i=0; iIndex(); 86 | fi[i].V(j) = &vi[id]; 87 | } 88 | } 89 | cout << "append mesh: " << mesh1.VN() << ":" << mesh1.FN() << endl; 90 | } 91 | // and above code is same below one 92 | { 93 | cout << "append mesh 2" << endl; 94 | CMeshO mesh1, mesh2; 95 | tri::Hexahedron(mesh1); 96 | tri::Tetrahedron(mesh2); 97 | 98 | bool selected = false; 99 | bool adjFlag = true; 100 | tri::Append::Mesh(mesh1, mesh2, selected, adjFlag); // copy with adj information 101 | 102 | cout << "append mesh: " << mesh1.VN() << ":" << mesh1.FN() << endl; 103 | } 104 | 105 | return 1; 106 | } 107 | -------------------------------------------------------------------------------- /samples/adjacent/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # Add Executable 31 | add_executable(${PROJECT_NAME}) 32 | target_sources(${PROJECT_NAME} 33 | PRIVATE 34 | main.cpp 35 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 36 | ) 37 | target_include_directories(${PROJECT_NAME} 38 | PUBLIC 39 | ${VCGLIB_DIR} 40 | ${MESHLAB_DIR} 41 | ${EIGEN3_INCLUDE_DIR} 42 | ) 43 | 44 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 45 | -------------------------------------------------------------------------------- /samples/adjacent/README.md: -------------------------------------------------------------------------------- 1 | Reference : http://vcg.isti.cnr.it/vcglib/adjacency.html 2 | 3 | 4 | 5 | ```cpp 6 | // get adjacent faces from a face 7 | cout << "adjacent faces from a face" << endl; 8 | for(int i=0; i<3; ++i){ 9 | CMeshO::FacePointer fp = &(mesh.face[0]); 10 | CMeshO::FacePointer fadj = fp->FFp(i); 11 | cout << fp->Index() << " : " << fadj->Index() << endl; 12 | } 13 | 14 | // Around the adjacent faces centering on the vertex vp (The order of rotation is undefined) 15 | cout << "VFIterator" << endl; 16 | for (face::VFIterator vfi(vp); !vfi.End(); ++vfi){ 17 | cout << vfi.F()->Index() << endl; 18 | } 19 | 20 | // Around the adjacent vertices centering on the vertex vp (The order of rotation is counter clock wise in default option) 21 | cout << "VVOrderedStarFF" << endl; 22 | vector vecvt; 23 | face::VFIterator vfi(vp); // set VFIterator from vertex 24 | face::Pos fpos; 25 | fpos.Set(vfi.f, vp); // set face pos from VFIterator 26 | face::VVOrderedStarFF(fpos, vecvt); // get adjacent vertices of vp (counter clock wise) 27 | for(auto &&vp : vecvt){ 28 | cout << vp->Index() << endl; 29 | } 30 | 31 | // Around the adjacent faces centering on the vertex vp (The order of rotation is counter clock wise in default option) 32 | cout << "VFOrderedStarFF" << endl; 33 | vector> vecfpos; 34 | face::VFOrderedStarFF(fpos, vecfpos); 35 | cout << " vert" << endl; 36 | for(auto &&fps : vecfpos){ 37 | cout << fps.V()->Index() << endl; // vert is always same because it's center of ratation 38 | } 39 | cout << " face" << endl; 40 | for(auto &&fps : vecfpos){ 41 | cout << fps.F()->Index() << endl; 42 | } 43 | ``` 44 | 45 | 46 | 47 | index of sample data 48 | 49 | ![Octahedron](../../images/oct_index.PNG) 50 | 51 | 52 | 53 | output 54 | 55 | ```shell 56 | adjacent faces from a face 57 | 0 : 3 58 | 0 : 7 59 | 0 : 1 60 | VFIterator 61 | 3 62 | 2 63 | 1 64 | 0 65 | VVOrderedStarFF 66 | 1 67 | 2 68 | 4 69 | 5 70 | VFOrderedStarFF 71 | vert 72 | 0 73 | 0 74 | 0 75 | 0 76 | face 77 | 3 78 | 0 79 | 1 80 | 2 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /samples/adjacent/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | CMeshO mesh; 10 | tri::Octahedron(mesh); // create preset mesh data 11 | 12 | mesh.vert.EnableVFAdjacency(); 13 | mesh.face.EnableFFAdjacency(); 14 | mesh.face.EnableVFAdjacency(); 15 | 16 | tri::UpdateTopology::VertexFace(mesh); 17 | tri::UpdateTopology::FaceFace(mesh); 18 | 19 | CMeshO::VertexPointer vp; 20 | vp = &(mesh.vert[0]); 21 | if(vp->HasVFAdjacency()==false){ 22 | cout << "Adjacency is not valid" << endl; 23 | return 0; 24 | } 25 | 26 | // get adjacent faces from a face 27 | cout << "adjacent faces from a face" << endl; 28 | for(int i=0; i<3; ++i){ 29 | CMeshO::FacePointer fp = &(mesh.face[0]); 30 | CMeshO::FacePointer fadj = fp->FFp(i); 31 | cout << fp->Index() << " : " << fadj->Index() << endl; 32 | } 33 | 34 | // Around the adjacent faces centering on the vertex vp (The order of rotation is undefined) 35 | cout << "VFIterator" << endl; 36 | for (face::VFIterator vfi(vp); !vfi.End(); ++vfi){ 37 | cout << vfi.F()->Index() << endl; 38 | } 39 | 40 | // Around the adjacent vertices centering on the vertex vp (The order of rotation is counter clock wise in default option) 41 | cout << "VVOrderedStarFF" << endl; 42 | vector vecvt; 43 | face::VFIterator vfi(vp); // set VFIterator from vertex 44 | face::Pos fpos; 45 | fpos.Set(vfi.f, vp); // set face pos from VFIterator 46 | face::VVOrderedStarFF(fpos, vecvt); // get adjacent vertices of vp (counter clock wise) 47 | for(auto &&vp : vecvt){ 48 | cout << vp->Index() << endl; 49 | } 50 | 51 | // Around the adjacent faces centering on the vertex vp (The order of rotation is counter clock wise in default option) 52 | cout << "VFOrderedStarFF" << endl; 53 | vector> vecfpos; 54 | face::VFOrderedStarFF(fpos, vecfpos); 55 | cout << " vert" << endl; 56 | for(auto &&fps : vecfpos){ 57 | cout << fps.V()->Index() << endl; // vert is always same because it's center of ratation 58 | } 59 | cout << " face" << endl; 60 | for(auto &&fps : vecfpos){ 61 | cout << fps.F()->Index() << endl; 62 | } 63 | return 1; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /samples/angle_two_vector/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${EIGEN3_INCLUDE_DIR} 37 | ${VCGLIB_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/angle_two_vector/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | 6 | using namespace vcg; 7 | using namespace std; 8 | 9 | int main(){ 10 | vcg::Point3f a(0,0,1), b(1,1,0); 11 | float ang = vcg::Angle(a, b); 12 | cout << vcg::math::ToDeg(ang) << endl; 13 | 14 | return 1; 15 | } 16 | ``` 17 | 18 | 19 | 20 | ## output 21 | 22 | ```shell 23 | 90 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /samples/angle_two_vector/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | int main(){ 7 | vcg::Point3f a(0,0,1), b(1,1,0); 8 | float ang = vcg::Angle(a, b); 9 | cout << vcg::math::ToDeg(ang) << endl; 10 | 11 | return 1; 12 | } 13 | -------------------------------------------------------------------------------- /samples/conv_deg_and_rad/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/conv_deg_and_rad/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | 6 | using namespace vcg; 7 | using namespace std; 8 | 9 | int main(){ 10 | float a = vcg::math::ToRad(90.0f); 11 | float b = vcg::math::ToDeg(a); 12 | 13 | cout << a << endl; 14 | cout << b << endl; 15 | 16 | return 1; 17 | } 18 | ``` 19 | 20 | 21 | 22 | ## output 23 | 24 | ```shell 25 | 1.5708 26 | 90 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /samples/conv_deg_and_rad/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | int main(){ 7 | float a = vcg::math::ToRad(90.0f); 8 | float b = vcg::math::ToDeg(a); 9 | 10 | cout << a << endl; 11 | cout << b << endl; 12 | 13 | return 1; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /samples/copy_mesh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/copy_mesh/README.md: -------------------------------------------------------------------------------- 1 | # copy and append 2 | 3 | ## main.cpp 4 | 5 | ```cpp 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace vcg; 11 | using namespace std; 12 | 13 | int main(){ 14 | CMeshO mesh1, mesh2; 15 | tri::Tetrahedron(mesh1); 16 | tri::Hexahedron(mesh2); 17 | 18 | cout << "mesh1 : " << mesh1.VN() << "," << mesh1.FN() << endl; 19 | cout << "mesh2 : " << mesh2.VN() << "," << mesh2.FN() << endl; 20 | 21 | bool selected = false; 22 | bool adjFlag = true; 23 | 24 | tri::Append::Mesh(mesh1, mesh2, selected, adjFlag); // mesh1 += mesh2 25 | cout << "mesh1 += mesh2 : " << mesh1.VN() << "," << mesh1.FN() << endl; 26 | 27 | CMeshO mesh; 28 | tri::Append::MeshCopy(mesh, mesh2, selected, adjFlag); // mesh = mesh2 29 | cout << "mesh = mesh2 : " << mesh.VN() << "," << mesh.FN() << endl; 30 | 31 | return 1; 32 | } 33 | ``` 34 | 35 | ## output 36 | 37 | ```shell 38 | mesh1 : 4,4 39 | mesh2 : 8,12 40 | mesh1 += mesh2 : 12,16 41 | mesh = mesh2 : 8,12 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /samples/copy_mesh/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | CMeshO mesh1, mesh2; 10 | tri::Tetrahedron(mesh1); 11 | tri::Hexahedron(mesh2); 12 | 13 | cout << "mesh1 : " << mesh1.VN() << "," << mesh1.FN() << endl; 14 | cout << "mesh2 : " << mesh2.VN() << "," << mesh2.FN() << endl; 15 | 16 | bool selected = false; 17 | bool adjFlag = true; 18 | 19 | tri::Append::Mesh(mesh1, mesh2, selected, adjFlag); // mesh1 += mesh2 20 | cout << "mesh1 += mesh2 : " << mesh1.VN() << "," << mesh1.FN() << endl; 21 | 22 | CMeshO mesh; 23 | tri::Append::MeshCopy(mesh, mesh2, selected, adjFlag); // mesh = mesh2 24 | cout << "mesh = mesh2 : " << mesh.VN() << "," << mesh.FN() << endl; 25 | 26 | return 1; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /samples/create_mesh_manually/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${VCGLIB_DIR} 37 | ${EIGEN3_INCLUDE_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/create_mesh_manually/README.md: -------------------------------------------------------------------------------- 1 | ```cpp 2 | // Create a simple triangles mesh using just a vector of coords and a vector of indexes 3 | vector coordVec; 4 | vector indexVec; 5 | 6 | coordVec.push_back(Point3f(0,0,0)); 7 | coordVec.push_back(Point3f(10,0,0)); 8 | coordVec.push_back(Point3f(0,10,0)); 9 | coordVec.push_back(Point3f(0,0,10)); 10 | 11 | indexVec.push_back(Point3i(0,1,3)); 12 | indexVec.push_back(Point3i(0,2,1)); 13 | indexVec.push_back(Point3i(0,3,2)); 14 | indexVec.push_back(Point3i(1,2,3)); 15 | 16 | tri::BuildMeshFromCoordVectorIndexVector(mesh,coordVec,indexVec); 17 | ``` 18 | 19 | -------------------------------------------------------------------------------- /samples/create_mesh_manually/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | class MyFace; 9 | class MyVertex; 10 | 11 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 12 | class MyVertex : public Vertex< MyUsedTypes, 13 | vertex::Coord3f, 14 | vertex::Normal3f, 15 | vertex::BitFlags, 16 | vertex::VFAdj 17 | > {}; 18 | class MyFace : public Face< MyUsedTypes, 19 | face::VertexRef, 20 | face::Normal3f, 21 | face::VFAdj, 22 | face::BitFlags 23 | > {}; 24 | class MyMesh : public tri::TriMesh< 25 | vector, 26 | vector 27 | > {}; 28 | 29 | int main(){ 30 | MyMesh mesh; 31 | 32 | // Create a simple triangles mesh using just a vector of coords and a vector of indexes 33 | vector coordVec; 34 | vector indexVec; 35 | 36 | coordVec.push_back(Point3f(0,0,0)); 37 | coordVec.push_back(Point3f(10,0,0)); 38 | coordVec.push_back(Point3f(0,10,0)); 39 | coordVec.push_back(Point3f(0,0,10)); 40 | 41 | indexVec.push_back(Point3i(0,1,3)); 42 | indexVec.push_back(Point3i(0,2,1)); 43 | indexVec.push_back(Point3i(0,3,2)); 44 | indexVec.push_back(Point3i(1,2,3)); 45 | 46 | tri::BuildMeshFromCoordVectorIndexVector(mesh,coordVec,indexVec); 47 | tri::io::ExporterSTL::Save(mesh, "out.stl"); 48 | return 1; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /samples/create_preset_obj/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | ) 33 | target_include_directories(${PROJECT_NAME} 34 | PUBLIC 35 | ${EIGEN3_INCLUDE_DIR} 36 | ${VCGLIB_DIR} 37 | ) 38 | 39 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 40 | -------------------------------------------------------------------------------- /samples/create_preset_obj/README.md: -------------------------------------------------------------------------------- 1 | you can create some preset shape. 2 | 3 | See [platonic.h](https://github.com/cnr-isti-vclab/vcglib/blob/devel/vcg/complex/algorithms/create/platonic.h) for details 4 | 5 | ```cpp 6 | tri::Tetrahedron(mesh); 7 | tri::Square(mesh); 8 | tri::Hexahedron(mesh); 9 | tri::Octahedron(mesh); 10 | tri::Dodecahedron(mesh); 11 | tri::Icosahedron(mesh); 12 | tri::Sphere(mesh, 3); 13 | // and more ... 14 | ``` 15 | 16 | -------------------------------------------------------------------------------- /samples/create_preset_obj/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace vcg; 5 | using namespace std; 6 | 7 | class MyFace; 8 | class MyVertex; 9 | 10 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 11 | class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::VFAdj> {}; 12 | class MyFace : public Face< MyUsedTypes, face::VertexRef, face::VFAdj, face::BitFlags> {}; 13 | class MyMesh : public tri::TriMesh, vector > {}; 14 | 15 | 16 | int main(){ 17 | MyMesh mesh; 18 | tri::Tetrahedron(mesh); 19 | tri::Square(mesh); 20 | tri::Hexahedron(mesh); 21 | tri::Octahedron(mesh); 22 | tri::Dodecahedron(mesh); 23 | tri::Icosahedron(mesh); 24 | tri::Sphere(mesh, 3); 25 | return 1; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /samples/curvature/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/curvature/README.md: -------------------------------------------------------------------------------- 1 | # Curvature 2 | 3 | ## Default curvature function 4 | 5 | 曲率計算はvcglibに実装されているものは 6 | 7 | ```cpp 8 | #include 9 | vcg::tri::UpdateCurvature::MeanAndGaussian(mesh); 10 | ``` 11 | 12 | 計算結果は各頂点に平均曲率とガウス曲率が入る。最大・最小曲率を計算したい場合は自分で計算する。 13 | 14 | 以下は最小曲率を各頂点のQ要素に入れている(Q要素はデフォルトで用意されている浮動小数点を保持するメンバ) 15 | 16 | ```cpp 17 | for(CMeshO::VertexIterator vi=mesh.vert.begin(); vi!=mesh.vert.end(); ++vi){ 18 | CMeshO::VertexType *pv = &*vi; 19 | float H = pv->Kh(); 20 | float G = pv->Kg(); 21 | float a = std::max(0.f, H*H-G); // h^2-gは手法によっては負になる場合があるので0でmaxとる 22 | MESHLAB_SCALAR sq = sqrt(a); 23 | pv->Q() = H-sq; // minimum curvature 24 | //pv->Q() = H+sq; // maximum curvature 25 | } 26 | ``` 27 | 28 | 曲率に応じて色分けをしたい場合はQ値によって色分けする関数を使用する 29 | 30 | ```cpp 31 | std::pair curv_minmax = vcg::tri::Stat::ComputePerVertexQualityMinMax(mesh); 32 | float curv_min = curv_minmax.first; 33 | float curv_max = curv_minmax.second; 34 | vcg::tri::UpdateColor::PerVertexQualityRamp(mesh, curv_min, curv_max); 35 | ``` 36 | 37 | ## APSS function 38 | 39 | MeshLabには曲率計算の拡張機能が実装されている 40 | 41 | 42 | 43 | ## Preparation for calculating curvature 44 | 45 | メッシュの構造が不正なもの(Non manifold)の状態で曲率を計算するとエラーが起きる。 46 | 47 | この場合は、あらかじめ不正な状態を解消する。 48 | 49 | 不正な状態は以下の関数で検出できる。 50 | 51 | ```cpp 52 | // Non manifoldの検出 53 | #include 54 | 55 | bool isNonManifold(CMeshO &mesh){ 56 | int cnt = 0; 57 | bool select_flag = false; 58 | 59 | // Count the number of non manifold edges in a mesh, e.g. the edges where there are more than 2 incident faces. 60 | // Note that this test is not enough to say that a mesh is two manifold, you have to count also the non manifold vertexes. 61 | cnt += tri::Clean::CountNonManifoldEdgeFF(mesh, select_flag); 62 | 63 | // Count (and eventually select) non 2-Manifold vertexes of a mesh 64 | // typical situation two cones connected by one vertex. 65 | cnt += tri::Clean::CountNonManifoldVertexFF(mesh, select_flag); 66 | return cnt>0; 67 | } 68 | 69 | mesh.vert.EnableVFAdjacency(); 70 | mesh.face.EnableFFAdjacency(); 71 | bool b = isNonManifold(mesh); 72 | ``` 73 | 74 | 75 | 76 | 不正な箇所は手動で修正することもできるが、一番簡単な方法は該当箇所を丸ごと削除してしまうことである。 77 | 78 | ```cpp 79 | int setDeleteFlagToSelectedFaceVert(CMeshO &mesh){ 80 | int vvn = mesh.vn; 81 | int ffn = mesh.fn; 82 | for (CMeshO::FaceIterator fi = mesh.face.begin(); fi != mesh.face.end(); ++fi) 83 | if (!(*fi).IsD() && (*fi).IsS()) 84 | tri::Allocator::DeleteFace(mesh, *fi); 85 | for (CMeshO::VertexIterator vi = mesh.vert.begin(); vi != mesh.vert.end(); ++vi) 86 | if (!(*vi).IsD() && (*vi).IsS()) 87 | tri::Allocator::DeleteVertex(mesh, *vi); 88 | return vvn - mesh.vn + ffn - mesh.fn; 89 | } 90 | 91 | int deleteUnreferencedVert(CMeshO &mesh, bool delDuplicate){ 92 | int dup = 0; 93 | if(delDuplicate){ 94 | dup = tri::Clean::RemoveDuplicateVertex(mesh); // STLとかの頂点が重複定義されるものは統合する 95 | } 96 | int delvert = tri::Clean::RemoveUnreferencedVertex(mesh); 97 | if(delvert>0 || dup>0){ 98 | tri::Allocator::CompactFaceVector(mesh); 99 | tri::Allocator::CompactVertexVector(mesh); 100 | } 101 | return delvert; 102 | } 103 | int deleteRelatedFaceAndVert(CMeshO &mesh){ 104 | // set select flag to faces if there is selected vertex 105 | tri::UpdateSelection::FaceClear(mesh); 106 | tri::UpdateSelection::FaceFromVertexLoose(mesh); 107 | 108 | int cnt = setDeleteFlagToSelectedFaceVert(mesh); 109 | if(cnt>0){ 110 | // delete elements which have delete flag 111 | tri::Allocator::CompactEveryVector(mesh); 112 | tri::UpdateTopology::FaceFace(mesh); 113 | tri::UpdateTopology::VertexFace(mesh); 114 | } 115 | return cnt; 116 | } 117 | int deleteNonManifold_Vert(CMeshO &mesh){ 118 | int ret = 0; 119 | int cnt = tri::Clean::CountNonManifoldVertexFF(mesh, true); // Select non manifold vertices 120 | if(cnt>0){ 121 | ret = deleteRelatedFaceAndVert(mesh); 122 | } 123 | return ret; 124 | } 125 | int deleteNonManifold_Edge(CMeshO &mesh){ 126 | int ret = 0; 127 | int cnt = tri::Clean::CountNonManifoldEdgeFF(mesh, true); // Select faces and vertices with non manifold edges 128 | if(cnt>0){ 129 | ret = deleteRelatedFaceAndVert(mesh); 130 | } 131 | return cnt; 132 | } 133 | 134 | int deleteNonManifold(CMeshO &mesh){ 135 | tri::UpdateTopology::FaceFace(mesh); 136 | tri::UpdateTopology::VertexFace(mesh); 137 | tri::UpdateNormal::PerFace(mesh); 138 | tri::UpdateNormal::NormalizePerFace(mesh); 139 | 140 | int sum=0; 141 | sum += deleteNonManifold_Edge(mesh); // 構造上1回削除すればなくなるはず 142 | 143 | while(1){ // 削除した結果、別の頂点がnon manifoldの状態になる可能性があるためループ処理する 144 | int cnt = deleteNonManifold_Vert(mesh); 145 | sum += cnt; 146 | if(cnt==0){break;} 147 | } 148 | 149 | deleteUnreferencedVert(mesh, false); // 面に所属しなくなった頂点を削除 150 | tri::UpdateBounding::Box(mesh); 151 | if(mesh.fn>0) { 152 | tri::UpdateNormal::PerFaceNormalized(mesh); 153 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 154 | } 155 | return sum; 156 | } 157 | 158 | deleteNonManifold(mesh); 159 | ``` 160 | 161 | この方法だとメッシュに穴が開くこともあることに注意。 162 | 163 | -------------------------------------------------------------------------------- /samples/curvature/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | using namespace vcg; 11 | using namespace std; 12 | 13 | int deleteNonManifold(CMeshO &mesh); 14 | 15 | bool isNonManifold(CMeshO &mesh){ 16 | int cnt = 0; 17 | cnt += tri::Clean::CountNonManifoldVertexFF(mesh, false); 18 | cnt += tri::Clean::CountNonManifoldEdgeFF(mesh, false); 19 | return cnt>0; 20 | } 21 | 22 | int setDeleteFlagToSelectedFaceVert(CMeshO &mesh){ 23 | int vvn = mesh.vn; 24 | int ffn = mesh.fn; 25 | for (CMeshO::FaceIterator fi = mesh.face.begin(); fi != mesh.face.end(); ++fi) 26 | if (!(*fi).IsD() && (*fi).IsS()) 27 | tri::Allocator::DeleteFace(mesh, *fi); 28 | for (CMeshO::VertexIterator vi = mesh.vert.begin(); vi != mesh.vert.end(); ++vi) 29 | if (!(*vi).IsD() && (*vi).IsS()) 30 | tri::Allocator::DeleteVertex(mesh, *vi); 31 | return vvn - mesh.vn + ffn - mesh.fn; 32 | } 33 | 34 | int deleteUnreferencedVert(CMeshO &mesh, bool delDuplicate){ 35 | int dup = 0; 36 | if(delDuplicate){ 37 | dup = tri::Clean::RemoveDuplicateVertex(mesh); // STLとかの頂点が重複定義されるものは統合する 38 | } 39 | int delvert = tri::Clean::RemoveUnreferencedVertex(mesh); 40 | if(delvert>0 || dup>0){ 41 | tri::Allocator::CompactFaceVector(mesh); 42 | tri::Allocator::CompactVertexVector(mesh); 43 | } 44 | return delvert; 45 | } 46 | int deleteRelatedFaceAndVert(CMeshO &mesh){ 47 | // set select flag to faces if there is selected vertex 48 | tri::UpdateSelection::FaceClear(mesh); 49 | tri::UpdateSelection::FaceFromVertexLoose(mesh); 50 | 51 | int cnt = setDeleteFlagToSelectedFaceVert(mesh); 52 | if(cnt>0){ 53 | // delete elements which have delete flag 54 | tri::Allocator::CompactEveryVector(mesh); 55 | tri::UpdateTopology::FaceFace(mesh); 56 | tri::UpdateTopology::VertexFace(mesh); 57 | } 58 | return cnt; 59 | } 60 | int deleteNonManifold_Vert(CMeshO &mesh){ 61 | int ret = 0; 62 | int cnt = tri::Clean::CountNonManifoldVertexFF(mesh, true); // Select non manifold vertices 63 | if(cnt>0){ 64 | ret = deleteRelatedFaceAndVert(mesh); 65 | } 66 | return ret; 67 | } 68 | int deleteNonManifold_Edge(CMeshO &mesh){ 69 | int ret = 0; 70 | int cnt = tri::Clean::CountNonManifoldEdgeFF(mesh, true); // Select faces and vertices with non manifold edges 71 | if(cnt>0){ 72 | ret = deleteRelatedFaceAndVert(mesh); 73 | } 74 | return cnt; 75 | } 76 | 77 | int deleteNonManifold(CMeshO &mesh){ 78 | tri::UpdateTopology::FaceFace(mesh); 79 | tri::UpdateTopology::VertexFace(mesh); 80 | tri::UpdateNormal::PerFace(mesh); 81 | tri::UpdateNormal::NormalizePerFace(mesh); 82 | 83 | int sum=0; 84 | sum += deleteNonManifold_Edge(mesh); // 構造上1回削除すればなくなるはず 85 | 86 | while(1){ // 削除した結果、別の頂点がnon manifoldの状態になる可能性があるためループ処理する 87 | int cnt = deleteNonManifold_Vert(mesh); 88 | sum += cnt; 89 | if(cnt==0){break;} 90 | } 91 | 92 | deleteUnreferencedVert(mesh, false); // 面に所属しなくなった頂点を削除 93 | tri::UpdateBounding::Box(mesh); 94 | if(mesh.fn>0) { 95 | tri::UpdateNormal::PerFaceNormalized(mesh); 96 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 97 | } 98 | return sum; 99 | } 100 | 101 | void set_color_by_Q_value(CMeshO &mesh){ 102 | tri::UpdateColor::PerVertexQualityRamp(mesh); 103 | } 104 | 105 | bool calc_min_curvature(CMeshO &mesh){ 106 | mesh.vert.EnableVFAdjacency(); 107 | mesh.face.EnableFFAdjacency(); 108 | mesh.face.EnableVFAdjacency(); 109 | mesh.vert.EnableCurvature(); 110 | mesh.vert.EnableCurvatureDir(); 111 | 112 | // delete invalid vertices and faces 113 | // compactVert(mesh); 114 | 115 | // calc normal 116 | tri::UpdateTopology::FaceFace(mesh); 117 | tri::UpdateTopology::VertexFace(mesh); 118 | // calc curvature 119 | tri::UpdateCurvature::MeanAndGaussian(mesh); 120 | for(CMeshO::VertexIterator vi=mesh.vert.begin(); vi!=mesh.vert.end(); ++vi){ 121 | CMeshO::VertexType *pv = &*vi; 122 | float H = pv->Kh(); 123 | float G = pv->Kg(); 124 | float a = std::max(0.f, H*H-G); // h^2-gは手法によっては負になる場合があるので0でmaxとる 125 | MESHLAB_SCALAR sq = sqrt(a); 126 | pv->Q() = H-sq; // minimum curvature 127 | //pv->Q() = H+sq; // maximum curvature 128 | } 129 | std::pair curv_minmax = tri::Stat::ComputePerVertexQualityMinMax(mesh); 130 | float curv_min = curv_minmax.first; 131 | float curv_max = curv_minmax.second; 132 | printf("curvature min,max = (%f, %f)\n", curv_min, curv_max); 133 | tri::UpdateColor::PerVertexQualityRamp(mesh, curv_min, curv_max); 134 | 135 | //set_color_by_Q_value(mesh); 136 | return true; 137 | } 138 | 139 | int main(int argc, char ** argv){ 140 | CMeshO mesh; 141 | 142 | if(argc<2){ 143 | cout << "add filename" << endl; 144 | return 0; 145 | } 146 | 147 | int err = tri::io::Importer::Open(mesh, argv[1]); 148 | if (err) { // all the importers return 0 in case of success 149 | printf("Error in reading %s: '%s'\n", argv[1], tri::io::Importer::ErrorMsg(err)); 150 | exit(-1); 151 | } 152 | 153 | calc_min_curvature(mesh); 154 | 155 | int result; 156 | bool bBinary = false; 157 | result = tri::io::ExporterPLY::Save(mesh,"out.ply",tri::io::Mask::IOM_VERTCOLOR, bBinary); 158 | printf("result ply: %d\n", result); 159 | return 1; 160 | } 161 | 162 | -------------------------------------------------------------------------------- /samples/dist_point_line/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${EIGEN3_INCLUDE_DIR} 37 | ${VCGLIB_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/dist_point_line/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | 6 | using namespace vcg; 7 | using namespace std; 8 | 9 | int main(){ 10 | Point3f A0(0,0,0), A1(10,0,0); 11 | vcg::Line3f line(A0, A1-A0); 12 | 13 | Point3f p(20,10,0); 14 | 15 | Point3f B = line.ClosestPoint(p); 16 | float a = vcg::Distance(line, p); 17 | 18 | printf("(%f,%f,%f)\n", B.X(), B.Y(), B.Z()); 19 | cout << a << endl; 20 | 21 | return 1; 22 | } 23 | ``` 24 | 25 | 26 | 27 | ## output 28 | 29 | ```shell 30 | (20.000000,0.000000,0.000000) 31 | 10 32 | ``` 33 | 34 | -------------------------------------------------------------------------------- /samples/dist_point_line/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | int main(){ 7 | Point3f A0(0,0,0), A1(10,0,0); 8 | vcg::Line3f line(A0, A1-A0); 9 | 10 | Point3f p(20,10,0); 11 | 12 | Point3f B = line.ClosestPoint(p); 13 | float a = vcg::Distance(line, p); 14 | 15 | printf("(%f,%f,%f)\n", B.X(), B.Y(), B.Z()); 16 | cout << a << endl; 17 | 18 | return 1; 19 | } 20 | -------------------------------------------------------------------------------- /samples/dist_point_plane/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${EIGEN3_INCLUDE_DIR} 37 | ${VCGLIB_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/dist_point_plane/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | 6 | using namespace vcg; 7 | using namespace std; 8 | 9 | int main(){ 10 | Plane3f plate; 11 | 12 | Point3f a(0,0,0),b(10,0,0),c(0,10,0); 13 | plate.Init(a,b,c); 14 | 15 | Point3f p(20,20,20); 16 | Point3f q = plate.Projection(p); 17 | float l = SignedDistancePlanePoint(plate, p); 18 | 19 | printf("(%f,%f,%f)\n", q.X(), q.Y(), q.Z()); 20 | cout << l << endl; 21 | 22 | return 1; 23 | } 24 | ``` 25 | 26 | 27 | 28 | ## output 29 | 30 | ```shell 31 | (20.000000,20.000000,0.000000) 32 | -20 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /samples/dist_point_plane/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | int main(){ 7 | Plane3f plate; 8 | 9 | Point3f a(0,0,0),b(10,0,0),c(0,10,0); 10 | plate.Init(a,b,c); 11 | 12 | Point3f p(20,20,20); 13 | Point3f q = plate.Projection(p); 14 | float l = SignedDistancePlanePoint(plate, p); 15 | 16 | printf("(%f,%f,%f)\n", q.X(), q.Y(), q.Z()); 17 | cout << l << endl; 18 | 19 | return 1; 20 | } 21 | -------------------------------------------------------------------------------- /samples/dist_two_points/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/dist_two_points/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | 6 | using namespace vcg; 7 | using namespace std; 8 | 9 | int main(){ 10 | Point3f a(0,0,0), b(1,1,0); 11 | 12 | float l2 = vcg::SquaredDistance(a, b); // 二乗距離 13 | float l = vcg::Distance(a, b); 14 | 15 | cout << l2 << endl; 16 | cout << l << endl; 17 | 18 | return 1; 19 | } 20 | ``` 21 | 22 | 23 | 24 | ## output 25 | 26 | ```shell 27 | 2 28 | 1.41421 29 | ``` 30 | 31 | -------------------------------------------------------------------------------- /samples/dist_two_points/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | int main(){ 7 | Point3f a(0,0,0), b(1,1,0); 8 | 9 | float l2 = vcg::SquaredDistance(a, b); // 二乗距離 10 | float l = vcg::Distance(a, b); 11 | 12 | cout << l2 << endl; 13 | cout << l << endl; 14 | 15 | return 1; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /samples/expand_select/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/expand_select/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | `FaceConnectedFF` expand current selection to cover the whole connected component. 4 | 5 | ```cpp 6 | tri::UpdateSelection::FaceConnectedFF(mesh); 7 | ``` 8 | 9 | 10 | 11 | Select all the vertices that are touched by at least a single selected faces 12 | 13 | ``` 14 | cnt = tri::UpdateSelection::VertexFromFaceLoose(mesh); 15 | ``` 16 | 17 | 18 | 19 | Select ONLY the vertices that are touched ONLY by selected faces 20 | 21 | ```cpp 22 | cnt = tri::UpdateSelection::VertexFromFaceStrict(mesh); 23 | ``` 24 | 25 | 26 | 27 | Select all the faces with at least one selected vertex 28 | 29 | ```cpp 30 | cnt = tri::UpdateSelection::FaceFromVertexLoose(mesh); 31 | ``` 32 | 33 | 34 | 35 | Select ONLY the faces with ALL the vertices selected 36 | 37 | ```cpp 38 | cnt = tri::UpdateSelection::FaceFromVertexStrict(mesh); 39 | ``` 40 | 41 | 42 | 43 | ## output 44 | 45 | ```shell 46 | 0 47 | 1 48 | 2 49 | 3 50 | VertexFromFaceLoose: 3 51 | VertexFromFaceStrict: 1 52 | FaceFromVertexLoose: 3 53 | FaceFromVertexStrict: 1 54 | ``` 55 | 56 | -------------------------------------------------------------------------------- /samples/expand_select/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | CMeshO mesh; 10 | mesh.vert.EnableVFAdjacency(); 11 | mesh.face.EnableFFAdjacency(); 12 | mesh.face.EnableVFAdjacency(); 13 | 14 | tri::Tetrahedron(mesh); // create preset mesh data 15 | 16 | // you have to update adjacent relation after loading data 17 | tri::UpdateTopology::FaceFace(mesh); 18 | tri::UpdateTopology::VertexFace(mesh); 19 | 20 | // Recursively select faces that are connected to the selected faces 21 | mesh.face[0].SetS(); 22 | tri::UpdateSelection::FaceConnectedFF(mesh); 23 | for(auto &&f:mesh.face) 24 | if(f.IsS()) 25 | cout << f.Index() << endl; 26 | 27 | int cnt; 28 | // Select all the vertices that are touched by at least a single selected faces 29 | tri::UpdateFlags::Clear(mesh); 30 | mesh.face[0].SetS(); 31 | cnt = tri::UpdateSelection::VertexFromFaceLoose(mesh); 32 | cout << "VertexFromFaceLoose: " << cnt << endl; 33 | 34 | // Select ONLY the vertices that are touched ONLY by selected faces 35 | tri::UpdateFlags::Clear(mesh); 36 | mesh.face[0].SetS(); 37 | mesh.face[1].SetS(); 38 | mesh.face[2].SetS(); 39 | cnt = tri::UpdateSelection::VertexFromFaceStrict(mesh); 40 | cout << "VertexFromFaceStrict: " << cnt << endl; 41 | 42 | // Select all the faces with at least one selected vertex 43 | tri::UpdateFlags::Clear(mesh); 44 | mesh.vert[0].SetS(); 45 | cnt = tri::UpdateSelection::FaceFromVertexLoose(mesh); 46 | cout << "FaceFromVertexLoose: " << cnt << endl; 47 | 48 | // Select ONLY the faces with ALL the vertices selected 49 | tri::UpdateFlags::Clear(mesh); 50 | mesh.vert[0].SetS(); 51 | mesh.vert[1].SetS(); 52 | mesh.vert[2].SetS(); 53 | cnt = tri::UpdateSelection::FaceFromVertexStrict(mesh); 54 | cout << "FaceFromVertexStrict: " << cnt << endl; 55 | 56 | return 1; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /samples/flags/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${EIGEN3_INCLUDE_DIR} 37 | ${VCGLIB_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/flags/README.md: -------------------------------------------------------------------------------- 1 | Reference : http://vcg.isti.cnr.it/vcglib/flags.html 2 | 3 | 4 | 5 | ```cpp 6 | // set selected flag manually 7 | MyMesh::VertexPointer vp; 8 | vp = &(mesh.vert[0]); 9 | vp->SetS(); 10 | vp = &(mesh.vert[2]); 11 | vp->SetS(); 12 | 13 | // get all selected flag state 14 | MyMesh::VertexIterator vi; 15 | for(auto &&vi : mesh.vert){ 16 | cout << vi.IsS() << endl; 17 | } 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /samples/flags/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | class MyFace; 7 | class MyVertex; 8 | 9 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 10 | class MyVertex : public Vertex< MyUsedTypes, 11 | vertex::Coord3f, 12 | vertex::Normal3f, 13 | vertex::BitFlags, 14 | vertex::VFAdj 15 | > {}; 16 | class MyFace : public Face< MyUsedTypes, 17 | face::VertexRef, 18 | face::Normal3f, 19 | face::VFAdj, 20 | face::BitFlags 21 | > {}; 22 | class MyMesh : public tri::TriMesh< 23 | vector, 24 | vector 25 | > {}; 26 | 27 | int main(){ 28 | MyMesh mesh; 29 | vcg::tri::Tetrahedron(mesh); // create preset mesh data 30 | 31 | cout << "vert" << endl; 32 | // set selected flag manually 33 | MyMesh::VertexPointer vp; 34 | vp = &(mesh.vert[0]); 35 | vp->SetS(); 36 | vp = &(mesh.vert[2]); 37 | vp->SetS(); 38 | 39 | // get all selected flag state 40 | MyMesh::VertexIterator vi; 41 | for(auto &&vi : mesh.vert){ 42 | cout << vi.IsS() << endl; 43 | } 44 | 45 | // clear all select flag 46 | tri::UpdateFlags::VertexClearS(mesh); 47 | 48 | cout << "face" << endl; 49 | // set selected flag manually 50 | MyMesh::FacePointer fp; 51 | fp = &(mesh.face[0]); 52 | fp->SetS(); 53 | 54 | // get all selected flag state 55 | MyMesh::FaceIterator fi; 56 | for(auto &&fi : mesh.face){ 57 | cout << fi.IsS() << endl; 58 | } 59 | 60 | // clear all select flag 61 | tri::UpdateFlags::FaceClearS(mesh); 62 | 63 | return 1; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /samples/hello_mesh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | # If you use visual studio, set the character code to UTF8 9 | add_compile_options("$<$:/utf-8>") 10 | 11 | # In debug mode, add 'd' to the end of the executable file name 12 | if(NOT CMAKE_DEBUG_POSTFIX) 13 | set(CMAKE_DEBUG_POSTFIX d) 14 | endif() 15 | 16 | # set output file directory 17 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 18 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 19 | 20 | # define path of Eigen 21 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 22 | # define path of vcglib 23 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 24 | 25 | # Add Executable 26 | add_executable(${PROJECT_NAME}) 27 | target_sources(${PROJECT_NAME} 28 | PRIVATE 29 | main.cpp 30 | ) 31 | target_include_directories(${PROJECT_NAME} 32 | PUBLIC 33 | ${EIGEN3_INCLUDE_DIR} 34 | ${VCGLIB_DIR} 35 | ) 36 | 37 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 38 | -------------------------------------------------------------------------------- /samples/hello_mesh/README.md: -------------------------------------------------------------------------------- 1 | # hello_mesh 2 | 3 | CMakeLists.txt 4 | 5 | - target_include_directories : set the proper path for Eigen and vcglib 6 | 7 | ```cmake 8 | cmake_minimum_required( VERSION 3.6 ) 9 | 10 | # Create Project 11 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 12 | string(REPLACE " " "_" ProjectId ${ProjectId}) 13 | project(${ProjectId} CXX) 14 | 15 | message(${ProjectId}) 16 | 17 | # If you use visual studio, set the character code to UTF8 18 | add_compile_options("$<$:/utf-8>") 19 | 20 | # In debug mode, add 'd' to the end of the executable file name 21 | if(NOT CMAKE_DEBUG_POSTFIX) 22 | set(CMAKE_DEBUG_POSTFIX d) 23 | endif() 24 | 25 | # set output file directory 26 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 27 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 28 | 29 | # Add Executable 30 | add_executable(${PROJECT_NAME}) 31 | target_sources(${PROJECT_NAME} 32 | PRIVATE 33 | main.cpp 34 | ) 35 | target_include_directories(${PROJECT_NAME} 36 | PUBLIC 37 | C:/Users/Public/Documents/GitHub/vcglib 38 | C:/eigen-3.3.7 39 | ) 40 | 41 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 42 | ``` 43 | 44 | main.cpp 45 | 46 | - In vcglib, data types such as vertices and faces are defined by yourself ([Reference](http://vcg.isti.cnr.it/vcglib/basic_concepts.html)) 47 | 48 | ```cpp 49 | #include 50 | #include 51 | 52 | class MyFace; 53 | class MyVertex; 54 | 55 | struct MyUsedTypes : public vcg::UsedTypes< vcg::Use::AsVertexType, vcg::Use::AsFaceType> {}; 56 | class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::BitFlags, vcg::vertex::VFAdj> {}; 57 | class MyFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::VFAdj> {}; 58 | class MyMesh : public vcg::tri::TriMesh, vector > {}; 59 | 60 | int main(){ 61 | MyMesh mesh; 62 | vcg::tri::Octahedron(mesh); // create preset mesh data 63 | 64 | MyMesh::FaceIterator fi; 65 | for(fi=mesh.face.begin(); fi!=mesh.face.end(); ++fi){ // iterate each faces 66 | std::cout << vcg::tri::Index(mesh, *fi) << ": "; // get face index 67 | for(int i=0; iVN(); ++i){ // iterate each vertex of face 68 | std::cout << vcg::tri::Index(mesh, fi->V(i)) << ","; // get vertex index 69 | } 70 | std::cout << std::endl; 71 | } 72 | return 1; 73 | } 74 | ``` 75 | 76 | # build 77 | 78 | ## MinGW 79 | 80 | ```shell 81 | $ cmake .. -G"MinGW Makefiles" 82 | -- The CXX compiler identification is GNU 9.2.0 83 | -- Check for working CXX compiler: C:/MinGW/bin/g++.exe 84 | -- Check for working CXX compiler: C:/MinGW/bin/g++.exe -- works 85 | -- Detecting CXX compiler ABI info 86 | -- Detecting CXX compiler ABI info - done 87 | -- Detecting CXX compile features 88 | -- Detecting CXX compile features - done 89 | hello_mesh 90 | -- Configuring done 91 | -- Generating done 92 | -- Build files have been written to: C:/Users/Public/Documents/GitHub/vcglib_samples/samples/hello_mesh/build 93 | 94 | $ cmake --build . --config release 95 | Scanning dependencies of target hello_mesh 96 | [ 50%] Building CXX object CMakeFiles/hello_mesh.dir/main.cpp.obj 97 | [100%] Linking CXX executable hello_mesh.exe 98 | [100%] Built target hello_mesh 99 | 100 | $ hello_mesh.exe 101 | 0: 0,1,2, 102 | 1: 0,2,4, 103 | 2: 0,4,5, 104 | 3: 0,5,1, 105 | 4: 3,1,5, 106 | 5: 3,5,4, 107 | 6: 3,4,2, 108 | 7: 3,2,1, 109 | ``` 110 | 111 | ## Visual Studio 2017 112 | 113 | ```shell 114 | $ cmake .. -G"Visual Studio 15 2017 Win64" -DCMAKE_CXX_FLAGS="/utf-8 /EHsc" 115 | -- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.19041. 116 | -- The CXX compiler identification is MSVC 19.16.27042.0 117 | -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe 118 | -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- works 119 | -- Detecting CXX compiler ABI info 120 | -- Detecting CXX compiler ABI info - done 121 | -- Detecting CXX compile features 122 | -- Detecting CXX compile features - done 123 | hello_mesh 124 | -- Configuring done 125 | -- Generating done 126 | -- Build files have been written to: C:/Users/Public/Documents/GitHub/vcglib_samples/samples/hello_mesh/build 127 | 128 | $ cmake --build . --config release 129 | .NET Framework 向け Microsoft (R) Build Engine バージョン 15.9.21+g9802d43bc3 130 | Copyright (C) Microsoft Corporation.All rights reserved. 131 | 132 | Checking Build System 133 | Building Custom Rule C:/Users/Public/Documents/GitHub/vcglib_samples/samples/hello_mesh/CMakeLists.txt 134 | main.cpp 135 | hello_mesh.vcxproj -> C:\Users\Public\Documents\GitHub\vcglib_samples\samples\hello_mesh\build\Release\hello_mesh.exe 136 | Building Custom Rule C:/Users/Public/Documents/GitHub/vcglib_samples/samples/hello_mesh/CMakeLists.txt 137 | 138 | $ Release\hello_mesh.exe 139 | 0: 0,1,2, 140 | 1: 0,2,4, 141 | 2: 0,4,5, 142 | 3: 0,5,1, 143 | 4: 3,1,5, 144 | 5: 3,5,4, 145 | 6: 3,4,2, 146 | 7: 3,2,1, 147 | ``` 148 | 149 | -------------------------------------------------------------------------------- /samples/hello_mesh/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class MyFace; 5 | class MyVertex; 6 | 7 | struct MyUsedTypes : public vcg::UsedTypes< vcg::Use::AsVertexType, vcg::Use::AsFaceType> {}; 8 | class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::BitFlags, vcg::vertex::VFAdj> {}; 9 | class MyFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::VFAdj> {}; 10 | class MyMesh : public vcg::tri::TriMesh, vector > {}; 11 | 12 | int main(){ 13 | MyMesh mesh; 14 | vcg::tri::Octahedron(mesh); // create preset mesh data 15 | 16 | MyMesh::FaceIterator fi; 17 | for(fi=mesh.face.begin(); fi!=mesh.face.end(); ++fi){ // iterate each faces 18 | std::cout << vcg::tri::Index(mesh, *fi) << ": "; // get face index 19 | for(int i=0; iVN(); ++i){ // iterate each vertex of face 20 | std::cout << vcg::tri::Index(mesh, fi->V(i)) << ","; // get vertex index 21 | } 22 | std::cout << std::endl; 23 | } 24 | return 1; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /samples/iterator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${EIGEN3_INCLUDE_DIR} 37 | ${VCGLIB_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/iterator/README.md: -------------------------------------------------------------------------------- 1 | ```cpp 2 | // Access to face and vertex via iterator 3 | cout << "iterator" << endl; 4 | MyMesh::FaceIterator fi; 5 | for(fi=mesh.face.begin(); fi!=mesh.face.end(); ++fi){ // iterate each faces 6 | cout << "face : " << tri::Index(mesh, *fi) << endl; // get face index 7 | } 8 | MyMesh::VertexIterator vi; 9 | for(vi=mesh.vert.begin(); vi!=mesh.vert.end(); ++vi){ 10 | cout << "vert : " << tri::Index(mesh, *vi) << endl; 11 | } 12 | 13 | // via pointer 14 | cout << "pointer" << endl; 15 | MyMesh::FacePointer fp; 16 | for(int i=0; i 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | class MyFace; 7 | class MyVertex; 8 | 9 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 10 | class MyVertex : public Vertex< MyUsedTypes, 11 | vertex::Coord3f, 12 | vertex::Normal3f, 13 | vertex::BitFlags, 14 | vertex::VFAdj 15 | > {}; 16 | class MyFace : public Face< MyUsedTypes, 17 | face::VertexRef, 18 | face::Normal3f, 19 | face::VFAdj, 20 | face::BitFlags 21 | > {}; 22 | class MyMesh : public tri::TriMesh< 23 | vector, 24 | vector 25 | > {}; 26 | 27 | int main(){ 28 | MyMesh mesh; 29 | tri::Tetrahedron(mesh); // create preset mesh data 30 | 31 | // Access to face and vertex via iterator 32 | cout << "iterator" << endl; 33 | MyMesh::FaceIterator fi; 34 | for(fi=mesh.face.begin(); fi!=mesh.face.end(); ++fi){ // iterate each faces 35 | cout << "face : " << tri::Index(mesh, *fi) << endl; // get face index 36 | // cout << fi->P(0).X() << endl; // get point 37 | } 38 | MyMesh::VertexIterator vi; 39 | for(vi=mesh.vert.begin(); vi!=mesh.vert.end(); ++vi){ 40 | cout << "vert : " << tri::Index(mesh, *vi) << endl; 41 | // cout << vi->P().X() << endl; // get point 42 | } 43 | 44 | // via pointer 45 | cout << "pointer" << endl; 46 | MyMesh::FacePointer fp; 47 | for(int i=0; i:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/matrix_with_eigen/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace vcg; 9 | using namespace std; 10 | 11 | template 12 | using RMatrix = Eigen::Matrix; 13 | typedef RMatrix RMatrixm; 14 | using RefRMatrix = Eigen::Ref; 15 | using EVector = Eigen::Vector3f; 16 | 17 | int main(){ 18 | Matrix44m M; 19 | RMatrixm eigenM = RMatrixm::Identity(4,4); // set matrix size 20 | M.ToEigenMatrix(eigenM); 21 | cout << eigenM << endl; 22 | 23 | RMatrix em = RMatrix::Ones(4,4);; 24 | M.FromEigenMatrix>(em); 25 | return 1; 26 | } 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /samples/matrix_with_eigen/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | template 9 | using RMatrix = Eigen::Matrix; 10 | typedef RMatrix RMatrixm; 11 | using RefRMatrix = Eigen::Ref; 12 | using EVector = Eigen::Vector3f; 13 | 14 | int main(){ 15 | Matrix44m M; 16 | RMatrixm eigenM = RMatrixm::Identity(4,4); // set matrix size 17 | M.ToEigenMatrix(eigenM); 18 | cout << eigenM << endl; 19 | 20 | RMatrix em = RMatrix::Ones(4,4);; 21 | M.FromEigenMatrix>(em); 22 | return 1; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /samples/ply_with_vert_value/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/ply_with_vert_value/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | using namespace vcg; 12 | using namespace std; 13 | 14 | int main(){ 15 | CMeshO mesh; 16 | tri::Tetrahedron(mesh); // create preset mesh data 17 | 18 | mesh.vert[0].Q() = 0.1; 19 | mesh.vert[1].Q() = -2.0; 20 | mesh.vert[2].Q() = 100.0; 21 | 22 | for(auto &&vp:mesh.vert) 23 | cout << vp.Q() << endl; 24 | 25 | auto flags = tri::io::Mask::IOM_VERTCOLOR| 26 | tri::io::Mask::IOM_VERTQUALITY; 27 | bool bBinary = false; 28 | int result = tri::io::ExporterPLY::Save(mesh, "out.ply", flags, bBinary); 29 | if(result == ply::PlyError::E_NOERROR){ 30 | return 1; 31 | }else{ 32 | cout << "save error" << endl; 33 | return 0; 34 | } 35 | } 36 | ``` 37 | 38 | 39 | 40 | ## output 41 | 42 | ```shell 43 | 0.1 44 | -2 45 | 100 46 | 0 47 | ``` 48 | 49 | 50 | 51 | ## out.ply 52 | 53 | ``` 54 | ply 55 | format ascii 1.0 56 | comment VCGLIB generated 57 | element vertex 4 58 | property float x 59 | property float y 60 | property float z 61 | property uchar red 62 | property uchar green 63 | property uchar blue 64 | property uchar alpha 65 | property float quality 66 | element face 4 67 | property list uchar int vertex_indices 68 | end_header 69 | 1 1 1 255 255 255 255 0.1 70 | -1 1 -1 255 255 255 255 -2 71 | -1 -1 1 255 255 255 255 100 72 | 1 -1 -1 255 255 255 255 0 73 | 3 0 1 2 74 | 3 0 2 3 75 | 3 0 3 1 76 | 3 3 2 1 77 | ``` 78 | 79 | -------------------------------------------------------------------------------- /samples/ply_with_vert_value/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | using namespace vcg; 9 | using namespace std; 10 | 11 | int main(){ 12 | CMeshO mesh; 13 | tri::Tetrahedron(mesh); // create preset mesh data 14 | 15 | mesh.vert[0].Q() = 0.1; 16 | mesh.vert[1].Q() = -2.0; 17 | mesh.vert[2].Q() = 100.0; 18 | 19 | for(auto &&vp:mesh.vert) 20 | cout << vp.Q() << endl; 21 | 22 | auto flags = tri::io::Mask::IOM_VERTCOLOR| 23 | tri::io::Mask::IOM_VERTQUALITY; 24 | bool bBinary = false; 25 | int result = tri::io::ExporterPLY::Save(mesh, "out.ply", flags, bBinary); 26 | if(result == ply::PlyError::E_NOERROR){ 27 | return 1; 28 | }else{ 29 | cout << "save error" << endl; 30 | return 0; 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /samples/quaternion/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/quaternion/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace vcg; 9 | using namespace std; 10 | 11 | int main(){ 12 | { 13 | Point3m p(10,10,10); 14 | Point3m z(0,0,10); 15 | 16 | // Quaternion that rotates 90 degrees around the vector z direction (rotation is centered on the origin) 17 | Quaternionf qua(math::ToRad(90.0f),z); 18 | Point3m q = qua.Rotate(p); 19 | printf("(%f,%f,%f)\n", q.X(),q.Y(),q.Z()); 20 | } 21 | 22 | // Superposing vector A on vector B 23 | { 24 | Point3m A(10,10,10), B(-10,0,0); 25 | Quaternionf atob(Angle(A,B),A^B); 26 | Point3m C = atob.Rotate(A); 27 | printf("(%f,%f,%f)\n", C.X(),C.Y(),C.Z()); 28 | } 29 | return 1; 30 | } 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /samples/quaternion/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | { 10 | Point3m p(10,10,10); 11 | Point3m z(0,0,10); 12 | 13 | // Quaternion that rotates 90 degrees around the vector z direction (rotation is centered on the origin) 14 | Quaternionf qua(math::ToRad(90.0f),z); 15 | Point3m q = qua.Rotate(p); 16 | printf("(%f,%f,%f)\n", q.X(),q.Y(),q.Z()); 17 | } 18 | 19 | // Superposing vector A on vector B 20 | { 21 | Point3m A(10,10,10), B(-10,0,0); 22 | Quaternionf atob(Angle(A,B),A^B); 23 | Point3m C = atob.Rotate(A); 24 | printf("(%f,%f,%f)\n", C.X(),C.Y(),C.Z()); 25 | } 26 | return 1; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /samples/read_write_file/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${EIGEN3_INCLUDE_DIR} 37 | ${VCGLIB_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/read_write_file/README.md: -------------------------------------------------------------------------------- 1 | Reference : http://vcg.isti.cnr.it/vcglib/fileformat.html 2 | 3 | [By default the following formats are supported for reading:](https://github.com/cnr-isti-vclab/vcglib/blob/devel/wrap/io_trimesh/import.h#L115) 4 | 5 | - PLY 6 | - STL 7 | - OFF 8 | - OBJ 9 | - VMI 10 | 11 | If you want to read other files, refer to the source file of [each format](https://github.com/cnr-isti-vclab/vcglib/tree/devel/wrap/io_trimesh). 12 | 13 | 14 | 15 | if you use ply file format, you have to add cpp file In CMakeLists.txt like below 16 | 17 | ```cmake 18 | target_sources(${PROJECT_NAME} 19 | PRIVATE 20 | main.cpp 21 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp 22 | ) 23 | ``` 24 | 25 | 26 | 27 | And also you have to add some attribute to data structure like below 28 | 29 | ```cpp 30 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 31 | class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::VFAdj> {}; // need BitFlags, VFAdj 32 | class MyFace : public Face< MyUsedTypes, face::VertexRef, face::VFAdj, face::BitFlags> {}; // need BitFlags, VFAdj 33 | class MyMesh : public tri::TriMesh, vector > {}; 34 | ``` 35 | 36 | 37 | 38 | If you forget this, you will get error message like this, 39 | 40 | ```shell 41 | Missing Component Exception -PerVertexFlags - 42 | terminate called after throwing an instance of 'vcg::MissingComponentException' 43 | what(): Missing Component 44 | ``` 45 | 46 | 47 | 48 | # Result sample 49 | 50 | ```shell 51 | $ read_write_file.exe ..\..\..\sample_data\octahedron.obj 52 | Removed 0 duplicate and 0 unreferenced vertices from mesh ..\..\..\sample_data\octahedron.obj 53 | face num : 8 54 | vert num : 6 55 | result ply: 0 56 | result stl: 0 57 | ``` -------------------------------------------------------------------------------- /samples/read_write_file/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace vcg; 10 | using namespace std; 11 | 12 | class MyFace; 13 | class MyVertex; 14 | 15 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 16 | class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::VFAdj> {}; // need BitFlags, VFAdj 17 | class MyFace : public Face< MyUsedTypes, face::VertexRef, face::VFAdj, face::BitFlags> {}; // need BitFlags, VFAdj 18 | class MyMesh : public tri::TriMesh, vector > {}; 19 | 20 | int main(int argc, char ** argv) 21 | { 22 | if (argc < 2){ 23 | printf("Usage: \n"); 24 | return 0; 25 | } 26 | MyMesh m; 27 | 28 | //open a mesh 29 | int err = tri::io::Importer::Open(m, argv[1]); // 多分ライブラリにあるファイルなら何でも開ける 30 | if (err) { // all the importers return 0 in case of success 31 | printf("Error in reading %s: '%s'\n", argv[1], tri::io::Importer::ErrorMsg(err)); 32 | exit(-1); 33 | } 34 | 35 | // some cleaning to get rid of bad file formats like stl that duplicate vertexes.. 36 | int dup = tri::Clean::RemoveDuplicateVertex(m); 37 | int unref = tri::Clean::RemoveUnreferencedVertex(m); 38 | printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n", dup, unref, argv[1]); 39 | 40 | tri::UpdateTopology::VertexFace(m); 41 | 42 | // print number of faces and vertices 43 | cout << "face num : " << m.FN() << endl << "vert num : " << m.VN() << endl; 44 | 45 | // write mesh data as ply format 46 | int result; 47 | bool bBinary = false; 48 | result = tri::io::ExporterPLY::Save(m,"out.ply",tri::io::Mask::IOM_NONE, bBinary); 49 | printf("result ply: %d\n", result); 50 | 51 | // write mesh data as stl format 52 | result = tri::io::ExporterSTL::Save(m,"out.stl"); 53 | printf("result stl: %d\n", result); 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /samples/remove_non_manifold/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/remove_non_manifold/README.md: -------------------------------------------------------------------------------- 1 | # Curvature 2 | 3 | ## Default curvature function 4 | 5 | 曲率計算はvcglibに実装されているものは 6 | 7 | ```cpp 8 | #include 9 | vcg::tri::UpdateCurvature::MeanAndGaussian(mesh); 10 | ``` 11 | 12 | 計算結果は各頂点に平均曲率とガウス曲率が入る。最大・最小曲率を計算したい場合は自分で計算する。 13 | 14 | 以下は最小曲率を各頂点のQ要素に入れている(Q要素はデフォルトで用意されている浮動小数点を保持するメンバ) 15 | 16 | ```cpp 17 | for(CMeshO::VertexIterator vi=mesh.vert.begin(); vi!=mesh.vert.end(); ++vi){ 18 | CMeshO::VertexType *pv = &*vi; 19 | float H = pv->Kh(); 20 | float G = pv->Kg(); 21 | float a = std::max(0.f, H*H-G); // h^2-gは手法によっては負になる場合があるので0でmaxとる 22 | MESHLAB_SCALAR sq = sqrt(a); 23 | pv->Q() = H-sq; // minimum curvature 24 | //pv->Q() = H+sq; // maximum curvature 25 | } 26 | ``` 27 | 28 | 曲率に応じて色分けをしたい場合はQ値によって色分けする関数を使用する 29 | 30 | ```cpp 31 | std::pair curv_minmax = vcg::tri::Stat::ComputePerVertexQualityMinMax(mesh); 32 | float curv_min = curv_minmax.first; 33 | float curv_max = curv_minmax.second; 34 | vcg::tri::UpdateColor::PerVertexQualityRamp(mesh, curv_min, curv_max); 35 | ``` 36 | 37 | ## APSS function 38 | 39 | MeshLabには曲率計算の拡張機能が実装されている 40 | 41 | 42 | 43 | ## Preparation for calculating curvature 44 | 45 | メッシュの構造が不正なもの(Non manifold)の状態で曲率を計算するとエラーが起きる。 46 | 47 | この場合は、あらかじめ不正な状態を解消する。 48 | 49 | 不正な状態は以下の関数で検出できる。 50 | 51 | ```cpp 52 | // Non manifoldの検出 53 | #include 54 | 55 | bool isNonManifold(CMeshO &mesh){ 56 | int cnt = 0; 57 | bool select_flag = false; 58 | 59 | // Count the number of non manifold edges in a mesh, e.g. the edges where there are more than 2 incident faces. 60 | // Note that this test is not enough to say that a mesh is two manifold, you have to count also the non manifold vertexes. 61 | cnt += tri::Clean::CountNonManifoldEdgeFF(mesh, select_flag); 62 | 63 | // Count (and eventually select) non 2-Manifold vertexes of a mesh 64 | // typical situation two cones connected by one vertex. 65 | cnt += tri::Clean::CountNonManifoldVertexFF(mesh, select_flag); 66 | return cnt>0; 67 | } 68 | 69 | mesh.vert.EnableVFAdjacency(); 70 | mesh.face.EnableFFAdjacency(); 71 | bool b = isNonManifold(mesh); 72 | ``` 73 | 74 | 75 | 76 | 不正な箇所は手動で修正することもできるが、一番簡単な方法は該当箇所を丸ごと削除してしまうことである。 77 | 78 | ```cpp 79 | int setDeleteFlagToSelectedFaceVert(CMeshO &mesh){ 80 | int vvn = mesh.vn; 81 | int ffn = mesh.fn; 82 | for (CMeshO::FaceIterator fi = mesh.face.begin(); fi != mesh.face.end(); ++fi) 83 | if (!(*fi).IsD() && (*fi).IsS()) 84 | tri::Allocator::DeleteFace(mesh, *fi); 85 | for (CMeshO::VertexIterator vi = mesh.vert.begin(); vi != mesh.vert.end(); ++vi) 86 | if (!(*vi).IsD() && (*vi).IsS()) 87 | tri::Allocator::DeleteVertex(mesh, *vi); 88 | return vvn - mesh.vn + ffn - mesh.fn; 89 | } 90 | 91 | int deleteUnreferencedVert(CMeshO &mesh, bool delDuplicate){ 92 | int dup = 0; 93 | if(delDuplicate){ 94 | dup = tri::Clean::RemoveDuplicateVertex(mesh); // STLとかの頂点が重複定義されるものは統合する 95 | } 96 | int delvert = tri::Clean::RemoveUnreferencedVertex(mesh); 97 | if(delvert>0 || dup>0){ 98 | tri::Allocator::CompactFaceVector(mesh); 99 | tri::Allocator::CompactVertexVector(mesh); 100 | } 101 | return delvert; 102 | } 103 | int deleteRelatedFaceAndVert(CMeshO &mesh){ 104 | // set select flag to faces if there is selected vertex 105 | tri::UpdateSelection::FaceClear(mesh); 106 | tri::UpdateSelection::FaceFromVertexLoose(mesh); 107 | 108 | int cnt = setDeleteFlagToSelectedFaceVert(mesh); 109 | if(cnt>0){ 110 | // delete elements which have delete flag 111 | tri::Allocator::CompactEveryVector(mesh); 112 | tri::UpdateTopology::FaceFace(mesh); 113 | tri::UpdateTopology::VertexFace(mesh); 114 | } 115 | return cnt; 116 | } 117 | int deleteNonManifold_Vert(CMeshO &mesh){ 118 | int ret = 0; 119 | int cnt = tri::Clean::CountNonManifoldVertexFF(mesh, true); // Select non manifold vertices 120 | if(cnt>0){ 121 | ret = deleteRelatedFaceAndVert(mesh); 122 | } 123 | return ret; 124 | } 125 | int deleteNonManifold_Edge(CMeshO &mesh){ 126 | int ret = 0; 127 | int cnt = tri::Clean::CountNonManifoldEdgeFF(mesh, true); // Select faces and vertices with non manifold edges 128 | if(cnt>0){ 129 | ret = deleteRelatedFaceAndVert(mesh); 130 | } 131 | return cnt; 132 | } 133 | 134 | int deleteNonManifold(CMeshO &mesh){ 135 | tri::UpdateTopology::FaceFace(mesh); 136 | tri::UpdateTopology::VertexFace(mesh); 137 | tri::UpdateNormal::PerFace(mesh); 138 | tri::UpdateNormal::NormalizePerFace(mesh); 139 | 140 | int sum=0; 141 | sum += deleteNonManifold_Edge(mesh); // 構造上1回削除すればなくなるはず 142 | 143 | while(1){ // 削除した結果、別の頂点がnon manifoldの状態になる可能性があるためループ処理する 144 | int cnt = deleteNonManifold_Vert(mesh); 145 | sum += cnt; 146 | if(cnt==0){break;} 147 | } 148 | 149 | deleteUnreferencedVert(mesh, false); // 面に所属しなくなった頂点を削除 150 | tri::UpdateBounding::Box(mesh); 151 | if(mesh.fn>0) { 152 | tri::UpdateNormal::PerFaceNormalized(mesh); 153 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 154 | } 155 | return sum; 156 | } 157 | 158 | deleteNonManifold(mesh); 159 | ``` 160 | 161 | この方法だとメッシュに穴が開くこともあることに注意。 162 | 163 | -------------------------------------------------------------------------------- /samples/remove_non_manifold/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | using namespace vcg; 11 | using namespace std; 12 | 13 | bool isNonManifold(CMeshO &mesh){ 14 | int cnt = 0; 15 | cnt += tri::Clean::CountNonManifoldVertexFF(mesh, false); 16 | cnt += tri::Clean::CountNonManifoldEdgeFF(mesh, false); 17 | return cnt>0; 18 | } 19 | 20 | int setDeleteFlagToSelectedFaceVert(CMeshO &mesh){ 21 | int vvn = mesh.vn; 22 | int ffn = mesh.fn; 23 | for (CMeshO::FaceIterator fi = mesh.face.begin(); fi != mesh.face.end(); ++fi) 24 | if (!(*fi).IsD() && (*fi).IsS()) 25 | tri::Allocator::DeleteFace(mesh, *fi); 26 | for (CMeshO::VertexIterator vi = mesh.vert.begin(); vi != mesh.vert.end(); ++vi) 27 | if (!(*vi).IsD() && (*vi).IsS()) 28 | tri::Allocator::DeleteVertex(mesh, *vi); 29 | return vvn - mesh.vn + ffn - mesh.fn; 30 | } 31 | 32 | int deleteUnreferencedVert(CMeshO &mesh, bool delDuplicate){ 33 | int dup = 0; 34 | if(delDuplicate){ 35 | dup = tri::Clean::RemoveDuplicateVertex(mesh); // STLとかの頂点が重複定義されるものは統合する 36 | } 37 | int delvert = tri::Clean::RemoveUnreferencedVertex(mesh); 38 | if(delvert>0 || dup>0){ 39 | tri::Allocator::CompactFaceVector(mesh); 40 | tri::Allocator::CompactVertexVector(mesh); 41 | } 42 | return delvert; 43 | } 44 | int deleteRelatedFaceAndVert(CMeshO &mesh){ 45 | // set select flag to faces if there is selected vertex 46 | tri::UpdateSelection::FaceClear(mesh); 47 | tri::UpdateSelection::FaceFromVertexLoose(mesh); 48 | 49 | int cnt = setDeleteFlagToSelectedFaceVert(mesh); 50 | if(cnt>0){ 51 | // delete elements which have delete flag 52 | tri::Allocator::CompactEveryVector(mesh); 53 | tri::UpdateTopology::FaceFace(mesh); 54 | tri::UpdateTopology::VertexFace(mesh); 55 | } 56 | return cnt; 57 | } 58 | int deleteNonManifold_Vert(CMeshO &mesh){ 59 | int ret = 0; 60 | int cnt = tri::Clean::CountNonManifoldVertexFF(mesh, true); // Select non manifold vertices 61 | if(cnt>0){ 62 | ret = deleteRelatedFaceAndVert(mesh); 63 | } 64 | return ret; 65 | } 66 | int deleteNonManifold_Edge(CMeshO &mesh){ 67 | int ret = 0; 68 | int cnt = tri::Clean::CountNonManifoldEdgeFF(mesh, true); // Select faces and vertices with non manifold edges 69 | if(cnt>0){ 70 | ret = deleteRelatedFaceAndVert(mesh); 71 | } 72 | return cnt; 73 | } 74 | 75 | int deleteNonManifold(CMeshO &mesh){ 76 | tri::UpdateTopology::FaceFace(mesh); 77 | tri::UpdateTopology::VertexFace(mesh); 78 | tri::UpdateNormal::PerFace(mesh); 79 | tri::UpdateNormal::NormalizePerFace(mesh); 80 | 81 | int sum=0; 82 | sum += deleteNonManifold_Edge(mesh); // 構造上1回削除すればなくなるはず 83 | 84 | while(1){ // 削除した結果、別の頂点がnon manifoldの状態になる可能性があるためループ処理する 85 | int cnt = deleteNonManifold_Vert(mesh); 86 | sum += cnt; 87 | if(cnt==0){break;} 88 | } 89 | 90 | deleteUnreferencedVert(mesh, false); // 面に所属しなくなった頂点を削除 91 | tri::UpdateBounding::Box(mesh); 92 | if(mesh.fn>0) { 93 | tri::UpdateNormal::PerFaceNormalized(mesh); 94 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 95 | } 96 | return sum; 97 | } 98 | 99 | bool add_non_manifold(CMeshO &mesh){ 100 | // 閉じているメッシュが前提 101 | // edgeの重複 : 頂点を一つ追加、既存の辺を共有する面を一つ追加 102 | // 適当な面を選択 103 | // 面の2頂点取得、3頂点目を面の法線方向に作成 104 | // この3頂点をつなぐ面を作成 105 | 106 | // 頂点の重複 : 頂点を2個追加、既存の頂点を共有する面を一つ追加 107 | // 適当な面を取得 108 | // 面の2頂点を法線方向にずらした頂点を作成 109 | // 残りの1頂点と作った2頂点をつないだ面を作成 110 | 111 | return true; 112 | } 113 | 114 | int main(int argc, char ** argv){ 115 | CMeshO mesh; 116 | 117 | if(argc<2){ 118 | cout << "add filename" << endl; 119 | return 0; 120 | } 121 | 122 | int err = tri::io::Importer::Open(mesh, argv[1]); 123 | if (err) { // all the importers return 0 in case of success 124 | printf("Error in reading %s: '%s'\n", argv[1], tri::io::Importer::ErrorMsg(err)); 125 | exit(-1); 126 | } 127 | 128 | // create non manifold state 129 | add_non_manifold(mesh); 130 | tri::io::ExporterPLY::Save(mesh,"out_with_non_manifold.ply",tri::io::Mask::IOM_VERTCOLOR, false); 131 | 132 | // remove non manifold elements 133 | deleteNonManifold(mesh); 134 | tri::io::ExporterPLY::Save(mesh,"out.ply",tri::io::Mask::IOM_VERTCOLOR, false); 135 | return 1; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /samples/set_color/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # Add Executable 31 | add_executable(${PROJECT_NAME}) 32 | target_sources(${PROJECT_NAME} 33 | PRIVATE 34 | main.cpp 35 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp 36 | ) 37 | target_include_directories(${PROJECT_NAME} 38 | PUBLIC 39 | ${EIGEN3_INCLUDE_DIR} 40 | ${VCGLIB_DIR} 41 | ${MESHLAB_DIR} 42 | ) 43 | 44 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 45 | -------------------------------------------------------------------------------- /samples/set_color/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | // if you use face color, you have to enable color because meshlab has Color4bOcf 5 | mesh.face.EnableColor(); 6 | 7 | mesh.vert[0].C() = Color4b(0xff,0,0,0xff); 8 | mesh.vert[1].C() = Color4b::Cyan; 9 | mesh.face[0].C() = Color4b::Yellow; 10 | 11 | auto flags = tri::io::Mask::IOM_VERTCOLOR| 12 | tri::io::Mask::IOM_FACECOLOR; 13 | bool binary = false; 14 | int result = tri::io::ExporterPLY::Save(mesh, "out.ply", flags, binary); 15 | if(result != ply::PlyError::E_NOERROR){ 16 | cout << "error" << endl; 17 | } 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /samples/set_color/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | using namespace vcg; 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | CMeshO mesh; 15 | tri::Tetrahedron(mesh); // create preset mesh data 16 | 17 | // if you use face color, you have to enable color because meshlab has Color4bOcf 18 | mesh.face.EnableColor(); 19 | 20 | mesh.vert[0].C() = Color4b(0xff,0,0,0xff); 21 | mesh.vert[1].C() = Color4b::Cyan; 22 | mesh.face[0].C() = Color4b::Yellow; 23 | 24 | auto flags = tri::io::Mask::IOM_VERTCOLOR| 25 | tri::io::Mask::IOM_FACECOLOR; 26 | bool binary = false; 27 | int result = tri::io::ExporterPLY::Save(mesh, "out.ply", flags, binary); 28 | if(result != ply::PlyError::E_NOERROR){ 29 | cout << "error" << endl; 30 | } 31 | 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /samples/simplification/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | quadric_simp.cpp 40 | ) 41 | target_include_directories(${PROJECT_NAME} 42 | PUBLIC 43 | ${EIGEN3_INCLUDE_DIR} 44 | ${VCGLIB_DIR} 45 | ${MESHLAB_DIR} 46 | ${CMAKE_CURRENT_SOURCE_DIR} 47 | ) 48 | 49 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 50 | -------------------------------------------------------------------------------- /samples/simplification/README.md: -------------------------------------------------------------------------------- 1 | # Simplification 2 | 3 | メッシュの再分割。いくつかの方法があり、それぞれ使用するヘッダファイルが異なる 4 | 5 | ## Clustering Decimation 6 | 7 | ```cpp 8 | #include 9 | 10 | void SimplificationClusteringDecimation(CMeshO &mesh, float grid_size){ 11 | float threshold = grid_size; 12 | tri::Clustering > ClusteringGrid; 13 | ClusteringGrid.Init(mesh.bbox,100000,threshold); 14 | if(mesh.FN() == 0) 15 | ClusteringGrid.AddPointSet(mesh); 16 | else 17 | ClusteringGrid.AddMesh(mesh); 18 | ClusteringGrid.ExtractMesh(mesh); 19 | tri::UpdateBounding::Box(mesh); 20 | if(mesh.fn>0) { 21 | tri::UpdateNormal::PerFaceNormalized(mesh); 22 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 23 | } 24 | } 25 | 26 | int main(int argc, char ** argv){ 27 | CMeshO mesh; 28 | if(argc<2){ 29 | cout << "add filename" << endl; 30 | return 0; 31 | } 32 | 33 | int err = tri::io::Importer::Open(mesh, argv[1]); 34 | if (err) { // all the importers return 0 in case of success 35 | printf("Error in reading %s: '%s'\n", argv[1], tri::io::Importer::ErrorMsg(err)); 36 | exit(-1); 37 | } 38 | 39 | { 40 | CMeshO mesh1; 41 | tri::Append::MeshCopy(mesh1, mesh); 42 | float gridsize = 0.1; 43 | mesh1.bbox.Diag(); 44 | SimplificationClusteringDecimation(mesh1, gridsize); 45 | tri::io::ExporterPLY::Save(mesh,"SimplificationClusteringDecimation.ply",tri::io::Mask::IOM_NONE, false); 46 | } 47 | return 1; 48 | } 49 | ``` 50 | 51 | ## Edge Collapse for Marching Cube Meshes 52 | 53 | ```cpp 54 | #include 55 | // mingwだとコンパイル時にエラー? volume.hで_int64が未定義になる(定義漏れ?issueに上げる) 56 | 57 | bool SimplificationEdgeCollapseMarchingCube(CMeshO &mesh, float absoluteError){ 58 | if (mesh.fn == 0){ 59 | return false; 60 | } 61 | mesh.vert.EnableVFAdjacency(); 62 | mesh.face.EnableVFAdjacency(); 63 | tri::UpdateTopology::VertexFace(mesh); 64 | 65 | mesh.face.EnableFFAdjacency(); 66 | tri::UpdateTopology::FaceFace(mesh); 67 | 68 | mesh.vert.EnableMark(); 69 | 70 | int res = tri::MCSimplify(mesh, absoluteError, false); 71 | if (res !=1){ 72 | return false; 73 | } 74 | 75 | tri::Allocator::CompactFaceVector(mesh); 76 | tri::Clean::RemoveTVertexByFlip(mesh,20,true); 77 | tri::Clean::RemoveFaceFoldByFlip(mesh); 78 | tri::Allocator::CompactVertexVector(mesh); 79 | tri::Allocator::CompactFaceVector(mesh); 80 | tri::UpdateTopology::VertexFace(mesh); 81 | tri::UpdateTopology::FaceFace(mesh); 82 | return true; 83 | } 84 | 85 | int main(int argc, char ** argv){ 86 | CMeshO mesh; 87 | if(argc<2){ 88 | cout << "add filename" << endl; 89 | return 0; 90 | } 91 | 92 | int err = tri::io::Importer::Open(mesh, argv[1]); 93 | if (err) { // all the importers return 0 in case of success 94 | printf("Error in reading %s: '%s'\n", argv[1], tri::io::Importer::ErrorMsg(err)); 95 | exit(-1); 96 | } 97 | 98 | { 99 | CMeshO mesh1; 100 | tri::Append::MeshCopy(mesh1, mesh); 101 | float abs_error = 0.1; 102 | SimplificationEdgeCollapseMarchingCube(mesh1, abs_error); 103 | tri::io::ExporterPLY::Save(mesh,"SimplificationEdgeCollapseMarchingCube.ply",tri::io::Mask::IOM_NONE, false); 104 | } 105 | return 1; 106 | } 107 | 108 | ``` 109 | 110 | ## Quadric Edge Collapse Decimation 111 | 112 | MeshLabのソースファイルから`quadric_simp`のヘッダファイルとcppファイルをコピーする 113 | 114 | ```cpp 115 | #include "quadric_simp.h" // for simplification collapse edge 116 | 117 | void SimplificationQuadricEdgeCollapseDecimation(CMeshO &mesh, int targetFaceNum, double qualityThreshold, bool selectedOnly, bool autoClean){ 118 | int TargetFaceNum = targetFaceNum; 119 | //double TargetPerc = 0; 120 | double QualityThr = qualityThreshold; 121 | bool PreserveBoundary = false; 122 | double BoundaryWeight = 1.0; 123 | bool PreserveNormal = false; 124 | bool PreserveTopology = false; 125 | bool OptimalPlacement = true; 126 | bool PlanarQuadric = false; 127 | double PlanarWeight = 0.001; 128 | bool QualityWeight = false; 129 | bool AutoClean = autoClean; 130 | bool Selected = selectedOnly; 131 | 132 | if(TargetFaceNum<=0){ 133 | TargetFaceNum = mesh.FN()/2; 134 | } 135 | mesh.vert.EnableVFAdjacency(); 136 | mesh.face.EnableVFAdjacency(); 137 | tri::UpdateTopology::VertexFace(mesh); 138 | mesh.vert.EnableMark(); 139 | 140 | tri::UpdateFlags::FaceBorderFromVF(mesh); 141 | 142 | tri::TriEdgeCollapseQuadricParameter pp; 143 | pp.QualityThr = QualityThr; 144 | pp.PreserveBoundary = PreserveBoundary; 145 | pp.BoundaryQuadricWeight = pp.BoundaryQuadricWeight * BoundaryWeight; 146 | pp.PreserveTopology = PreserveTopology; 147 | pp.QualityWeight = QualityWeight; 148 | pp.NormalCheck = PreserveNormal; 149 | pp.OptimalPlacement = OptimalPlacement; 150 | pp.QualityQuadric = PlanarQuadric; 151 | pp.QualityQuadricWeight = PlanarWeight; 152 | 153 | QuadricSimplification(mesh,TargetFaceNum,Selected,pp); 154 | 155 | if(AutoClean) 156 | { 157 | int nullFaces=tri::Clean::RemoveFaceOutOfRangeArea(mesh,0); 158 | int deldupvert=tri::Clean::RemoveDuplicateVertex(mesh); 159 | int delvert=tri::Clean::RemoveUnreferencedVertex(mesh); 160 | //mesh.clearDataMask(MeshModel::MM_FACEFACETOPO ); 161 | mesh.face.DisableFFAdjacency(); 162 | tri::Allocator::CompactVertexVector(mesh); 163 | tri::Allocator::CompactFaceVector(mesh); 164 | } 165 | 166 | //mesh.UpdateBoxAndNormals(); 167 | tri::UpdateBounding::Box(mesh); 168 | if(mesh.fn>0) { 169 | tri::UpdateNormal::PerFaceNormalized(mesh); 170 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 171 | } 172 | 173 | tri::UpdateNormal::NormalizePerFace(mesh); 174 | tri::UpdateNormal::PerVertexFromCurrentFaceNormal(mesh); 175 | tri::UpdateNormal::NormalizePerVertex(mesh); 176 | } 177 | 178 | int main(int argc, char ** argv){ 179 | CMeshO mesh; 180 | if(argc<2){ 181 | cout << "add filename" << endl; 182 | return 0; 183 | } 184 | 185 | int err = tri::io::Importer::Open(mesh, argv[1]); 186 | if (err) { // all the importers return 0 in case of success 187 | printf("Error in reading %s: '%s'\n", argv[1], tri::io::Importer::ErrorMsg(err)); 188 | exit(-1); 189 | } 190 | 191 | { 192 | CMeshO mesh1; 193 | tri::Append::MeshCopy(mesh1, mesh); 194 | int targetFaceNum = 0; 195 | bool selectedOnly = false; 196 | bool autoClean = true; 197 | double qualityThreshold = 0.3; 198 | SimplificationQuadricEdgeCollapseDecimation(mesh1, targetFaceNum, qualityThreshold, selectedOnly, autoClean); 199 | tri::io::ExporterPLY::Save(mesh,"SimplificationQuadricEdgeCollapseDecimation.ply",tri::io::Mask::IOM_NONE, false); 200 | } 201 | return 1; 202 | } 203 | ``` 204 | 205 | -------------------------------------------------------------------------------- /samples/simplification/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include "quadric_simp.h" // for simplification collapse edge 11 | #include 12 | #include 13 | 14 | using namespace vcg; 15 | using namespace std; 16 | 17 | void SimplificationClusteringDecimation(CMeshO &mesh, float grid_size){ 18 | float threshold = grid_size; 19 | tri::Clustering > ClusteringGrid; 20 | ClusteringGrid.Init(mesh.bbox,100000,threshold); 21 | if(mesh.FN() == 0) 22 | ClusteringGrid.AddPointSet(mesh); 23 | else 24 | ClusteringGrid.AddMesh(mesh); 25 | ClusteringGrid.ExtractMesh(mesh); 26 | tri::UpdateBounding::Box(mesh); 27 | if(mesh.fn>0) { 28 | tri::UpdateNormal::PerFaceNormalized(mesh); 29 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 30 | } 31 | } 32 | 33 | void SimplificationQuadricEdgeCollapseDecimation(CMeshO &mesh, int targetFaceNum, double qualityThreshold, bool selectedOnly, bool autoClean){ 34 | int TargetFaceNum = targetFaceNum; 35 | //double TargetPerc = 0; 36 | double QualityThr = qualityThreshold; 37 | bool PreserveBoundary = false; 38 | double BoundaryWeight = 1.0; 39 | bool PreserveNormal = false; 40 | bool PreserveTopology = false; 41 | bool OptimalPlacement = true; 42 | bool PlanarQuadric = false; 43 | double PlanarWeight = 0.001; 44 | bool QualityWeight = false; 45 | bool AutoClean = autoClean; 46 | bool Selected = selectedOnly; 47 | 48 | if(TargetFaceNum<=0){ 49 | TargetFaceNum = mesh.FN()/2; 50 | } 51 | mesh.vert.EnableVFAdjacency(); 52 | mesh.face.EnableVFAdjacency(); 53 | tri::UpdateTopology::VertexFace(mesh); 54 | mesh.vert.EnableMark(); 55 | 56 | tri::UpdateFlags::FaceBorderFromVF(mesh); 57 | 58 | tri::TriEdgeCollapseQuadricParameter pp; 59 | pp.QualityThr = QualityThr; 60 | pp.PreserveBoundary = PreserveBoundary; 61 | pp.BoundaryQuadricWeight = pp.BoundaryQuadricWeight * BoundaryWeight; 62 | pp.PreserveTopology = PreserveTopology; 63 | pp.QualityWeight = QualityWeight; 64 | pp.NormalCheck = PreserveNormal; 65 | pp.OptimalPlacement = OptimalPlacement; 66 | pp.QualityQuadric = PlanarQuadric; 67 | pp.QualityQuadricWeight = PlanarWeight; 68 | 69 | QuadricSimplification(mesh,TargetFaceNum,Selected,pp); 70 | 71 | if(AutoClean) 72 | { 73 | int nullFaces=tri::Clean::RemoveFaceOutOfRangeArea(mesh,0); 74 | int deldupvert=tri::Clean::RemoveDuplicateVertex(mesh); 75 | int delvert=tri::Clean::RemoveUnreferencedVertex(mesh); 76 | //mesh.clearDataMask(MeshModel::MM_FACEFACETOPO ); 77 | mesh.face.DisableFFAdjacency(); 78 | tri::Allocator::CompactVertexVector(mesh); 79 | tri::Allocator::CompactFaceVector(mesh); 80 | } 81 | 82 | //mesh.UpdateBoxAndNormals(); 83 | tri::UpdateBounding::Box(mesh); 84 | if(mesh.fn>0) { 85 | tri::UpdateNormal::PerFaceNormalized(mesh); 86 | tri::UpdateNormal::PerVertexAngleWeighted(mesh); 87 | } 88 | 89 | tri::UpdateNormal::NormalizePerFace(mesh); 90 | tri::UpdateNormal::PerVertexFromCurrentFaceNormal(mesh); 91 | tri::UpdateNormal::NormalizePerVertex(mesh); 92 | } 93 | bool SimplificationEdgeCollapseMarchingCube(CMeshO &mesh, float absoluteError){ 94 | if (mesh.fn == 0){ 95 | return false; 96 | } 97 | mesh.vert.EnableVFAdjacency(); 98 | mesh.face.EnableVFAdjacency(); 99 | tri::UpdateTopology::VertexFace(mesh); 100 | 101 | mesh.face.EnableFFAdjacency(); 102 | tri::UpdateTopology::FaceFace(mesh); 103 | 104 | mesh.vert.EnableMark(); 105 | 106 | int res = tri::MCSimplify(mesh, absoluteError, false); 107 | if (res !=1){ 108 | return false; 109 | } 110 | 111 | tri::Allocator::CompactFaceVector(mesh); 112 | tri::Clean::RemoveTVertexByFlip(mesh,20,true); 113 | tri::Clean::RemoveFaceFoldByFlip(mesh); 114 | tri::Allocator::CompactVertexVector(mesh); 115 | tri::Allocator::CompactFaceVector(mesh); 116 | tri::UpdateTopology::VertexFace(mesh); 117 | tri::UpdateTopology::FaceFace(mesh); 118 | return true; 119 | } 120 | 121 | 122 | int main(int argc, char ** argv){ 123 | CMeshO mesh; 124 | if(argc<2){ 125 | cout << "add filename" << endl; 126 | return 0; 127 | } 128 | 129 | int err = tri::io::Importer::Open(mesh, argv[1]); 130 | if (err) { // all the importers return 0 in case of success 131 | printf("Error in reading %s: '%s'\n", argv[1], tri::io::Importer::ErrorMsg(err)); 132 | exit(-1); 133 | } 134 | 135 | { 136 | CMeshO mesh1; 137 | tri::Append::MeshCopy(mesh1, mesh); 138 | int targetFaceNum = 0; 139 | bool selectedOnly = false; 140 | bool autoClean = true; 141 | double qualityThreshold = 0.3; 142 | SimplificationQuadricEdgeCollapseDecimation(mesh1, targetFaceNum, qualityThreshold, selectedOnly, autoClean); 143 | tri::io::ExporterPLY::Save(mesh,"SimplificationQuadricEdgeCollapseDecimation.ply",tri::io::Mask::IOM_NONE, false); 144 | } 145 | { 146 | CMeshO mesh1; 147 | tri::Append::MeshCopy(mesh1, mesh); 148 | float gridsize = 0.1; 149 | mesh1.bbox.Diag(); 150 | SimplificationClusteringDecimation(mesh1, gridsize); 151 | tri::io::ExporterPLY::Save(mesh,"SimplificationClusteringDecimation.ply",tri::io::Mask::IOM_NONE, false); 152 | } 153 | { 154 | CMeshO mesh1; 155 | tri::Append::MeshCopy(mesh1, mesh); 156 | float abs_error = 0.1; 157 | SimplificationEdgeCollapseMarchingCube(mesh1, abs_error); 158 | tri::io::ExporterPLY::Save(mesh,"SimplificationEdgeCollapseMarchingCube.ply",tri::io::Mask::IOM_NONE, false); 159 | } 160 | return 1; 161 | } 162 | 163 | -------------------------------------------------------------------------------- /samples/simplification/quadric_simp.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MeshLab o o * 3 | * A versatile mesh processing toolbox o o * 4 | * _ O _ * 5 | * Copyright(C) 2005 \/)\/ * 6 | * Visual Computing Lab /\/| * 7 | * ISTI - Italian National Research Council | * 8 | * \ * 9 | * All rights reserved. * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 2 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * 19 | * for more details. * 20 | * * 21 | ****************************************************************************/ 22 | //#include "meshfilter.h" 23 | 24 | #include 25 | #include 26 | 27 | #include "quadric_simp.h" 28 | 29 | using namespace vcg; 30 | using namespace std; 31 | 32 | void QuadricSimplification(CMeshO &m,int TargetFaceNum, bool Selected, tri::TriEdgeCollapseQuadricParameter &pp/*, CallBackPos *cb*/) 33 | { 34 | math::Quadric QZero; 35 | QZero.SetZero(); 36 | tri::QuadricTemp TD(m.vert,QZero); 37 | tri::QHelper::TDp()=&TD; 38 | 39 | if(Selected) // simplify only inside selected faces 40 | { 41 | // select only the vertices having ALL incident faces selected 42 | tri::UpdateSelection::VertexFromFaceStrict(m); 43 | 44 | // Mark not writable un-selected vertices 45 | for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) 46 | { 47 | if(!(*vi).IsS()) (*vi).ClearW(); 48 | else (*vi).SetW(); 49 | } 50 | } 51 | 52 | if(pp.PreserveBoundary && !Selected) 53 | { 54 | pp.FastPreserveBoundary=true; 55 | pp.PreserveBoundary = false; 56 | } 57 | 58 | if(pp.NormalCheck) pp.NormalThrRad = M_PI/4.0; 59 | 60 | vcg::LocalOptimization DeciSession(m,&pp); 61 | //cb(1,"Initializing simplification"); 62 | DeciSession.Init(); 63 | 64 | if(Selected) 65 | TargetFaceNum= m.fn - (m.sfn-TargetFaceNum); 66 | DeciSession.SetTargetSimplices(TargetFaceNum); 67 | DeciSession.SetTimeBudget(0.1f); // this allow to update the progress bar 10 time for sec... 68 | // if(TargetError< numeric_limits::max() ) DeciSession.SetTargetMetric(TargetError); 69 | //int startFn=m.fn; 70 | int faceToDel=m.fn-TargetFaceNum; 71 | while( DeciSession.DoOptimization() && m.fn>TargetFaceNum ) 72 | { 73 | //cb(100-100*(m.fn-TargetFaceNum)/(faceToDel), "Simplifying..."); 74 | } 75 | 76 | DeciSession.Finalize(); 77 | 78 | if(Selected) // Clear Writable flags 79 | { 80 | for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) 81 | { 82 | if (!(*vi).IsD()) (*vi).SetW(); 83 | if ((*vi).IsS()) (*vi).ClearS(); 84 | } 85 | } 86 | } 87 | 88 | //void QuadricTexSimplification(CMeshO &m,int TargetFaceNum, bool Selected, tri::TriEdgeCollapseQuadricTexParameter &pp, CallBackPos *cb) 89 | //{ 90 | // tri::UpdateNormal::PerFace(m); 91 | // math::Quadric QZero; 92 | // QZero.SetZero(); 93 | // tri::QuadricTexHelper::QuadricTemp TD3(m.vert,QZero); 94 | // tri::QuadricTexHelper::TDp3()=&TD3; 95 | 96 | // std::vector,Quadric5 > > qv; 97 | 98 | // tri::QuadricTexHelper::Quadric5Temp TD(m.vert,qv); 99 | // tri::QuadricTexHelper::TDp()=&TD; 100 | 101 | // if(Selected) // simplify only inside selected faces 102 | // { 103 | // // select only the vertices having ALL incident faces selected 104 | // tri::UpdateSelection::VertexFromFaceStrict(m); 105 | 106 | // // Mark not writable un-selected vertices 107 | // for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) 108 | // { 109 | // if(!(*vi).IsS()) (*vi).ClearW(); 110 | // else (*vi).SetW(); 111 | // } 112 | // } 113 | 114 | // vcg::LocalOptimization DeciSession(m,&pp); 115 | // cb(1,"Initializing simplification"); 116 | // DeciSession.Init(); 117 | 118 | // if(Selected) 119 | // TargetFaceNum= m.fn - (m.sfn-TargetFaceNum); 120 | // DeciSession.SetTargetSimplices(TargetFaceNum); 121 | // DeciSession.SetTimeBudget(0.1f); 122 | // // int startFn=m.fn; 123 | 124 | // int faceToDel=m.fn-TargetFaceNum; 125 | 126 | // while( DeciSession.DoOptimization() && m.fn>TargetFaceNum ) 127 | // { 128 | // char buf[256]; 129 | // sprintf(buf,"Simplifing: heap size %i ops %i\n",int(DeciSession.h.size()),DeciSession.nPerformedOps); 130 | // cb(100-100*(m.fn-TargetFaceNum)/(faceToDel), buf); 131 | // }; 132 | 133 | // DeciSession.Finalize(); 134 | 135 | // if(Selected) // Clear Writable flags 136 | // { 137 | // for (auto vi = m.vert.begin(); vi != m.vert.end(); ++vi) 138 | // { 139 | // if (!(*vi).IsD()) (*vi).SetW(); 140 | // if ((*vi).IsS()) (*vi).ClearS(); 141 | // } 142 | // } 143 | //} 144 | -------------------------------------------------------------------------------- /samples/simplification/quadric_simp.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MeshLab o o * 3 | * A versatile mesh processing toolbox o o * 4 | * _ O _ * 5 | * Copyright(C) 2005 \/)\/ * 6 | * Visual Computing Lab /\/| * 7 | * ISTI - Italian National Research Council | * 8 | * \ * 9 | * All rights reserved. * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 2 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * 19 | * for more details. * 20 | * * 21 | ****************************************************************************/ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace vcg { 29 | namespace tri { 30 | 31 | typedef SimpleTempData > QuadricTemp; 32 | 33 | 34 | class QHelper 35 | { 36 | public: 37 | QHelper(){} 38 | static void Init(){} 39 | static math::Quadric &Qd(CVertexO &v) {return TD()[v];} 40 | static math::Quadric &Qd(CVertexO *v) {return TD()[*v];} 41 | static CVertexO::ScalarType W(CVertexO * /*v*/) {return 1.0;} 42 | static CVertexO::ScalarType W(CVertexO & /*v*/) {return 1.0;} 43 | static void Merge(CVertexO & /*v_dest*/, CVertexO const & /*v_del*/){} 44 | static QuadricTemp* &TDp() {static QuadricTemp *td; return td;} 45 | static QuadricTemp &TD() {return *TDp();} 46 | }; 47 | 48 | typedef BasicVertexPair VertexPair; 49 | 50 | class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< CMeshO, VertexPair , MyTriEdgeCollapse, QHelper > { 51 | public: 52 | typedef vcg::tri::TriEdgeCollapseQuadric< CMeshO, VertexPair, MyTriEdgeCollapse, QHelper> TECQ; 53 | inline MyTriEdgeCollapse( const VertexPair &p, int i, BaseParameterClass *pp) :TECQ(p,i,pp){} 54 | }; 55 | 56 | class MyTriEdgeCollapseQTex: public TriEdgeCollapseQuadricTex< CMeshO, VertexPair, MyTriEdgeCollapseQTex, QuadricTexHelper > { 57 | public: 58 | typedef TriEdgeCollapseQuadricTex< CMeshO, VertexPair, MyTriEdgeCollapseQTex, QuadricTexHelper > TECQ; 59 | inline MyTriEdgeCollapseQTex( const VertexPair &p, int i,BaseParameterClass *pp) :TECQ(p,i,pp){} 60 | }; 61 | 62 | } // end namespace tri 63 | } // end namepsace vcg 64 | void QuadricSimplification (CMeshO &m,int TargetFaceNum, bool Selected, vcg::tri::TriEdgeCollapseQuadricParameter &pp/*, vcg::CallBackPos *cb*/); 65 | //void QuadricTexSimplification(CMeshO &m,int TargetFaceNum, bool Selected, vcg::tri::TriEdgeCollapseQuadricTexParameter &pp, vcg::CallBackPos *cb); 66 | 67 | -------------------------------------------------------------------------------- /samples/subdivision/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | ${VCGLIB_DIR}/wrap/ply/plylib.h 39 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp 40 | ) 41 | target_include_directories(${PROJECT_NAME} 42 | PUBLIC 43 | ${EIGEN3_INCLUDE_DIR} 44 | ${VCGLIB_DIR} 45 | ${MESHLAB_DIR} 46 | ) 47 | 48 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 49 | -------------------------------------------------------------------------------- /samples/subdivision/README.md: -------------------------------------------------------------------------------- 1 | # Subdivision Surfaces 2 | 3 | メッシュの分割 4 | 5 | [source code of meshlab](https://github.com/cnr-isti-vclab/meshlab/blob/master/src/meshlabplugins/filter_meshing/meshfilter.cpp) 6 | 7 | ## Midpoint 8 | 9 | 中点で分割していくだけのシンプルな方法。指定した回数だけ分割を行う(辺の長さが指定値未満になったら分割されない) 10 | 11 | ```cpp 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace vcg; 19 | using namespace std; 20 | 21 | int main(){ 22 | CMeshO mesh; 23 | tri::Tetrahedron(mesh); // create preset mesh data 24 | 25 | mesh.face.EnableFFAdjacency(); 26 | tri::UpdateTopology::FaceFace(mesh); 27 | 28 | tri::Allocator::CompactFaceVector(mesh); 29 | tri::Allocator::CompactVertexVector(mesh); 30 | tri::UpdateFlags::FaceBorderFromFF(mesh); 31 | 32 | if ( tri::Clean::CountNonManifoldEdgeFF(mesh) > 0) 33 | { 34 | printf("Mesh has some not 2 manifoldfaces, subdivision surfaces require manifoldness\n"); 35 | return 0; // can't continue, mesh can't be processed 36 | } 37 | 38 | MESHLAB_SCALAR threshold = mesh.bbox.Diag()*0.01; 39 | int cnt = 3; 40 | bool selected = false; 41 | for(int i=0; i > (mesh, MidPoint(&mesh), threshold, selected); 43 | } 44 | 45 | tri::io::ExporterPLY::Save(mesh,"out.ply",tri::io::Mask::IOM_NONE); 46 | 47 | return 1; 48 | } 49 | ``` 50 | 51 | 52 | 53 | ## Butterfly Subdivision 54 | 55 | エッジが少し丸くなる 56 | 57 | ```cpp 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | 64 | using namespace vcg; 65 | using namespace std; 66 | 67 | int main(){ 68 | CMeshO mesh; 69 | tri::Tetrahedron(mesh); // create preset mesh data 70 | 71 | mesh.face.EnableFFAdjacency(); 72 | tri::UpdateTopology::FaceFace(mesh); 73 | 74 | tri::Allocator::CompactFaceVector(mesh); 75 | tri::Allocator::CompactVertexVector(mesh); 76 | //m.updateDataMask( MeshModel::MM_FACEFACETOPO); 77 | tri::UpdateFlags::FaceBorderFromFF(mesh); 78 | 79 | if ( tri::Clean::CountNonManifoldEdgeFF(mesh) > 0) 80 | { 81 | printf("Mesh has some not 2 manifoldfaces, subdivision surfaces require manifoldness\n"); 82 | return 0; // can't continue, mesh can't be processed 83 | } 84 | 85 | MESHLAB_SCALAR threshold = mesh.bbox.Diag()*0.01; 86 | int cnt = 3; 87 | bool selected = false; 88 | for(int i=0; i > (mesh, MidPointButterfly(mesh), threshold, selected); 90 | } 91 | 92 | tri::io::ExporterPLY::Save(mesh,"out.ply",tri::io::Mask::IOM_NONE); 93 | 94 | return 1; 95 | } 96 | ``` 97 | 98 | 99 | 100 | ## Loop 101 | 102 | 形状がかなり縮小される 103 | 104 | ```cpp 105 | 106 | ``` 107 | 108 | 109 | 110 | ## Catmull-Clark 111 | 112 | ```cpp 113 | 114 | ``` 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /samples/subdivision/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace vcg; 8 | using namespace std; 9 | 10 | int main(){ 11 | CMeshO mesh; 12 | tri::Tetrahedron(mesh); // create preset mesh data 13 | 14 | mesh.face.EnableFFAdjacency(); 15 | tri::UpdateTopology::FaceFace(mesh); 16 | 17 | tri::Allocator::CompactFaceVector(mesh); 18 | tri::Allocator::CompactVertexVector(mesh); 19 | //m.updateDataMask( MeshModel::MM_FACEFACETOPO); 20 | tri::UpdateFlags::FaceBorderFromFF(mesh); 21 | 22 | if ( tri::Clean::CountNonManifoldEdgeFF(mesh) > 0) 23 | { 24 | printf("Mesh has some not 2 manifoldfaces, subdivision surfaces require manifoldness\n"); 25 | return 0; // can't continue, mesh can't be processed 26 | } 27 | 28 | MESHLAB_SCALAR threshold = mesh.bbox.Diag()*0.01; 29 | int cnt = 3; 30 | bool selected = false; 31 | for(int i=0; i > (mesh, MidPoint(&mesh), threshold, selected); // midpoint 33 | // Refine > (mesh, MidPointButterfly(mesh), threshold, selected); // Butterfly 34 | } 35 | 36 | tri::io::ExporterPLY::Save(mesh,"out.ply",tri::io::Mask::IOM_NONE); 37 | 38 | return 1; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /samples/template/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | 27 | # Add Executable 28 | add_executable(${PROJECT_NAME}) 29 | target_sources(${PROJECT_NAME} 30 | PRIVATE 31 | main.cpp 32 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 33 | ) 34 | target_include_directories(${PROJECT_NAME} 35 | PUBLIC 36 | ${EIGEN3_INCLUDE_DIR} 37 | ${VCGLIB_DIR} 38 | ) 39 | 40 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 41 | -------------------------------------------------------------------------------- /samples/template/README.md: -------------------------------------------------------------------------------- 1 | [Basic concepts](http://vcg.isti.cnr.it/vcglib/basic_concepts.html) 2 | 3 | 4 | 5 | ```cpp 6 | #include 7 | 8 | using namespace vcg; 9 | using namespace std; 10 | 11 | class MyFace; 12 | class MyVertex; 13 | 14 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 15 | class MyVertex : public Vertex< MyUsedTypes, 16 | vertex::Coord3f, 17 | vertex::Normal3f, 18 | vertex::BitFlags, 19 | vertex::VFAdj 20 | > {}; 21 | class MyFace : public Face< MyUsedTypes, 22 | face::VertexRef, 23 | face::Normal3f, 24 | face::VFAdj, 25 | face::BitFlags 26 | > {}; 27 | class MyMesh : public tri::TriMesh< 28 | vector, 29 | vector 30 | > {}; 31 | 32 | int main(){ 33 | MyMesh mesh; 34 | vcg::tri::Octahedron(mesh); // create preset mesh data 35 | 36 | MyMesh::FaceIterator fi; 37 | for(fi=mesh.face.begin(); fi!=mesh.face.end(); ++fi){ // iterate each faces 38 | std::cout << vcg::tri::Index(mesh, *fi) << ": "; // get face index 39 | for(int i=0; iVN(); ++i){ // iterate each vertex of face 40 | std::cout << vcg::tri::Index(mesh, fi->V(i)) << ","; // get vertex index 41 | } 42 | std::cout << std::endl; 43 | } 44 | return 1; 45 | } 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /samples/template/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace vcg; 4 | using namespace std; 5 | 6 | class MyFace; 7 | class MyVertex; 8 | 9 | struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType> {}; 10 | class MyVertex : public Vertex< MyUsedTypes, 11 | vertex::Coord3f, 12 | vertex::Normal3f, 13 | vertex::BitFlags, 14 | vertex::VFAdj 15 | > {}; 16 | class MyFace : public Face< MyUsedTypes, 17 | face::VertexRef, 18 | face::Normal3f, 19 | face::VFAdj, 20 | face::BitFlags 21 | > {}; 22 | class MyMesh : public tri::TriMesh< 23 | vector, 24 | vector 25 | > {}; 26 | 27 | int main(){ 28 | MyMesh mesh; 29 | vcg::tri::Octahedron(mesh); // create preset mesh data 30 | 31 | MyMesh::FaceIterator fi; 32 | for(fi=mesh.face.begin(); fi!=mesh.face.end(); ++fi){ // iterate each faces 33 | std::cout << vcg::tri::Index(mesh, *fi) << ": "; // get face index 34 | for(int i=0; iVN(); ++i){ // iterate each vertex of face 35 | std::cout << vcg::tri::Index(mesh, fi->V(i)) << ","; // get vertex index 36 | } 37 | std::cout << std::endl; 38 | } 39 | return 1; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /samples/template_meshlab/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/template_meshlab/README.md: -------------------------------------------------------------------------------- 1 | You can use data structure used by [MeshLab](https://github.com/cnr-isti-vclab/meshlab). 2 | 3 | What you have to do is only to import [`meshlab/src/common/ml_mesh_type.h`](https://github.com/cnr-isti-vclab/meshlab/blob/master/src/common/ml_mesh_type.h) 4 | 5 | Then you can declare mesh data as `CMeshO`. 6 | 7 | 8 | 9 | CMakeLists.txt 10 | 11 | ```cmake 12 | # define path of meshlab source 13 | set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 14 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 15 | ``` 16 | 17 | 18 | 19 | main.cpp 20 | 21 | ```cpp 22 | #include 23 | #include 24 | #include 25 | 26 | using namespace vcg; 27 | using namespace std; 28 | 29 | int main(){ 30 | CMeshO mesh; 31 | tri::Tetrahedron(mesh); // create preset mesh data 32 | 33 | for(CMeshO::VertexType &vt : mesh.vert){ 34 | cout << vt.Index() << endl; 35 | } 36 | 37 | return 1; 38 | } 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /samples/template_meshlab/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | CMeshO mesh; 10 | tri::Tetrahedron(mesh); // create preset mesh data 11 | 12 | for(CMeshO::VertexType &vt : mesh.vert){ 13 | cout << vt.Index() << endl; 14 | } 15 | 16 | return 1; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /samples/template_pybind/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | set(CMAKE_CXX_STANDARD 14) 3 | 4 | # Create Project 5 | # get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 6 | # string(REPLACE " " "_" ProjectId ${ProjectId}) 7 | # project(${ProjectId} CXX) 8 | project(vcgmesh CXX) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | find_package(pybind11 REQUIRED) 19 | 20 | # set output file directory 21 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}) 22 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}) 23 | 24 | # define path of Eigen 25 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 26 | # define path of vcglib 27 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 28 | # define path of meshlab source 29 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 30 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 31 | 32 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 33 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 34 | 35 | if(pybind11_FOUND) 36 | else() 37 | message(FATAL_ERROR "ERROR: this program will not be compiled.") 38 | endif() 39 | 40 | add_library(${PROJECT_NAME} MODULE 41 | main.cpp 42 | ${VCGLIB_DIR}/wrap/ply/plylib.h 43 | ${VCGLIB_DIR}/wrap/ply/plylib.cpp 44 | ) 45 | 46 | target_link_libraries(${PROJECT_NAME} PRIVATE pybind11::module) 47 | 48 | target_include_directories(${PROJECT_NAME} 49 | PUBLIC 50 | ${EIGEN3_INCLUDE_DIR} 51 | ${VCGLIB_DIR} 52 | ${MESHLAB_DIR} 53 | ) 54 | 55 | set_target_properties(${PROJECT_NAME} PROPERTIES 56 | DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} 57 | SUFFIX ".pyd" 58 | ) 59 | 60 | add_definitions(-DMY_MODULE_NAME=${PROJECT_NAME}) # module name must be same lib name -------------------------------------------------------------------------------- /samples/template_pybind/README.md: -------------------------------------------------------------------------------- 1 | You can use data structure used by [MeshLab](https://github.com/cnr-isti-vclab/meshlab). 2 | 3 | What you have to do is only to import [`meshlab/src/common/ml_mesh_type.h`](https://github.com/cnr-isti-vclab/meshlab/blob/master/src/common/ml_mesh_type.h) 4 | 5 | Then you can declare mesh data as `CMeshO`. 6 | 7 | 8 | 9 | CMakeLists.txt 10 | 11 | ```cmake 12 | # define path of meshlab source 13 | set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 14 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 15 | ``` 16 | 17 | 18 | 19 | main.cpp 20 | 21 | ```cpp 22 | #include 23 | #include 24 | #include 25 | 26 | using namespace vcg; 27 | using namespace std; 28 | 29 | int main(){ 30 | CMeshO mesh; 31 | tri::Tetrahedron(mesh); // create preset mesh data 32 | 33 | for(CMeshO::VertexType &vt : mesh.vert){ 34 | cout << vt.Index() << endl; 35 | } 36 | 37 | return 1; 38 | } 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /samples/template_pybind/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace vcg; 13 | using namespace std; 14 | namespace py = pybind11; 15 | 16 | class Vcgmesh{ 17 | public: 18 | void create_Tetrahedron(); 19 | bool load(string s); 20 | bool save_ply(string s, bool binary, bool withVertColor, bool withFaceColor); 21 | 22 | CMeshO mesh; 23 | }; 24 | 25 | void Vcgmesh::create_Tetrahedron(){ 26 | tri::Tetrahedron(mesh); 27 | } 28 | 29 | bool Vcgmesh::load(string s){ 30 | int err = tri::io::Importer::Open(mesh, s.c_str()); // 多分ライブラリにあるファイルなら何でも開ける 31 | if (err) { // all the importers return 0 in case of success 32 | printf("Error in reading %s: '%s'\n", s.c_str(), tri::io::Importer::ErrorMsg(err)); 33 | return false; 34 | } 35 | return true; 36 | } 37 | 38 | bool Vcgmesh::save_ply(string s, bool binary, bool withVertColor, bool withFaceColor){ 39 | int mask = tri::io::Mask::IOM_NONE; 40 | if(withVertColor) mask |= tri::io::Mask::IOM_VERTCOLOR; 41 | if(withFaceColor) mask |= tri::io::Mask::IOM_FACECOLOR; 42 | int result = tri::io::ExporterPLY::Save(mesh, s.c_str(), mask, binary); 43 | if(ply::PlyError::E_NOERROR == result){ 44 | return true; 45 | }else{ 46 | printf("ply save error : error_code is %d\n", result); 47 | return false; 48 | } 49 | } 50 | 51 | void hello(){ 52 | cout << "Hello Vcgmesh" << endl; 53 | } 54 | 55 | PYBIND11_MODULE(MY_MODULE_NAME, m) { 56 | m.doc() = "pybind11 example plugin"; // optional module docstring 57 | m.def("hello", &hello, "Hello Vcgmesh"); 58 | 59 | py::class_(m, "Vcgmesh") 60 | .def(py::init<>()) 61 | .def("load", [](Vcgmesh &a, string fname){ 62 | bool ret = a.load(fname); 63 | return ret; 64 | },"input file path(e.g. PLY, OFF, STL...)") 65 | .def("save_ply", [](Vcgmesh &a, string fname, bool binary, bool withVertColor, bool withFaceColor){ 66 | // TODO : check extension is ply 67 | a.save_ply(fname, binary, withVertColor, withFaceColor); 68 | }, py::arg("fname")="out.ply", py::arg("binary")=true, py::arg("withVertColor")=false, py::arg("withFaceColor")=false, "save as ply format.") 69 | .def("__repr__", [](const Vcgmesh &a){ 70 | return "vert: " + to_string(a.mesh.VN()) + ", face: " + std::to_string(a.mesh.FN()); 71 | },"print mesh infomation. number of vertices and faces") 72 | .def("create_Tetrahedron", &Vcgmesh::create_Tetrahedron) 73 | ; 74 | } 75 | -------------------------------------------------------------------------------- /samples/template_pybind/out.ply: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nitta-K-git/vcglib_samples/dbe70bd21bbc618286bbdf7533782a398a4f276d/samples/template_pybind/out.ply -------------------------------------------------------------------------------- /samples/transformation_matrix/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/transformation_matrix/README.md: -------------------------------------------------------------------------------- 1 | ## main.cpp 2 | 3 | ```cpp 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace vcg; 9 | using namespace std; 10 | 11 | int main(){ 12 | CMeshO mesh; 13 | tri::Tetrahedron(mesh); // create preset mesh data 14 | cout << "default" << endl; 15 | for(auto &&v:mesh.vert) 16 | printf("(%f,%f,%f)\n",v.P().X(), v.P().Y(), v.P().Z()); 17 | 18 | // meshlab\src\meshlabplugins\filter_meshing\meshfilter.cpp 19 | Matrix44m trRot, trTran, trTranInv, transfM; 20 | 21 | Point3m rotAxis = Point3m(1,0,0); 22 | Point3m rotCenter = Point3m(0,0,0); 23 | float angleDeg= 45.0; 24 | 25 | trRot.SetRotateDeg(angleDeg,rotAxis); 26 | trTran.SetTranslate(rotCenter); 27 | trTranInv.SetTranslate(-rotCenter); 28 | transfM = trTran*trRot*trTranInv; 29 | 30 | tri::UpdatePosition::Matrix(mesh, transfM); 31 | tri::UpdateBounding::Box(mesh); 32 | 33 | cout << "translated" << endl; 34 | for(auto &&v:mesh.vert) 35 | printf("(%f,%f,%f)\n",v.P().X(), v.P().Y(), v.P().Z()); 36 | return 1; 37 | } 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /samples/transformation_matrix/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | CMeshO mesh; 10 | tri::Tetrahedron(mesh); // create preset mesh data 11 | cout << "default" << endl; 12 | for(auto &&v:mesh.vert) 13 | printf("(%f,%f,%f)\n",v.P().X(), v.P().Y(), v.P().Z()); 14 | 15 | // meshlab\src\meshlabplugins\filter_meshing\meshfilter.cpp 16 | Matrix44m trRot, trTran, trTranInv, transfM; 17 | 18 | Point3m rotAxis = Point3m(1,0,0); 19 | Point3m rotCenter = Point3m(0,0,0); 20 | float angleDeg= 45.0; 21 | 22 | trRot.SetRotateDeg(angleDeg,rotAxis); 23 | trTran.SetTranslate(rotCenter); 24 | trTranInv.SetTranslate(-rotCenter); 25 | transfM = trTran*trRot*trTranInv; 26 | 27 | tri::UpdatePosition::Matrix(mesh, transfM); 28 | tri::UpdateBounding::Box(mesh); 29 | 30 | cout << "translated" << endl; 31 | for(auto &&v:mesh.vert) 32 | printf("(%f,%f,%f)\n",v.P().X(), v.P().Y(), v.P().Z()); 33 | return 1; 34 | } 35 | -------------------------------------------------------------------------------- /samples/user_defined_attr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 3.6 ) 2 | 3 | # Create Project 4 | get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME) 5 | string(REPLACE " " "_" ProjectId ${ProjectId}) 6 | project(${ProjectId} CXX) 7 | 8 | message(${ProjectId}) 9 | 10 | # If you use visual studio, set the character code to UTF8 11 | add_compile_options("$<$:/utf-8>") 12 | 13 | # In debug mode, add 'd' to the end of the executable file name 14 | if(NOT CMAKE_DEBUG_POSTFIX) 15 | set(CMAKE_DEBUG_POSTFIX d) 16 | endif() 17 | 18 | # set output file directory 19 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 20 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin) 21 | 22 | # define path of Eigen 23 | file(TO_CMAKE_PATH $ENV{EIGEN3_INCLUDE_DIR} EIGEN3_INCLUDE_DIR) 24 | # define path of vcglib 25 | file(TO_CMAKE_PATH $ENV{VCGLIB_DIR} VCGLIB_DIR) 26 | # define path of meshlab source 27 | file(TO_CMAKE_PATH $ENV{MESHLAB_DIR} MESHLAB_DIR) 28 | add_definitions(-DMESHLAB_SCALAR=float) # you should add this definition if you use meshlab source 29 | 30 | # set(VCGLIB_DIR C:/Users/Public/Documents/GitHub/vcglib) 31 | # set(MESHLAB_DIR C:/Users/Public/Documents/GitHub/meshlab_latest/src) 32 | 33 | # Add Executable 34 | add_executable(${PROJECT_NAME}) 35 | target_sources(${PROJECT_NAME} 36 | PRIVATE 37 | main.cpp 38 | # ${VCGLIB_DIR}/wrap/ply/plylib.cpp # if you deal with ply format, you should add this file 39 | ) 40 | target_include_directories(${PROJECT_NAME} 41 | PUBLIC 42 | ${EIGEN3_INCLUDE_DIR} 43 | ${VCGLIB_DIR} 44 | ${MESHLAB_DIR} 45 | ) 46 | 47 | set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 48 | -------------------------------------------------------------------------------- /samples/user_defined_attr/README.md: -------------------------------------------------------------------------------- 1 | http://vcg.isti.cnr.it/vcglib/attributes.html 2 | 3 | 4 | 5 | You can add original attribute to each vertices, faces, edges or meshes. 6 | 7 | ```cpp 8 | // define original attribute per vertex, face, mesh 9 | CMeshO::PerVertexAttributeHandle vert_ex_id; 10 | vert_ex_id = tri::Allocator::GetPerVertexAttribute(mesh, string("vert_ex_id")); 11 | 12 | CMeshO::PerFaceAttributeHandle face_ex_flag; 13 | face_ex_flag = tri::Allocator::GetPerFaceAttribute(mesh, string("face_ex_flag")); 14 | 15 | CMeshO::PerMeshAttributeHandle> mesh_ex_vect; 16 | mesh_ex_vect = tri::Allocator::GetPerMeshAttribute>(mesh, string("mesh_ex_vect")); 17 | 18 | // you can set/get user-defined attr via iterator, pointer, index, Vertex/FaceType 19 | cout << "vert attr" << endl; 20 | tri::Allocator::ClearPerVertexAttribute(mesh, vert_ex_id, -1); 21 | vert_ex_id[1] = 30; 22 | CMeshO::VertexIterator vi = mesh.vert.begin(); 23 | vert_ex_id[vi] = 10; 24 | CMeshO::VertexPointer vp = &(mesh.vert[3]); 25 | vert_ex_id[vp] = 100; 26 | for(CMeshO::VertexType &vt : mesh.vert) 27 | cout << vert_ex_id[vt] << endl; 28 | 29 | cout << "face attr" << endl; 30 | for(auto &&f : mesh.face) 31 | face_ex_flag[f] = false; 32 | CMeshO::FaceIterator fi = mesh.face.begin(); 33 | face_ex_flag[fi] = true; 34 | CMeshO::FacePointer fp = &(mesh.face[3]); 35 | face_ex_flag[fp] = true; 36 | for(CMeshO::FaceType &ft : mesh.face) 37 | cout << face_ex_flag[ft] << endl; 38 | 39 | // use vector attribute 40 | cout << "mesh attr" << endl; 41 | vector *pMeshVect = nullptr; 42 | pMeshVect = &mesh_ex_vect(); 43 | pMeshVect->clear(); 44 | for(int i=5; i<10; ++i) 45 | pMeshVect->push_back(i); 46 | for(auto &&a : *pMeshVect) 47 | cout << a << endl; 48 | ``` 49 | 50 | ## output 51 | 52 | ```shell 53 | vert attr 54 | 10 55 | 30 56 | -1 57 | 100 58 | face attr 59 | 1 60 | 0 61 | 0 62 | 1 63 | mesh attr 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | delete attr 70 | 1 71 | 0 72 | ``` 73 | 74 | -------------------------------------------------------------------------------- /samples/user_defined_attr/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace vcg; 6 | using namespace std; 7 | 8 | int main(){ 9 | CMeshO mesh; 10 | tri::Tetrahedron(mesh); // create preset mesh data 11 | 12 | // define original attribute per vertex, face, mesh 13 | CMeshO::PerVertexAttributeHandle vert_ex_id; 14 | vert_ex_id = tri::Allocator::GetPerVertexAttribute(mesh, string("vert_ex_id")); 15 | 16 | CMeshO::PerFaceAttributeHandle face_ex_flag; 17 | face_ex_flag = tri::Allocator::GetPerFaceAttribute(mesh, string("face_ex_flag")); 18 | 19 | CMeshO::PerMeshAttributeHandle> mesh_ex_vect; 20 | mesh_ex_vect = tri::Allocator::GetPerMeshAttribute>(mesh, string("mesh_ex_vect")); 21 | 22 | // you can set/get user-defined attr via iterator, pointer, index, Vertex/FaceType 23 | cout << "vert attr" << endl; 24 | tri::Allocator::ClearPerVertexAttribute(mesh, vert_ex_id, -1); 25 | vert_ex_id[1] = 30; 26 | CMeshO::VertexIterator vi = mesh.vert.begin(); 27 | vert_ex_id[vi] = 10; 28 | CMeshO::VertexPointer vp = &(mesh.vert[3]); 29 | vert_ex_id[vp] = 100; 30 | for(CMeshO::VertexType &vt : mesh.vert) 31 | cout << vert_ex_id[vt] << endl; 32 | 33 | cout << "face attr" << endl; 34 | for(auto &&f : mesh.face) 35 | face_ex_flag[f] = false; 36 | CMeshO::FaceIterator fi = mesh.face.begin(); 37 | face_ex_flag[fi] = true; 38 | CMeshO::FacePointer fp = &(mesh.face[3]); 39 | face_ex_flag[fp] = true; 40 | for(CMeshO::FaceType &ft : mesh.face) 41 | cout << face_ex_flag[ft] << endl; 42 | 43 | // use vector attribute 44 | cout << "mesh attr" << endl; 45 | vector *pMeshVect = nullptr; 46 | pMeshVect = &mesh_ex_vect(); 47 | pMeshVect->clear(); 48 | for(int i=5; i<10; ++i) 49 | pMeshVect->push_back(i); 50 | for(auto &&a : *pMeshVect) 51 | cout << a << endl; 52 | 53 | // you can delete attribute 54 | cout << "delete attr" << endl; 55 | cout << tri::Allocator::IsValidHandle(mesh, vert_ex_id) << endl; 56 | tri::Allocator::DeletePerVertexAttribute(mesh, string("vert_ex_id")); 57 | cout << tri::Allocator::IsValidHandle(mesh, vert_ex_id) << endl; 58 | 59 | return 1; 60 | } 61 | 62 | --------------------------------------------------------------------------------