diff --git a/include/geode/geometry/basic_objects/infinite_line.hpp b/include/geode/geometry/basic_objects/infinite_line.hpp index e7eb04497..df271a2db 100644 --- a/include/geode/geometry/basic_objects/infinite_line.hpp +++ b/include/geode/geometry/basic_objects/infinite_line.hpp @@ -31,10 +31,7 @@ namespace geode FORWARD_DECLARATION_DIMENSION_CLASS( OwnerInfiniteLine ); FORWARD_DECLARATION_DIMENSION_CLASS( OwnerRay ); FORWARD_DECLARATION_DIMENSION_CLASS( Point ); - template < typename PointType, index_t dimension > - class GenericSegment; FORWARD_DECLARATION_DIMENSION_CLASS( Segment ); - FORWARD_DECLARATION_DIMENSION_CLASS( OwnerSegment ); template < index_t dimension > using RefPoint = std::reference_wrapper< const Point< dimension > >; @@ -47,9 +44,7 @@ namespace geode { public: GenericLine( const Vector< dimension >& direction, PointType origin ); - - explicit GenericLine( - const GenericSegment< PointType, dimension >& segment ); + explicit GenericLine( const Segment< dimension >& segment ); GenericLine( const GenericLine< PointType, dimension >& other ); GenericLine< PointType, dimension >& operator=( const GenericLine< PointType, dimension >& other ); @@ -75,7 +70,7 @@ namespace geode explicit OwnerInfiniteLine( const Vector< dimension >& direction, Point< dimension > origin ); - OwnerInfiniteLine( const Segment< dimension >& segment ); + explicit OwnerInfiniteLine( const Segment< dimension >& segment ); OwnerInfiniteLine( const OwnerInfiniteLine< dimension >& other ); OwnerInfiniteLine< dimension >& operator=( const OwnerInfiniteLine< dimension >& other ); @@ -94,7 +89,7 @@ namespace geode explicit OwnerRay( const Vector< dimension >& direction, Point< dimension > origin ); - OwnerRay( const Segment< dimension >& segment ); + explicit OwnerRay( const Segment< dimension >& segment ); OwnerRay( const OwnerRay< dimension >& other ); OwnerRay< dimension >& operator=( const OwnerRay< dimension >& other ); OwnerRay( OwnerRay< dimension >&& other ) noexcept; @@ -111,7 +106,7 @@ namespace geode public: InfiniteLine( const Vector< dimension >& direction, const Point< dimension >& origin ); - InfiniteLine( const Segment< dimension >& segment ); + explicit InfiniteLine( const Segment< dimension >& segment ); InfiniteLine( const InfiniteLine< dimension >& other ); InfiniteLine( const OwnerInfiniteLine< dimension >& other ); diff --git a/include/geode/geometry/basic_objects/plane.hpp b/include/geode/geometry/basic_objects/plane.hpp index 1e9149ef5..9614b1fd3 100644 --- a/include/geode/geometry/basic_objects/plane.hpp +++ b/include/geode/geometry/basic_objects/plane.hpp @@ -29,6 +29,8 @@ namespace geode { FORWARD_DECLARATION_DIMENSION_CLASS( Point ); + FORWARD_DECLARATION_DIMENSION_CLASS( Triangle ); + ALIAS_3D( Triangle ); class OwnerPlane; template < index_t dimension > @@ -43,7 +45,7 @@ namespace geode { public: GenericPlane( const Vector3D& normal, PointType origin ); - + explicit GenericPlane( const Triangle3D& triangle ); GenericPlane( const GenericPlane& other ); GenericPlane& operator=( const GenericPlane& other ); GenericPlane( GenericPlane&& other ) noexcept; @@ -64,6 +66,7 @@ namespace geode public: explicit OwnerPlane( const Vector3D& normal, Point3D origin ); + explicit OwnerPlane( const Triangle3D& triangle ); OwnerPlane( const OwnerPlane& other ); OwnerPlane& operator=( const OwnerPlane& other ); OwnerPlane( OwnerPlane&& other ) noexcept; @@ -76,7 +79,7 @@ namespace geode public: Plane( const Vector3D& normal, const Point3D& origin ); - + explicit Plane( const Triangle3D& triangle ); Plane( const Plane& other ); Plane( const OwnerPlane& other ); Plane& operator=( const Plane& other ); diff --git a/include/geode/geometry/basic_objects/segment.hpp b/include/geode/geometry/basic_objects/segment.hpp index c80261197..da9ecbd25 100644 --- a/include/geode/geometry/basic_objects/segment.hpp +++ b/include/geode/geometry/basic_objects/segment.hpp @@ -60,6 +60,7 @@ namespace geode void set_point( local_index_t vertex, PointType point ); [[nodiscard]] const std::array< PointType, 2 >& vertices() const; [[nodiscard]] BoundingBox< dimension > bounding_box() const; + [[nodiscard]] bool is_degenerated() const; private: std::array< PointType, 2 > vertices_; diff --git a/include/geode/geometry/basic_objects/tetrahedron.hpp b/include/geode/geometry/basic_objects/tetrahedron.hpp index 60693e6b5..9b60addc2 100644 --- a/include/geode/geometry/basic_objects/tetrahedron.hpp +++ b/include/geode/geometry/basic_objects/tetrahedron.hpp @@ -64,6 +64,7 @@ namespace geode void set_point( local_index_t vertex, PointType point ); [[nodiscard]] const std::array< PointType, 4 >& vertices() const; [[nodiscard]] BoundingBox3D bounding_box() const; + [[nodiscard]] bool is_degenerated() const; private: std::array< PointType, 4 > vertices_; diff --git a/include/geode/geometry/basic_objects/triangle.hpp b/include/geode/geometry/basic_objects/triangle.hpp index 61da1433e..6975703f0 100644 --- a/include/geode/geometry/basic_objects/triangle.hpp +++ b/include/geode/geometry/basic_objects/triangle.hpp @@ -85,6 +85,7 @@ namespace geode [[nodiscard]] BoundingBox< dimension > bounding_box() const; [[nodiscard]] local_index_t longest_edge_index() const; [[nodiscard]] double minimum_height() const; + [[nodiscard]] bool is_degenerated() const; private: std::array< PointType, 3 > vertices_; diff --git a/src/geode/geometry/basic_objects/infinite_line.cpp b/src/geode/geometry/basic_objects/infinite_line.cpp index 8ac65eddb..5b91b9309 100644 --- a/src/geode/geometry/basic_objects/infinite_line.cpp +++ b/src/geode/geometry/basic_objects/infinite_line.cpp @@ -35,7 +35,7 @@ namespace geode } template < typename PointType, index_t dimension > GenericLine< PointType, dimension >::GenericLine( - const GenericSegment< PointType, dimension >& segment ) + const Segment< dimension >& segment ) : GenericLine( segment.normalized_direction(), segment.vertices()[0] ) { } @@ -77,8 +77,7 @@ namespace geode template < index_t dimension > OwnerInfiniteLine< dimension >::OwnerInfiniteLine( const Segment< dimension >& segment ) - : OwnerInfiniteLine( - segment.normalized_direction(), segment.vertices()[0] ) + : Base( segment ) { } template < index_t dimension > @@ -104,7 +103,7 @@ namespace geode template < index_t dimension > InfiniteLine< dimension >::InfiniteLine( const Segment< dimension >& segment ) - : InfiniteLine( segment.normalized_direction(), segment.vertices()[0] ) + : Base( segment ) { } template < index_t dimension > @@ -135,7 +134,7 @@ namespace geode } template < index_t dimension > OwnerRay< dimension >::OwnerRay( const Segment< dimension >& segment ) - : OwnerRay( segment.normalized_direction(), segment.vertices()[0] ) + : Base( segment ) { } template < index_t dimension > @@ -159,7 +158,7 @@ namespace geode } template < index_t dimension > Ray< dimension >::Ray( const Segment< dimension >& segment ) - : Ray( segment.normalized_direction(), segment.vertices()[0] ) + : Base( segment ) { } template < index_t dimension > diff --git a/src/geode/geometry/basic_objects/plane.cpp b/src/geode/geometry/basic_objects/plane.cpp index c199f1869..87b3b623c 100644 --- a/src/geode/geometry/basic_objects/plane.cpp +++ b/src/geode/geometry/basic_objects/plane.cpp @@ -23,6 +23,8 @@ #include +#include + namespace geode { template < typename PointType > @@ -31,6 +33,13 @@ namespace geode : normal_( normal.normalize() ), origin_( std::move( origin ) ) { } + template < typename PointType > + GenericPlane< PointType >::GenericPlane( const Triangle3D& triangle ) + : normal_( triangle.normal().value() ), + origin_( triangle.vertices()[0] ) + { + } + template < typename PointType > GenericPlane< PointType >::GenericPlane( const GenericPlane& ) = default; template < typename PointType > @@ -69,6 +78,8 @@ namespace geode : Base( normal, std::move( origin ) ) { } + OwnerPlane::OwnerPlane( const Triangle3D& triangle ) : Base( triangle ) {} + OwnerPlane::OwnerPlane( const OwnerPlane& ) = default; OwnerPlane& OwnerPlane::operator=( const OwnerPlane& ) = default; OwnerPlane::OwnerPlane( OwnerPlane&& ) noexcept = default; @@ -78,6 +89,8 @@ namespace geode : Base( normal, origin ) { } + Plane::Plane( const Triangle3D& triangle ) : Base( triangle ) {} + Plane::Plane( const Plane& ) = default; Plane::Plane( const OwnerPlane& other ) : Base( other.normal(), other.origin() ) diff --git a/src/geode/geometry/basic_objects/segment.cpp b/src/geode/geometry/basic_objects/segment.cpp index 33c992a90..9df8bc8cb 100644 --- a/src/geode/geometry/basic_objects/segment.cpp +++ b/src/geode/geometry/basic_objects/segment.cpp @@ -102,6 +102,12 @@ namespace geode return bbox; } + template < typename PointType, index_t dimension > + bool GenericSegment< PointType, dimension >::is_degenerated() const + { + return length() <= GLOBAL_EPSILON; + } + template < index_t dimension > OwnerSegment< dimension >::OwnerSegment( Point< dimension > point0, Point< dimension > point1 ) noexcept diff --git a/src/geode/geometry/basic_objects/tetrahedron.cpp b/src/geode/geometry/basic_objects/tetrahedron.cpp index dfcf16283..7c58606fc 100644 --- a/src/geode/geometry/basic_objects/tetrahedron.cpp +++ b/src/geode/geometry/basic_objects/tetrahedron.cpp @@ -23,7 +23,10 @@ #include +#include +#include #include +#include namespace geode { @@ -79,6 +82,23 @@ namespace geode return bbox; } + template < typename PointType > + bool GenericTetrahedron< PointType >::is_degenerated() const + { + const Point3D& point0 = vertices_.at( 0 ); + const Point3D& point1 = vertices_.at( 1 ); + const Point3D& point2 = vertices_.at( 2 ); + const Triangle3D triangle{ point0, point1, point2 }; + if( triangle.is_degenerated() ) + { + return true; + } + const Point3D& point3 = vertices_.at( 3 ); + return std::get< 0 >( + point_plane_distance( point3, Plane{ triangle } ) ) + <= GLOBAL_EPSILON; + } + OwnerTetrahedron::OwnerTetrahedron( Point3D point0, Point3D point1, Point3D point2, diff --git a/src/geode/geometry/basic_objects/triangle.cpp b/src/geode/geometry/basic_objects/triangle.cpp index cff221256..d88f5584f 100644 --- a/src/geode/geometry/basic_objects/triangle.cpp +++ b/src/geode/geometry/basic_objects/triangle.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -269,6 +270,21 @@ namespace geode return point_segment_distance( opposite_vertex, longest_edge ); } + template < typename PointType, index_t dimension > + bool GenericTriangle< PointType, dimension >::is_degenerated() const + { + const Point< dimension >& point0 = vertices_.at( 0 ); + const Point< dimension >& point1 = vertices_.at( 1 ); + const Segment< dimension > edge{ point0, point1 }; + if( edge.is_degenerated() ) + { + return true; + } + const Point< dimension >& point2 = vertices_.at( 2 ); + return point_line_distance( point2, InfiniteLine< dimension >{ edge } ) + <= GLOBAL_EPSILON; + } + template < index_t dimension > OwnerTriangle< dimension >::OwnerTriangle( Point< dimension > point0, Point< dimension > point1, diff --git a/src/geode/mesh/helpers/rasterize.cpp b/src/geode/mesh/helpers/rasterize.cpp index a74e39b13..890587688 100644 --- a/src/geode/mesh/helpers/rasterize.cpp +++ b/src/geode/mesh/helpers/rasterize.cpp @@ -537,6 +537,7 @@ namespace const geode::Segment2D segment_in_grid{ pt0_in_grid, pt1_in_grid }; const auto normal_in_grid = geode::perpendicular( segment_in_grid.direction() ); + const geode::InfiniteLine2D line_in_grid{ segment_in_grid }; const auto critical_point = compute_critical_point( normal_in_grid ); for( const auto j : geode::Range( min[1], max[1] + 1 ) ) @@ -549,13 +550,13 @@ namespace // Test segment line through box const auto p_minus = point + critical_point; - const auto p_minus_dist = geode::point_line_signed_distance( - p_minus, { segment_in_grid } ); + const auto p_minus_dist = + geode::point_line_signed_distance( p_minus, line_in_grid ); const geode::Point2D p_plus{ { 1. + i - critical_point.value( 0 ), 1. + j - critical_point.value( 1 ) } }; - const auto p_plus_dist = geode::point_line_signed_distance( - p_plus, { segment_in_grid } ); + const auto p_plus_dist = + geode::point_line_signed_distance( p_plus, line_in_grid ); if( std::fabs( p_minus_dist ) > 2. * geode::GLOBAL_EPSILON && std::fabs( p_plus_dist ) > 2. * geode::GLOBAL_EPSILON && p_minus_dist * p_plus_dist > 0. ) diff --git a/src/geode/model/helpers/surface_radial_sort.cpp b/src/geode/model/helpers/surface_radial_sort.cpp index 3343cc17a..341b9d8dd 100644 --- a/src/geode/model/helpers/surface_radial_sort.cpp +++ b/src/geode/model/helpers/surface_radial_sort.cpp @@ -89,17 +89,6 @@ namespace geode::Point3D opposite_point; }; - bool is_polygon_degenerate( const geode::SurfaceMesh3D& mesh, - const geode::PolygonEdge& edge, - const geode::Point3D& opposite_point ) - { - const auto edge_vertices = mesh.polygon_edge_vertices( edge ); - return geode::point_line_distance( opposite_point, - { geode::Segment3D{ mesh.point( edge_vertices[0] ), - mesh.point( edge_vertices[1] ) } } ) - <= geode::GLOBAL_EPSILON; - } - std::pair< bool, std::vector< BorderPolygon > > border_polygons( const geode::BRep& brep, const geode::Line3D& line, @@ -126,20 +115,18 @@ namespace { polygons.emplace_back( surface, true, std::move( edge0.value() ) ); - degenerate_polygon = - degenerate_polygon - || is_polygon_degenerate( surface_mesh, edge0.value(), - polygons.back().opposite_point ); + degenerate_polygon = degenerate_polygon + || surface_mesh.is_polygon_degenerated( + edge0->polygon_id ); } if( auto edge1 = surface_mesh.polygon_edge_from_vertices( pair[1], pair[0] ) ) { polygons.emplace_back( surface, false, std::move( edge1.value() ) ); - degenerate_polygon = - degenerate_polygon - || is_polygon_degenerate( surface_mesh, edge1.value(), - polygons.back().opposite_point ); + degenerate_polygon = degenerate_polygon + || surface_mesh.is_polygon_degenerated( + edge1->polygon_id ); } } }