/
spivag
/
command_occ
Обзор
Документация
Войти
/
spivag
/
command_occ
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
initial
commands/topology.cpp
350 строк
9 KB
Степанов Никита
Запрос на слияние 'topology_iterators' (
#3
) из topology_iterators в initial
27 апр 2026, 21:55
Верифицирован
27 апр 2026, 21:55
c047a95
Код
Авторство
О чём код?
#include <topology.h> #include <BRepGProp.hxx> #include <GProp_GProps.hxx> #include <BRep_Tool.hxx> #include <BRepBndLib.hxx> #include <BRepMesh_IncrementalMesh.hxx> #include <BRepAdaptor_Surface.hxx> #include <BRepAdaptor_Curve.hxx> #include <BRepLProp_SLProps.hxx> #include <GCPnts_TangentialDeflection.hxx> #include <Poly_Triangulation.hxx> #include <Bnd_Box.hxx> #include <gp_Pnt.hxx> #include <gp_Pnt2d.hxx> #include <gp_Dir.hxx> #include <TopExp.hxx> #include <TopExp_Explorer.hxx> #include <TopLoc_Location.hxx> #include <TopoDS.hxx> #include <TopAbs_ShapeEnum.hxx> #include <TopAbs_Orientation.hxx> #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx> #include <cmath> #include <sstream> std::string OCCShape::DumpToString() const { if ( m_shape.IsNull() ) return "Null OCCShape"; std::ostringstream oss; oss << "OCCShape: HashCode=" << HashCode(); return oss.str(); } void OCCShape::Tessellate( double linearDeflection, double angularDeflection ) { BRepMesh_IncrementalMesh mesh( m_shape, linearDeflection, false, angularDeflection ); } R3::Gabarit OCCFace::GetBounds() const { R3::Gabarit result; if ( !m_face.IsNull() ) { Bnd_Box box; BRepBndLib::Add( m_face, box ); if ( !box.IsVoid() ) { double xmin, ymin, zmin, xmax, ymax, zmax; box.Get( xmin, ymin, zmin, xmax, ymax, zmax ); result.Append( R3::Point{ xmin, ymin, zmin } ); result.Append( R3::Point{ xmax, ymax, zmax } ); } } return result; } std::string OCCFace::DumpToString() const { if ( m_face.IsNull() ) return "Null OCCFace"; std::ostringstream oss; oss << "OCCFace: HashCode=" << HashCode(); return oss.str(); } void OCCFace::Tessellate( double linearDeflection, double angularDeflection ) { BRepMesh_IncrementalMesh mesh( m_face, linearDeflection, false, angularDeflection ); } FaceMeshData OCCFace::GetTriangulation( bool computeGaussCurvature ) const { FaceMeshData result; if ( m_face.IsNull() ) return result; TopLoc_Location loc; Handle( Poly_Triangulation ) tris = BRep_Tool::Triangulation( m_face, loc ); if ( tris.IsNull() ) return result; bool faceReversed = ( m_face.Orientation() == TopAbs_REVERSED ); BRepAdaptor_Surface surf( m_face ); for ( int i = 1; i <= tris->NbTriangles(); ++i ) { Poly_Triangle tri = tris->Triangle( i ); int n1, n2, n3; tri.Get( n1, n2, n3 ); if ( faceReversed ) std::swap( n2, n3 ); int nodes[3] = { n1, n2, n3 }; std::array<MeshVertex, 3> triangle; for ( int j = 0; j < 3; ++j ) { gp_Pnt p = tris->Node( nodes[j] ); if ( !loc.IsIdentity() ) p.Transform( loc ); triangle[j].xyz = { static_cast<float>( p.X() ), static_cast<float>( p.Y() ), static_cast<float>( p.Z() ) }; gp_Dir normal( 0.0, 0.0, 1.0 ); if ( tris->HasUVNodes() ) { gp_Pnt2d uv = tris->UVNode( nodes[j] ); BRepLProp_SLProps props( surf, uv.X(), uv.Y(), 1, 1e-6 ); if ( props.IsNormalDefined() ) { normal = props.Normal(); if ( faceReversed ) normal.Reverse(); } if ( computeGaussCurvature ) { BRepLProp_SLProps cprops( surf, uv.X(), uv.Y(), 2, 1e-6 ); double gc = cprops.GaussianCurvature(); if ( std::isfinite( gc ) ) triangle[j].gaussCurvature = static_cast<float>( gc ); } } triangle[j].normal = { static_cast<float>( normal.X() ), static_cast<float>( normal.Y() ), static_cast<float>( normal.Z() ) }; } result.triangles.push_back( triangle ); } return result; } FaceIsolineData OCCFace::GetIsolines( int numLines, int numSamples ) const { FaceIsolineData result; if ( m_face.IsNull() ) return result; BRepAdaptor_Surface surf( m_face ); double uMin = surf.FirstUParameter(); double uMax = surf.LastUParameter(); double vMin = surf.FirstVParameter(); double vMax = surf.LastVParameter(); for ( int iu = 1; iu < numLines; ++iu ) { double u = uMin + ( uMax - uMin ) * iu / numLines; std::vector<std::array<float, 3>> line; for ( int s = 0; s <= numSamples; ++s ) { double v = vMin + ( vMax - vMin ) * s / numSamples; gp_Pnt p = surf.Value( u, v ); line.push_back( { static_cast<float>( p.X() ), static_cast<float>( p.Y() ), static_cast<float>( p.Z() ) } ); } result.lines.push_back( std::move( line ) ); } for ( int iv = 1; iv < numLines; ++iv ) { double v = vMin + ( vMax - vMin ) * iv / numLines; std::vector<std::array<float, 3>> line; for ( int s = 0; s <= numSamples; ++s ) { double u = uMin + ( uMax - uMin ) * s / numSamples; gp_Pnt p = surf.Value( u, v ); line.push_back( { static_cast<float>( p.X() ), static_cast<float>( p.Y() ), static_cast<float>( p.Z() ) } ); } result.lines.push_back( std::move( line ) ); } return result; } //---------------------------------------------------------------------------------------- double OCCEdge::Length() const { if ( m_edge.IsNull() ) return -1.; GProp_GProps props; BRepGProp::LinearProperties( m_edge, props ); return props.Mass(); } R3::Gabarit OCCEdge::GetBounds() const { R3::Gabarit result; if ( !m_edge.IsNull() ) { Bnd_Box box; BRepBndLib::Add( m_edge, box ); if ( !box.IsVoid() ) { double xmin, ymin, zmin, xmax, ymax, zmax; box.Get( xmin, ymin, zmin, xmax, ymax, zmax ); result.Append( R3::Point{ xmin, ymin, zmin } ); result.Append( R3::Point{ xmax, ymax, zmax } ); } } return result; } std::string OCCEdge::DumpToString() const { if ( m_edge.IsNull() ) return "Null OCCEdge"; std::ostringstream oss; oss << "OCCEdge: HashCode=" << HashCode() << ", Length=" << Length(); return oss.str(); } bool OCCEdge::IsDegenerated() const { return BRep_Tool::Degenerated( m_edge ); } EdgePolylineData OCCEdge::Discretize( double linearDeflection, double angularDeflection ) const { EdgePolylineData result; if ( m_edge.IsNull() || BRep_Tool::Degenerated( m_edge ) ) return result; BRepAdaptor_Curve curve( m_edge ); GCPnts_TangentialDeflection disc( curve, linearDeflection, angularDeflection ); if ( disc.NbPoints() < 2 ) return result; for ( int i = 1; i <= disc.NbPoints(); ++i ) { gp_Pnt p = disc.Value( i ); result.points.push_back( { static_cast<float>( p.X() ), static_cast<float>( p.Y() ), static_cast<float>( p.Z() ) } ); } return result; } //---------------------------------------------------------------------------------------- R3::Point OCCVertex::GetPoint() const { if ( m_vertex.IsNull() ) throw std::runtime_error( "Bad vertex" ); gp_Pnt pnt = BRep_Tool::Pnt( m_vertex ); return R3::Point{ pnt.X(), pnt.Y(), pnt.Z() }; } R3::Gabarit OCCVertex::GetBounds() const { R3::Gabarit result; if ( !m_vertex.IsNull() ) { gp_Pnt pnt = BRep_Tool::Pnt( m_vertex ); result.Append( R3::Point{ pnt.X(), pnt.Y(), pnt.Z() } ); } return result; } std::string OCCVertex::DumpToString() const { if ( m_vertex.IsNull() ) return "Null OCCVertex"; std::ostringstream oss; oss << "OCCVertex: HashCode=" << HashCode(); try { R3::Point pt = GetPoint(); oss << ", Point=(" << pt.x() << "," << pt.y() << "," << pt.z() << ")"; } catch (...) { oss << ", Point=<error>"; } return oss.str(); } std::vector< OCCFace > GetFaces( OCCShape const& shape ) { std::vector< OCCFace > result; for ( TopExp_Explorer ex( shape.GetOccShape(), TopAbs_FACE ); ex.More(); ex.Next() ) result.push_back( OCCFace{ TopoDS::Face( ex.Current() ) } ); return result; } std::vector< OCCEdge > GetEdges( OCCShape const& shape ) { std::vector< OCCEdge > result; for ( TopExp_Explorer ex( shape.GetOccShape(), TopAbs_EDGE ); ex.More(); ex.Next() ) result.push_back( OCCEdge{ TopoDS::Edge( ex.Current() ) } ); return result; } std::vector< OCCEdge > GetEdges( OCCFace const& face ) { std::vector< OCCEdge > result; for ( TopExp_Explorer ex( face.GetOccFace(), TopAbs_EDGE ); ex.More(); ex.Next() ) result.push_back( OCCEdge{ TopoDS::Edge( ex.Current() ) } ); return result; } std::vector< OCCVertex > GetVertices( OCCShape const& shape ) { std::vector< OCCVertex > result; for ( TopExp_Explorer ex( shape.GetOccShape(), TopAbs_VERTEX ); ex.More(); ex.Next() ) result.push_back( OCCVertex{ TopoDS::Vertex( ex.Current() ) } ); return result; } std::vector< OCCVertex > GetVertices( OCCEdge const& edge ) { std::vector< OCCVertex > result; for ( TopExp_Explorer ex( edge.GetOccEdge(), TopAbs_VERTEX ); ex.More(); ex.Next() ) result.push_back( OCCVertex{ TopoDS::Vertex( ex.Current() ) } ); return result; } std::vector< OCCFace > GetAdjacentFaces( OCCShape const& parentShape, OCCEdge const& edge ) { std::vector< OCCFace > result; if ( parentShape.IsNull() || edge.IsNull() ) return result; TopTools_IndexedDataMapOfShapeListOfShape edgeToFaces; TopExp::MapShapesAndAncestors( parentShape.GetOccShape(), TopAbs_EDGE, TopAbs_FACE, edgeToFaces ); if ( edgeToFaces.Contains( edge.GetOccEdge() ) ) { for ( TopTools_ListIteratorOfListOfShape it( edgeToFaces.FindFromKey( edge.GetOccEdge() ) ); it.More(); it.Next() ) result.push_back( OCCFace{ TopoDS::Face( it.Value() ) } ); } return result; }