/
spivag
/
command_occ
Обзор
Документация
Войти
/
spivag
/
command_occ
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
initial
commands/shape_iterator.cpp
621 строка
16 KB
Степанов Никита
Запрос на слияние 'topology_iterators' (
#3
) из topology_iterators в initial
27 апр 2026, 21:55
Верифицирован
27 апр 2026, 21:55
c047a95
Код
Авторство
О чём код?
#include <shape_iterator.h> #include <shape_command.h> #include <unordered_map> #include <vector> #include <sstream> #include <limits> MissingKernelObjectException::MissingKernelObjectException( std::string const& message ) : std::runtime_error{ message.c_str() } { } // Хранилища цвета и состояния выделения для топологических элементов. // Ключ — хэш-код фигуры (TopoDS_Shape::HashCode). static std::unordered_map< int, uint32_t > g_shapeColours; static std::unordered_map< int, bool > g_shapeSelected; static std::string HashToString( int hash ) { std::ostringstream oss; oss << hash; return oss.str(); } //---------------------------------------------------------------------------------------- // Реализация паттерна «Посетитель» // --- void TopologyHandle::Accept( TopologyVisitor& visitor ) const { visitor.Visit( *this ); } void IBrepFaceHandle::Accept( TopologyVisitor& visitor ) const { visitor.Visit( *this ); } void IBrepEdgeHandle::Accept( TopologyVisitor& visitor ) const { visitor.Visit( *this ); } void IBrepVertexHandle::Accept( TopologyVisitor& visitor ) const { visitor.Visit( *this ); } //---------------------------------------------------------------------------------------- // Базовый итератор // --- ShapeIterator::ShapeIterator( std::weak_ptr< IShapeBuilder > const& shape ) : m_baseShape{ shape } { } std::weak_ptr< IShapeBuilder > ShapeIterator::Shape() const { return m_baseShape; } //======================================================================================== // Провайдер граней //======================================================================================== class IBrepFaceHandleImpl : public IBrepFaceHandle { OCCFace m_face; public: explicit IBrepFaceHandleImpl( OCCFace const& face ) : m_face{ face } { } [[nodiscard]] R3::Gabarit Gabarit() const override { return m_face.GetBounds(); } std::string GetIdentifier() const override { return HashToString( m_face.HashCode() ); } std::optional< uint32_t > GetColour() const override { auto it = g_shapeColours.find( m_face.HashCode() ); return it != g_shapeColours.end() ? std::optional< uint32_t >{ it->second } : std::nullopt; } bool IsSelected() const override { auto it = g_shapeSelected.find( m_face.HashCode() ); return it != g_shapeSelected.end() && it->second; } bool SetColour( uint32_t rgba ) override { if ( m_face.IsNull() ) return false; g_shapeColours[m_face.HashCode()] = rgba; return true; } bool SetSelectedFlag( bool setSelected ) override { if ( m_face.IsNull() ) return false; g_shapeSelected[m_face.HashCode()] = setSelected; return true; } void RemoveMaterial() override { if ( !m_face.IsNull() ) g_shapeColours.erase( m_face.HashCode() ); } std::shared_ptr< IFace > GetFace() const override { return std::make_shared< OCCFace >( m_face ); } }; //======================================================================================== // Итератор граней тела //======================================================================================== IFaceBrepIterator::IFaceBrepIterator( std::weak_ptr< IShapeBuilder > const& shape ) : ShapeIterator{ shape } { } class FaceBrepIterator : public IFaceBrepIterator { std::vector< OCCFace > m_faces; mutable size_t m_index{ 0 }; mutable std::shared_ptr< IBrepFaceHandleImpl > m_currentHandle{}; public: bool HasNext() const override { return m_index < m_faces.size(); } std::shared_ptr< TopologyHandle > Next() const override { if ( m_index < m_faces.size() ) { m_currentHandle = std::make_shared< IBrepFaceHandleImpl >( m_faces[m_index] ); ++m_index; return m_currentHandle; } return {}; } std::shared_ptr< IBrepFaceHandle > FaceHandle() const override { return m_currentHandle; } static std::shared_ptr< FaceBrepIterator > Create( std::weak_ptr< IShapeBuilder > const& shapeBuilder ) { auto sp = shapeBuilder.lock(); if ( !sp ) return {}; auto occShape = std::dynamic_pointer_cast< OCCShape >( sp->GetShape() ); if ( !occShape || occShape->IsNull() ) return {}; return std::shared_ptr< FaceBrepIterator >{ new FaceBrepIterator{ shapeBuilder, *occShape } }; } protected: FaceBrepIterator( std::weak_ptr< IShapeBuilder > const& shapeBuilder, OCCShape const& shape ) : IFaceBrepIterator{ shapeBuilder } , m_faces{ GetFaces( shape ) } { } }; //======================================================================================== // Провайдер рёбер //======================================================================================== class IBrepEdgeHandleImpl : public IBrepEdgeHandle { OCCEdge m_edge; OCCShape m_parentShape; public: explicit IBrepEdgeHandleImpl( OCCEdge const& edge ) : m_edge{ edge } { } IBrepEdgeHandleImpl( OCCEdge const& edge, OCCShape const& parentShape ) : m_edge{ edge } , m_parentShape{ parentShape } { } OCCShape const& GetParentShape() const { return m_parentShape; } [[nodiscard]] R3::Gabarit Gabarit() const override { return m_edge.GetBounds(); } std::string GetIdentifier() const override { return HashToString( m_edge.HashCode() ); } [[nodiscard]] double Length() const override { return m_edge.Length(); } std::optional< uint32_t > GetColour() const override { auto it = g_shapeColours.find( m_edge.HashCode() ); return it != g_shapeColours.end() ? std::optional< uint32_t >{ it->second } : std::nullopt; } bool IsSelected() const override { auto it = g_shapeSelected.find( m_edge.HashCode() ); return it != g_shapeSelected.end() && it->second; } bool SetColour( uint32_t rgba ) override { if ( m_edge.IsNull() ) return false; g_shapeColours[m_edge.HashCode()] = rgba; return true; } bool SetSelectedFlag( bool setSelected ) override { if ( m_edge.IsNull() ) return false; g_shapeSelected[m_edge.HashCode()] = setSelected; return true; } void RemoveMaterial() override { if ( !m_edge.IsNull() ) g_shapeColours.erase( m_edge.HashCode() ); } std::shared_ptr< IEdge > GetEdge() const override { return std::make_shared< OCCEdge >( m_edge ); } }; //======================================================================================== // Итератор рёбер тела //======================================================================================== IEdgeBrepIterator::IEdgeBrepIterator( std::weak_ptr< IShapeBuilder > const& shape ) : ShapeIterator{ shape } { } class EdgeBrepIterator : public IEdgeBrepIterator { std::vector< OCCEdge > m_edges; OCCShape m_shape; mutable size_t m_index{ 0 }; mutable std::shared_ptr< IBrepEdgeHandleImpl > m_currentHandle{}; public: bool HasNext() const override { return m_index < m_edges.size(); } std::shared_ptr< TopologyHandle > Next() const override { if ( m_index < m_edges.size() ) { m_currentHandle = std::make_shared< IBrepEdgeHandleImpl >( m_edges[m_index], m_shape ); ++m_index; return m_currentHandle; } return {}; } std::shared_ptr< IBrepEdgeHandle > EdgeHandle() const override { return m_currentHandle; } static std::shared_ptr< EdgeBrepIterator > Create( std::weak_ptr< IShapeBuilder > const& shapeBuilder ) { auto sp = shapeBuilder.lock(); if ( !sp ) return {}; auto occShape = std::dynamic_pointer_cast< OCCShape >( sp->GetShape() ); if ( !occShape || occShape->IsNull() ) return {}; return std::shared_ptr< EdgeBrepIterator >{ new EdgeBrepIterator{ shapeBuilder, *occShape } }; } protected: EdgeBrepIterator( std::weak_ptr< IShapeBuilder > const& shapeBuilder, OCCShape const& shape ) : IEdgeBrepIterator{ shapeBuilder } , m_edges{ GetEdges( shape ) } , m_shape{ shape } { } }; //======================================================================================== // Провайдер вершин //======================================================================================== class IBrepVertexHandleImpl : public IBrepVertexHandle { OCCVertex m_vertex; public: explicit IBrepVertexHandleImpl( OCCVertex const& vertex ) : m_vertex{ vertex } { } [[nodiscard]] R3::Point Geometry() const override { return m_vertex.GetPoint(); } [[nodiscard]] R3::Gabarit Gabarit() const override { return m_vertex.GetBounds(); } std::string GetIdentifier() const override { return HashToString( m_vertex.HashCode() ); } std::optional< uint32_t > GetColour() const override { auto it = g_shapeColours.find( m_vertex.HashCode() ); return it != g_shapeColours.end() ? std::optional< uint32_t >{ it->second } : std::nullopt; } bool IsSelected() const override { auto it = g_shapeSelected.find( m_vertex.HashCode() ); return it != g_shapeSelected.end() && it->second; } bool SetColour( uint32_t rgba ) override { if ( m_vertex.IsNull() ) return false; g_shapeColours[m_vertex.HashCode()] = rgba; return true; } bool SetSelectedFlag( bool setSelected ) override { if ( m_vertex.IsNull() ) return false; g_shapeSelected[m_vertex.HashCode()] = setSelected; return true; } void RemoveMaterial() override { if ( !m_vertex.IsNull() ) g_shapeColours.erase( m_vertex.HashCode() ); } std::shared_ptr< IVertex > GetVertex() const override { return std::make_shared< OCCVertex >( m_vertex ); } }; //======================================================================================== // Итератор вершин тела //======================================================================================== IVertexBrepIterator::IVertexBrepIterator( std::weak_ptr< IShapeBuilder > const& shape ) : ShapeIterator{ shape } { } class VertexBrepIterator : public IVertexBrepIterator { std::vector< OCCVertex > m_vertices; mutable size_t m_index{ 0 }; mutable std::shared_ptr< IBrepVertexHandleImpl > m_currentHandle{}; public: bool HasNext() const override { return m_index < m_vertices.size(); } std::shared_ptr< TopologyHandle > Next() const override { if ( m_index < m_vertices.size() ) { m_currentHandle = std::make_shared< IBrepVertexHandleImpl >( m_vertices[m_index] ); ++m_index; return m_currentHandle; } return {}; } std::shared_ptr< IBrepVertexHandle > VertexHandle() const override { return m_currentHandle; } static std::shared_ptr< VertexBrepIterator > Create( std::weak_ptr< IShapeBuilder > const& shapeBuilder ) { auto sp = shapeBuilder.lock(); if ( !sp ) return {}; auto occShape = std::dynamic_pointer_cast< OCCShape >( sp->GetShape() ); if ( !occShape || occShape->IsNull() ) return {}; return std::shared_ptr< VertexBrepIterator >{ new VertexBrepIterator{ shapeBuilder, *occShape } }; } protected: VertexBrepIterator( std::weak_ptr< IShapeBuilder > const& shapeBuilder, OCCShape const& shape ) : IVertexBrepIterator{ shapeBuilder } , m_vertices{ GetVertices( shape ) } { } }; //======================================================================================== // Итератор рёбер грани //======================================================================================== class EdgeFaceIterator : public IEdgeBrepIterator { std::vector< OCCEdge > m_edges; mutable size_t m_index{ 0 }; mutable std::shared_ptr< IBrepEdgeHandleImpl > m_currentHandle{}; public: bool HasNext() const override { return m_index < m_edges.size(); } std::shared_ptr< TopologyHandle > Next() const override { if ( m_index < m_edges.size() ) { m_currentHandle = std::make_shared< IBrepEdgeHandleImpl >( m_edges[m_index] ); ++m_index; return m_currentHandle; } return {}; } std::shared_ptr< IBrepEdgeHandle > EdgeHandle() const override { return m_currentHandle; } static std::shared_ptr< EdgeFaceIterator > Create( OCCFace const& face ) { return std::shared_ptr< EdgeFaceIterator >{ new EdgeFaceIterator{ face } }; } protected: explicit EdgeFaceIterator( OCCFace const& face ) : IEdgeBrepIterator{ {} } , m_edges{ GetEdges( face ) } { } }; //======================================================================================== // Итератор граней ребра (смежные грани) //======================================================================================== class FaceEdgeIterator : public IFaceBrepIterator { std::vector< OCCFace > m_faces; mutable size_t m_index{ 0 }; mutable std::shared_ptr< IBrepFaceHandleImpl > m_currentHandle{}; public: bool HasNext() const override { return m_index < m_faces.size(); } std::shared_ptr< TopologyHandle > Next() const override { if ( m_index < m_faces.size() ) { m_currentHandle = std::make_shared< IBrepFaceHandleImpl >( m_faces[m_index] ); ++m_index; return m_currentHandle; } return {}; } std::shared_ptr< IBrepFaceHandle > FaceHandle() const override { return m_currentHandle; } static std::shared_ptr< FaceEdgeIterator > Create( std::vector< OCCFace > const& faces ) { return std::shared_ptr< FaceEdgeIterator >{ new FaceEdgeIterator{ faces } }; } protected: explicit FaceEdgeIterator( std::vector< OCCFace > const& faces ) : IFaceBrepIterator{ {} } , m_faces{ faces } { } }; //======================================================================================== // Итератор вершин ребра //======================================================================================== class VertexEdgeIterator : public IVertexBrepIterator { std::vector< OCCVertex > m_vertices; mutable size_t m_index{ 0 }; mutable std::shared_ptr< IBrepVertexHandleImpl > m_currentHandle{}; public: bool HasNext() const override { return m_index < m_vertices.size(); } std::shared_ptr< TopologyHandle > Next() const override { if ( m_index < m_vertices.size() ) { m_currentHandle = std::make_shared< IBrepVertexHandleImpl >( m_vertices[m_index] ); ++m_index; return m_currentHandle; } return {}; } std::shared_ptr< IBrepVertexHandle > VertexHandle() const override { return m_currentHandle; } static std::shared_ptr< VertexEdgeIterator > Create( OCCEdge const& edge ) { return std::shared_ptr< VertexEdgeIterator >{ new VertexEdgeIterator{ edge } }; } protected: explicit VertexEdgeIterator( OCCEdge const& edge ) : IVertexBrepIterator{ {} } , m_vertices{ GetVertices( edge ) } { } }; //======================================================================================== // Фабричные функции //======================================================================================== std::shared_ptr< IFaceBrepIterator > CreateFaceIterator( std::shared_ptr< IShapeBuilder > const& shape ) { return FaceBrepIterator::Create( shape ); } std::shared_ptr< IEdgeBrepIterator > CreateEdgeIterator( std::shared_ptr< IShapeBuilder > const& shape ) { return EdgeBrepIterator::Create( shape ); } std::shared_ptr< IVertexBrepIterator > CreateVertexIterator( std::shared_ptr< IShapeBuilder > const& shape ) { return VertexBrepIterator::Create( shape ); } std::shared_ptr< IEdgeBrepIterator > CreateEdgeIterator( std::shared_ptr< IBrepFaceHandle > const& face ) { auto faceOcc = std::dynamic_pointer_cast< OCCFace >( face->GetFace() ); if ( !faceOcc ) return {}; return EdgeFaceIterator::Create( *faceOcc ); } std::shared_ptr< IFaceBrepIterator > CreateFaceIterator( std::shared_ptr< IBrepEdgeHandle > const& edge ) { auto edgeImpl = dynamic_cast< IBrepEdgeHandleImpl const* >( edge.get() ); if ( edgeImpl == nullptr ) return FaceEdgeIterator::Create( {} ); OCCShape const& parentShape = edgeImpl->GetParentShape(); if ( parentShape.IsNull() ) return FaceEdgeIterator::Create( {} ); auto edgeOcc = std::dynamic_pointer_cast< OCCEdge >( edge->GetEdge() ); if ( !edgeOcc ) return FaceEdgeIterator::Create( {} ); return FaceEdgeIterator::Create( GetAdjacentFaces( parentShape, *edgeOcc ) ); } std::shared_ptr< IVertexBrepIterator > CreateVertexIterator( std::shared_ptr< IBrepEdgeHandle > const& edge ) { auto edgeOcc = std::dynamic_pointer_cast< OCCEdge >( edge->GetEdge() ); if ( !edgeOcc ) return {}; return VertexEdgeIterator::Create( *edgeOcc ); }