@@ -285,7 +285,7 @@ struct StepLoader
285285 {
286286 MR_TIMER ;
287287
288- const auto shapeTool = XCAFDoc_DocumentTool::ShapeTool ( document->Main () );
288+ shapeTool_ = XCAFDoc_DocumentTool::ShapeTool ( document->Main () );
289289#if STEP_LOAD_COLORS
290290 colorTool_ = XCAFDoc_DocumentTool::ColorTool ( document->Main () );
291291#endif
@@ -295,7 +295,7 @@ struct StepLoader
295295 objStack_.push ( rootObj_ );
296296
297297 TDF_LabelSequence shapes;
298- shapeTool ->GetFreeShapes ( shapes );
298+ shapeTool_ ->GetFreeShapes ( shapes );
299299
300300#if STEP_LOAD_COLORS
301301 TDF_LabelSequence colors;
@@ -404,6 +404,86 @@ struct StepLoader
404404
405405private:
406406#ifdef MRIOEXTRAS_OPENCASCADE_USE_XDE
407+ std::pair<std::optional<Color>, std::optional<Color>> readShapeColors_ ( const TopoDS_Shape& shape ) const
408+ {
409+ std::optional<Color> faceColor, edgeColor;
410+ #if STEP_LOAD_COLORS
411+ Quantity_ColorRGBA color;
412+ if ( colorTool_->GetColor ( shape, XCAFDoc_ColorGen, color ) )
413+ faceColor = edgeColor = toColor ( color );
414+ if ( colorTool_->GetColor ( shape, XCAFDoc_ColorSurf, color ) )
415+ faceColor = toColor ( color );
416+ if ( colorTool_->GetColor ( shape, XCAFDoc_ColorCurv, color ) )
417+ edgeColor = toColor ( color );
418+ #endif
419+ return { faceColor, edgeColor };
420+ }
421+
422+ std::string resolveSplitBodyName_ ( const TopoDS_Shape& bodyShape, const std::string& fallbackName ) const
423+ {
424+ if ( shapeTool_.IsNull () )
425+ return fallbackName;
426+
427+ TDF_Label bodyLabel;
428+ if ( shapeTool_->FindShape ( bodyShape, bodyLabel, true ) )
429+ {
430+ if ( const auto inheritedName = readName_ ( bodyLabel ); !inheritedName.empty () )
431+ return inheritedName;
432+ }
433+
434+ auto bodyShapeNoLocation = bodyShape;
435+ bodyShapeNoLocation.Location ( TopLoc_Location () );
436+ if ( shapeTool_->FindShape ( bodyShapeNoLocation, bodyLabel, true ) )
437+ {
438+ if ( const auto inheritedName = readName_ ( bodyLabel ); !inheritedName.empty () )
439+ return inheritedName;
440+ }
441+
442+ return fallbackName;
443+ }
444+
445+ bool addSplitSimpleShapeChildren_ ( const TopoDS_Shape& shape, const std::shared_ptr<Object>& parent, std::optional<Color> faceColor, std::optional<Color> edgeColor )
446+ {
447+ std::vector<std::pair<TopoDS_Shape, std::string>> bodies;
448+
449+ auto solidIndex = 0 ;
450+ for ( auto explorer = TopExp_Explorer ( shape, TopAbs_SOLID ); explorer.More (); explorer.Next () )
451+ bodies.emplace_back ( explorer.Current (), fmt::format ( " Solid{}" , ++solidIndex ) );
452+
453+ auto shellIndex = 0 ;
454+ for ( auto explorer = TopExp_Explorer ( shape, TopAbs_SHELL, TopAbs_SOLID ); explorer.More (); explorer.Next () )
455+ bodies.emplace_back ( explorer.Current (), fmt::format ( " Shell{}" , ++shellIndex ) );
456+
457+ if ( bodies.size () <= 1 )
458+ return false ;
459+
460+ const auto & parentLocation = shape.Location ();
461+ for ( const auto & [bodyShape, bodyName] : bodies )
462+ {
463+ const auto bodyLocalLocation = bodyShape.Location ().Predivided ( parentLocation );
464+ const auto bodyXf = AffineXf3f ( toXf ( bodyLocalLocation.Transformation () ) );
465+ auto bodyShapeNoLocation = bodyShape;
466+ bodyShapeNoLocation.Location ( TopLoc_Location () );
467+
468+ auto [bodyFaceColor, bodyEdgeColor] = readShapeColors_ ( bodyShape );
469+ if ( !bodyFaceColor )
470+ bodyFaceColor = faceColor;
471+ if ( !bodyEdgeColor )
472+ bodyEdgeColor = edgeColor;
473+
474+ auto objMesh = std::make_shared<ObjectMesh>();
475+ objMesh->setName ( resolveSplitBodyName_ ( bodyShape, bodyName ) );
476+ objMesh->setMesh ( std::make_shared<Mesh>() );
477+ objMesh->setXf ( bodyXf );
478+ objMesh->select ( true );
479+ parent->addChild ( objMesh );
480+
481+ meshTriangulationContexts_.emplace_back ( bodyShapeNoLocation, objMesh, bodyFaceColor, bodyEdgeColor );
482+ }
483+
484+ return true ;
485+ }
486+
407487 void readLabel_ ( const TDF_Label& label )
408488 {
409489 using ShapeTool = XCAFDoc_ShapeTool;
@@ -432,42 +512,49 @@ struct StepLoader
432512 [[maybe_unused]] const auto isRef = ShapeTool::GetReferredShape ( label, ref );
433513 assert ( isRef );
434514
515+ if ( !ShapeTool::IsSimpleShape ( ref ) )
516+ {
517+ auto obj = std::make_shared<Object>();
518+ obj->setName ( name );
519+ obj->setXf ( xf );
520+ obj->select ( true );
521+ objStack_.top ()->addChild ( obj );
522+
523+ iterateLabel_ ( ref, obj );
524+ return ;
525+ }
526+
527+ const auto refShape = ShapeTool::GetShape ( ref );
528+ auto [faceColor, edgeColor] = readShapeColors_ ( refShape );
529+
530+ {
531+ auto obj = std::make_shared<Object>();
532+ obj->setName ( name );
533+ obj->setXf ( xf );
534+ obj->select ( true );
535+
536+ if ( addSplitSimpleShapeChildren_ ( refShape, obj, faceColor, edgeColor ) )
537+ {
538+ objStack_.top ()->addChild ( obj );
539+ return ;
540+ }
541+ }
542+
435543 auto objMesh = std::make_shared<ObjectMesh>();
436544 objMesh->setName ( name );
437545 objMesh->setMesh ( std::make_shared<Mesh>() );
438546 objMesh->setXf ( xf );
439547 objMesh->select ( true );
440548 objStack_.top ()->addChild ( objMesh );
441549
442- iterateLabel_ ( ref, objMesh );
443- if ( ShapeTool::IsSimpleShape ( ref ) )
444- {
445- const auto refShape = ShapeTool::GetShape ( ref );
446-
447- std::optional<Color> faceColor, edgeColor;
448- #if STEP_LOAD_COLORS
449- Quantity_ColorRGBA color;
450- if ( colorTool_->GetColor ( refShape, XCAFDoc_ColorGen, color ) )
451- faceColor = edgeColor = toColor ( color );
452- if ( colorTool_->GetColor ( refShape, XCAFDoc_ColorSurf, color ) )
453- faceColor = toColor ( color );
454- if ( colorTool_->GetColor ( refShape, XCAFDoc_ColorCurv, color ) )
455- edgeColor = toColor ( color );
456- #endif
457-
458- // remove existing sub-shape triangulations
459- std::erase_if ( meshTriangulationContexts_, [&] ( const MeshTriangulationContext& ctx )
460- {
461- return ctx.mesh == objMesh;
462- } );
463550 meshTriangulationContexts_.emplace_back ( refShape, objMesh, faceColor, edgeColor );
464- }
465551 }
466552 else
467553 {
468554 assert ( ShapeTool::IsSimpleShape ( label ) );
469555
470556 std::shared_ptr<ObjectMesh> objMesh;
557+ auto [faceColor, edgeColor] = readShapeColors_ ( shape );
471558 if ( ShapeTool::IsSubShape ( label ) )
472559 {
473560 objMesh = std::dynamic_pointer_cast<ObjectMesh>( objStack_.top () );
@@ -476,6 +563,17 @@ struct StepLoader
476563 }
477564 else
478565 {
566+ auto obj = std::make_shared<Object>();
567+ obj->setName ( name );
568+ obj->setXf ( xf );
569+ obj->select ( true );
570+
571+ if ( addSplitSimpleShapeChildren_ ( shape, obj, faceColor, edgeColor ) )
572+ {
573+ objStack_.top ()->addChild ( obj );
574+ return ;
575+ }
576+
479577 objMesh = std::make_shared<ObjectMesh>();
480578 objMesh->setName ( name );
481579 objMesh->setMesh ( std::make_shared<Mesh>() );
@@ -484,17 +582,6 @@ struct StepLoader
484582 objStack_.top ()->addChild ( objMesh );
485583 }
486584
487- std::optional<Color> faceColor, edgeColor;
488- #if STEP_LOAD_COLORS
489- Quantity_ColorRGBA color;
490- if ( colorTool_->GetColor ( shape, XCAFDoc_ColorGen, color ) )
491- faceColor = edgeColor = toColor ( color );
492- if ( colorTool_->GetColor ( shape, XCAFDoc_ColorSurf, color ) )
493- faceColor = toColor ( color );
494- if ( colorTool_->GetColor ( shape, XCAFDoc_ColorCurv, color ) )
495- edgeColor = toColor ( color );
496- #endif
497-
498585 meshTriangulationContexts_.emplace_back ( shape, objMesh, faceColor, edgeColor );
499586 }
500587 }
@@ -651,6 +738,7 @@ struct StepLoader
651738#if STEP_LOAD_COLORS
652739 Handle ( XCAFDoc_ColorTool ) colorTool_;
653740#endif
741+ Handle ( XCAFDoc_ShapeTool ) shapeTool_;
654742
655743 std::shared_ptr<Object> rootObj_;
656744 std::stack<std::shared_ptr<Object>> objStack_;
0 commit comments