/
spivag
/
command_occ
Обзор
Документация
Войти
/
spivag
/
command_occ
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
initial
commands/io_command.cpp
328 строк
11 KB
Степанов Никита
Запрос на слияние 'topology_iterators' (
#3
) из topology_iterators в initial
27 апр 2026, 21:55
Верифицирован
27 апр 2026, 21:55
c047a95
Код
Авторство
О чём код?
// // Created by Alexander Spivakov on 02.10.2024. // #include "io_command.h" #include <TDocStd_Document.hxx> #include <TDF_Label.hxx> #include <XCAFDoc_ShapeTool.hxx> #include <XCAFDoc_DocumentTool.hxx> #include <vector> // OpenCASCADE includes #include <TopoDS_Shape.hxx> #include <BRep_Builder.hxx> #include <TopoDS_Compound.hxx> #include <gp_Trsf.hxx> #include <algorithm> WriteToFileCommand::WriteToFileCommand( const std::string& fileName, std::shared_ptr< IShapeBuilder > const& itemToWrite ) : m_path{ fileName } , m_shapeImpl{ itemToWrite } { } WriteToFileCommand::WriteToFileCommand( const std::string& fileName, std::shared_ptr< CreateModelDocumentCommand > const& itemToWrite ) : m_path{ fileName } , m_documentImpl{ itemToWrite } { } PartCreateParameters::PartCreateParameters( std::vector< std::shared_ptr< IShapeBuilder > > const& shapes, const std::string& fileName, bool isAssembly ) : m_shapes{ shapes } , m_fileName{ fileName } , m_isAssembly{ isAssembly } { } std::string PartCreateParameters::FileName() const { return m_fileName; } bool PartCreateParameters::IsAssembly() const { return m_isAssembly; } std::vector< std::shared_ptr< IShapeBuilder > > PartCreateParameters::Shapes() const { return m_shapes; } InstanceParameters::InstanceParameters( std::weak_ptr< CreateModelPartCommand > const& basePart, std::weak_ptr< CreateModelPartCommand > const& instancedPart, R3::Placement const& location ) : m_basePart( basePart ) , m_childPart( instancedPart ) , m_innerLocation( location ) { } //bool InstanceParameters::operator==( InstanceParameters const& to ) const //{ // return ( m_basePart.lock() == to.m_basePart.lock() ) && ( m_childPart.lock() == to.m_childPart.lock() ) // && m_innerLocation.m_origin == to.m_innerLocation.m_origin // && m_innerLocation.m_ox == to.m_innerLocation.m_ox // && m_innerLocation.m_oy == to.m_innerLocation.m_oy; //} CreateModelPartCommand::CreateModelPartCommand( PartCreateParameters const& partParameters ) : m_initialComponentParameters{ partParameters } { } CreateModelPartCommand::CreateModelPartCommand( PartCreateParameters const& createParameters, CreateModelDocumentCommand& rootDocument ) : m_originDocument( &rootDocument ) , m_initialComponentParameters{ createParameters } { } void CreateModelPartCommand::SetBasePart( std::weak_ptr< CreateModelPartCommand > const& parent ) { if ( m_originDocument == nullptr ) { if ( m_basePart.lock() == nullptr ) m_basePart = parent; } } void CreateModelPartCommand::AddInstance( ModelPartInstance const& instance ) { m_instances.push_back( instance ); } void CreateModelPartCommand::Init() { if ( !( m_createdAssembly.IsNull() && m_createdPart.IsNull() ) ) return; // OpenCASCADE implementation - using TopoDS_Shape for geometry representation TopoDS_Shape partShape; BRep_Builder builder; auto shapes = m_initialComponentParameters.Shapes(); for ( const auto& sc : shapes ) { if ( sc == nullptr ) continue; try { sc->Execute(); } catch ( ... ) { continue; } auto occShape = std::dynamic_pointer_cast< OCCShape >( sc->GetShape() ); if ( occShape && !occShape->IsNull() ) { if ( partShape.IsNull() ) { TopoDS_Compound compound; builder.MakeCompound( compound ); partShape = compound; } builder.Add( partShape, occShape->GetOccShape() ); } } if ( m_initialComponentParameters.IsAssembly() ) { auto basePart = m_basePart.lock(); if ( basePart != nullptr ) { basePart->Init(); TopoDS_Shape modInst; if ( !basePart->m_createdAssembly.IsNull() ) modInst = basePart->m_createdAssembly; else if ( !basePart->m_createdPart.IsNull() ) modInst = basePart->m_createdPart; m_createdAssembly = modInst; } else if ( m_originDocument != nullptr ) { // For OpenCASCADE, we need to get the shape from the document // This is a placeholder - actual implementation depends on how shapes are stored m_createdAssembly = TopoDS_Shape(); // Placeholder } } else { auto basePart = m_basePart.lock(); if ( basePart != nullptr ) { basePart->Init(); TopoDS_Shape modInst; if ( !basePart->m_createdAssembly.IsNull() ) modInst = basePart->m_createdAssembly; else if ( !basePart->m_createdPart.IsNull() ) modInst = basePart->m_createdPart; m_createdPart = modInst; } else if ( m_originDocument != nullptr ) { // For OpenCASCADE, we need to get the shape from the document // This is a placeholder - actual implementation depends on how shapes are stored m_createdPart = TopoDS_Shape(); // Placeholder } } } void CreateModelPartCommand::Run() { if ( !( m_createdAssembly.IsNull() && m_createdPart.IsNull() ) ) return; Init(); for ( auto inst : m_instances ) { std::shared_ptr< CreateModelPartCommand > curChild = inst.m_part.lock(); if ( curChild == nullptr ) continue; if ( curChild->IsModelComponentCreated() ) { TopoDS_Shape itModelInstance{ PrepareInstance() }; curChild->InstanceModelPart( itModelInstance, inst.m_location ); } else { curChild->Run(); } } } std::string CreateModelPartCommand::ExecutionMessage() { return "Create root part result"; } // For OpenCASCADE, PrepareInstance needs to be reimplemented // This is a placeholder - actual implementation will depend on how instances are created TopoDS_Shape CreateModelPartCommand::PrepareInstance() { if ( !m_createdAssembly.IsNull() ) return m_createdAssembly; else if ( !m_createdPart.IsNull() ) return m_createdPart; else { throw BadCommand{ "CreateModelPartCommand::PrepareInstance()" }; } } void CreateModelPartCommand::InstanceModelPart( TopoDS_Shape const& existingInstance, R3::Placement const& location ) { if ( existingInstance.IsNull() || !IsModelComponentCreated() ) return; // For OpenCASCADE, we need to implement instance creation differently // This is a placeholder - actual implementation will use BRepBuilderAPI_Transform if ( !m_createdPart.IsNull() ) { // Create transformed instance of the part gp_Trsf transformation; // Convert R3::Placement to gp_Trsf // transformation.SetTranslation(...); // BRepBuilderAPI_Transform transform(m_createdPart, transformation); // TopoDS_Shape transformedShape = transform.Shape(); } else if ( !m_createdAssembly.IsNull() ) { // Create transformed instance of the assembly // Similar transformation logic as above } } bool CreateModelPartCommand::IsModelComponentCreated() const { return !( m_createdPart.IsNull() && m_createdAssembly.IsNull() ); } CreateModelDocumentCommand::CreateModelDocumentCommand( PartCreateParameters const& rootPartParameters ) : m_rootComponent{ std::shared_ptr< CreateModelPartCommand >( new CreateModelPartCommand{ rootPartParameters, *this } ) } , m_modelDocument{ std::make_shared< Handle(TDocStd_Document) >() } { } std::shared_ptr< CreateModelPartCommand > CreateModelDocumentCommand::GetRootComponent() const { return m_rootComponent; } std::shared_ptr< CreateModelPartCommand > CreateModelDocumentCommand::CreatePart( PartCreateParameters const& partParameters ) { std::shared_ptr< CreateModelPartCommand > result{ new CreateModelPartCommand{ partParameters } }; m_parts.push_back( result ); return result; } bool CreateModelDocumentCommand::InstancePart( InstanceParameters const& partsRelation ) { if ( partsRelation.m_basePart.lock() != m_rootComponent ) { auto findParentItr = std::find_if( begin( m_parts ), end( m_parts ), [partsRelation]( const std::shared_ptr< CreateModelPartCommand >& pPart ) { return partsRelation.m_basePart.lock() == pPart; } ); if ( findParentItr == m_parts.cend() ) return false; } auto findChildItr = std::find_if( begin( m_parts ), end( m_parts ), [partsRelation]( const std::shared_ptr< CreateModelPartCommand >& pPart ) { return partsRelation.m_childPart.lock() == pPart; } ); if ( findChildItr == m_parts.cend() ) return false; partsRelation.m_childPart.lock()->SetBasePart( partsRelation.m_basePart ); ModelPartInstance curInstance{}; curInstance.m_part = partsRelation.m_childPart; curInstance.m_location = partsRelation.m_innerLocation; partsRelation.m_basePart.lock()->AddInstance( curInstance ); // Ещё надо проверить, чтобы не было циклических зависимостей // Возможно, следующее делать не потребуется, а можно будет разрулить на уровне instance return true; } Handle(TDocStd_Document)& CreateModelDocumentCommand::GetModelDocument() { return *m_modelDocument; } //void CreateModelDocumentCommand::Run() //{ // m_rootComponent->Init(); // auto rootCopy{m_rootComponent}; // std::list< InstanceParameters > children; // std::copy_if( begin(m_partRelations), end(m_partRelations), std::back_inserter(children), [ rootCopy ]( const // InstanceParameters & pRel ) { return pRel.m_basePart.lock() == rootCopy; } ); m_partRelations.erase( // std::remove_if( begin(m_partRelations), end(m_partRelations), [ rootCopy ]( const InstanceParameters & pRel ) { // return pRel.m_basePart.lock() == rootCopy; } ), m_partRelations.end() ); if ( !children.empty() ) // { // auto curChildrenItr = begin(children); // auto curChild = curChildrenItr->m_childPart.lock(); // curChild->Init(); // for ( ++curChildrenItr; curChildrenItr != end( children ); ++curChildrenItr ) // { // TopoDS_Shape itModInstance; // if ( !m_rootComponent->m_createdAssembly.IsNull() ) // itModInstance = m_rootComponent->PrepareInstance(); // else if ( !m_rootComponent->m_createdPart.IsNull() ) // itModInstance = m_rootComponent->PrepareInstance(); // if ( !itModInstance.IsNull() ) // { // auto curChild = curChildrenItr->m_childPart.lock(); // if ( curChild->IsModelComponentCreated() ) // { // curChild->InstanceModelPart( itModInstance, curChildrenItr->m_innerLocation ); // } // else // { // curChild->Run(); // } // } // } // } // }