|
28 | 28 |
|
29 | 29 | #include <bitsery/brief_syntax/array.h> |
30 | 30 |
|
| 31 | +#include <geode/basic/attribute.h> |
31 | 32 | #include <geode/basic/attribute_manager.h> |
32 | 33 | #include <geode/basic/bitsery_archive.h> |
33 | 34 | #include <geode/basic/cached_value.h> |
34 | 35 | #include <geode/basic/detail/mapping_after_deletion.h> |
35 | 36 | #include <geode/basic/pimpl_impl.h> |
36 | 37 |
|
| 38 | +#include <geode/geometry/basic_objects/infinite_line.h> |
| 39 | +#include <geode/geometry/basic_objects/segment.h> |
37 | 40 | #include <geode/geometry/basic_objects/triangle.h> |
38 | 41 | #include <geode/geometry/bounding_box.h> |
39 | 42 | #include <geode/geometry/distance.h> |
40 | 43 | #include <geode/geometry/mensuration.h> |
41 | 44 |
|
42 | 45 | #include <geode/mesh/builder/surface_edges_builder.h> |
43 | 46 | #include <geode/mesh/builder/surface_mesh_builder.h> |
| 47 | +#include <geode/mesh/builder/triangulated_surface_builder.h> |
44 | 48 | #include <geode/mesh/core/detail/facet_storage.h> |
45 | 49 | #include <geode/mesh/core/mesh_factory.h> |
46 | 50 | #include <geode/mesh/core/polygonal_surface.h> |
47 | 51 | #include <geode/mesh/core/private/surface_mesh_impl.h> |
48 | 52 | #include <geode/mesh/core/surface_edges.h> |
49 | 53 | #include <geode/mesh/core/texture2d.h> |
50 | 54 | #include <geode/mesh/core/texture_storage.h> |
| 55 | +#include <geode/mesh/core/triangulated_surface.h> |
| 56 | +#include <geode/mesh/io/triangulated_surface_output.h> |
51 | 57 |
|
52 | 58 | namespace |
53 | 59 | { |
@@ -98,6 +104,25 @@ namespace |
98 | 104 | "edge" ); |
99 | 105 | } |
100 | 106 |
|
| 107 | + template < geode::index_t dimension > |
| 108 | + void output( const geode::SurfaceMesh< dimension >& mesh ) |
| 109 | + { |
| 110 | + auto surf = geode::TriangulatedSurface< dimension >::create(); |
| 111 | + auto bui = |
| 112 | + geode::TriangulatedSurfaceBuilder< dimension >::create( *surf ); |
| 113 | + for( const auto v : geode::Range{ mesh.nb_vertices() } ) |
| 114 | + { |
| 115 | + bui->create_point( mesh.point( v ) ); |
| 116 | + } |
| 117 | + for( const auto p : geode::Range{ mesh.nb_polygons() } ) |
| 118 | + { |
| 119 | + const auto vertices = mesh.polygon_vertices( p ); |
| 120 | + bui->create_triangle( { vertices[0], vertices[1], vertices[2] } ); |
| 121 | + } |
| 122 | + bui->delete_isolated_vertices(); |
| 123 | + geode::save_triangulated_surface( *surf, "output.og_tsf3d" ); |
| 124 | + } |
| 125 | + |
101 | 126 | template < geode::index_t dimension > |
102 | 127 | geode::detail::PolygonsAroundVertexImpl compute_polygons_around_vertex( |
103 | 128 | const geode::SurfaceMesh< dimension >& mesh, |
@@ -147,6 +172,10 @@ namespace |
147 | 172 | safety_count++; |
148 | 173 | } |
149 | 174 | } |
| 175 | + if( safety_count >= MAX_SAFETY_COUNT ) |
| 176 | + { |
| 177 | + output( mesh ); |
| 178 | + } |
150 | 179 | OPENGEODE_EXCEPTION( safety_count < MAX_SAFETY_COUNT, |
151 | 180 | "[SurfaceMesh::polygons_around_vertex] Too many polygons " |
152 | 181 | "around vertex ", |
@@ -1051,6 +1080,48 @@ namespace geode |
1051 | 1080 | } |
1052 | 1081 | } |
1053 | 1082 |
|
| 1083 | + template < index_t dimension > |
| 1084 | + bool SurfaceMesh< dimension >::is_polygon_degenerated( |
| 1085 | + index_t polygon_id ) const |
| 1086 | + { |
| 1087 | + double max_length{ 0. }; |
| 1088 | + local_index_t max_length_edge{ 0 }; |
| 1089 | + for( const auto e : LRange{ nb_polygon_edges( polygon_id ) } ) |
| 1090 | + { |
| 1091 | + const auto cur_length = edge_length( PolygonEdge{ polygon_id, e } ); |
| 1092 | + if( cur_length > max_length ) |
| 1093 | + { |
| 1094 | + max_length = cur_length; |
| 1095 | + max_length_edge = e; |
| 1096 | + } |
| 1097 | + } |
| 1098 | + if( max_length < global_epsilon ) |
| 1099 | + { |
| 1100 | + return true; |
| 1101 | + } |
| 1102 | + const auto vertices = polygon_vertices( polygon_id ); |
| 1103 | + const auto next = |
| 1104 | + max_length_edge + 1 == nb_polygon_vertices( polygon_id ) |
| 1105 | + ? 0 |
| 1106 | + : max_length_edge + 1; |
| 1107 | + InfiniteLine< dimension > line{ Segment< dimension >{ |
| 1108 | + this->point( vertices[max_length_edge] ), |
| 1109 | + this->point( vertices[next] ) } }; |
| 1110 | + for( const auto v : LIndices{ vertices } ) |
| 1111 | + { |
| 1112 | + if( v == max_length_edge || v == next ) |
| 1113 | + { |
| 1114 | + continue; |
| 1115 | + } |
| 1116 | + if( point_line_distance( this->point( vertices[v] ), line ) |
| 1117 | + > global_epsilon ) |
| 1118 | + { |
| 1119 | + return false; |
| 1120 | + } |
| 1121 | + } |
| 1122 | + return true; |
| 1123 | + } |
| 1124 | + |
1054 | 1125 | template < index_t dimension > |
1055 | 1126 | std::unique_ptr< SurfaceMesh< dimension > > |
1056 | 1127 | SurfaceMesh< dimension >::clone() const |
|
0 commit comments