How can I split every parts of STEP file and thier names?

Question1 : Now I could use XCAFDoc_ShapeTool and XCAFDoc_ColorTool to get all shapes and all colors in XDE document.However, I don't know how to attach these colors to their shapes.How can I get the relationship between colors and their shapes?This is my code:

std::vector<Handle(AIS_Shape)> myReadSTEP(QString &modelFileName)
{
    Handle(TDocStd_Document) doc;
    XCAFApp_Application::GetApplication()->NewDocument("MDTV-XCAF", doc);

    STEPCAFControl_Reader myReader;
    myReader.ReadFile(modelFileName.toStdString().c_str());
    myReader.SetColorMode(true);
    myReader.SetNameMode(true);
    myReader.SetLayerMode(true);

    myReader.Transfer(doc);

    TDF_Label mainLabel = doc->Main();
    Handle(XCAFDoc_ShapeTool) myShapeTool = XCAFDoc_DocumentTool::ShapeTool(mainLabel);
    Handle(XCAFDoc_ColorTool) myColors = XCAFDoc_DocumentTool::ColorTool(mainLabel);

    TDF_LabelSequence FreeShape;
    myShapeTool->GetFreeShapes(FreeShape);

    TDF_LabelSequence FreeSubShape;
    std::vector<Handle(AIS_Shape)> shapeList;
    TDF_LabelSequence aColLabels;
    myColors->GetColors(aColLabels);
    // color
    for(TDF_LabelSequence::Iterator aColIter(aColLabels);aColIter.More();aColIter.Next())
    {
        Quantity_Color aCol; // to receive the values
        TDF_Label aColLabel = aColIter.Value();
        Handle(XCAFDoc_Color) aColorAttr;

        if (!myColors->GetColor (aColLabel, aCol)) { continue; }
         qDebug() << aCol.Red() << aCol.Green() << aCol.Blue();
    }

    // get every sub-shape
    if(myShapeTool->GetComponents(FreeShape.First(),FreeSubShape,true))
    {

        for (int index = 1;index <= FreeSubShape.Size();index++)
        {
            TDF_Label label = FreeSubShape.Value(index);

            TopoDS_Shape aShape = myShapeTool->GetShape(label);
            Handle(AIS_Shape) ais_shape = new AIS_Shape(aShape);
            shapeList.push_back(ais_shape);

// ------------------------------Name------------------------------
//            Handle(TDataStd_Name) aNameAttr;
//            if(!label.FindAttribute(TDataStd_Name::GetID(), aNameAttr))
//            {
//                qDebug() << "no name is attached!";
//            }
//            TCollection_ExtendedString aName = aNameAttr->Get();
//            TCollection_AsciiString Asciiname(aName);
//            std::string stringName= Asciiname.ToCString();
//            qDebug() << QString().fromStdString(stringName);
        }
    }

    return shapeList;
}

I found that This data structure is fitted for data exchange, rather than for use by the final application; in OCCT manual.Is XDE not the best option to display STEP file? Does XDE need XCAFPrs_AISObject to solve problems?

Question 2: Annotated code can get the name of sub-shape.However , the output only is NAUO01or NAUOXX.What is the reason for this quesiton?

Thanks in advance!

Attachments: 
Dmitrii Pasukhin's picture

Hello,

The quastion 1:
The relationship between shape label and color is reference. That is why, you can get list of the shapes from color for 3 types of connections (surf, curv and gen) and get one color from shape label for 3 types of connections (surf, curv, general).
Code sample of getting color from shape label:

//=======================================================================
//function : WriteColors
//purpose  : 
//=======================================================================
Standard_Boolean WriteColors (const TDF_LabelSequence &theLabels)
{
  TDF_LabelSequence labels;
  Handle(XCAFDoc_ShapeTool) aSTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main());
  if (!theLabels.IsEmpty())
  {
    labels = theLabels;
  }
  else
  {
    aSTool->GetFreeShapes(labels);
  }
  // Iterate on shapes in the document
  Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool(theDoc->Main());
  Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool(theDoc->Main());
  for ( Standard_Integer i=1; i <= labels.Length(); i++ ) {
    TDF_Label L = labels.Value(i);
    // Skip assemblies: colors assigned to assemblies and their instances
    // are not supported (it is not clear how to encode that in STEP)
    if ( XCAFDoc_ShapeTool::IsAssembly ( L ) ) {
      TDF_LabelSequence compLabels;
      if ( aSTool.IsNull() )
        continue;
      if (!aSTool->GetComponents(L, compLabels))
        continue;
      WriteColors(compLabels);
      continue;
    }
    
    // collect settings set on that label
    XCAFPrs_IndexedDataMapOfShapeStyle settings;
    TDF_LabelSequence seq;
    seq.Append ( L );
    XCAFDoc_ShapeTool::GetSubShapes ( L, seq );
    Standard_Boolean isVisible = Standard_True;
    for ( Standard_Integer j = 1; j <= seq.Length(); j++ ) {
      TDF_Label lab = seq.Value(j);
      XCAFPrs_Style style;
      Quantity_ColorRGBA C;
      if ( lab == L ) {
        // check for invisible status of object on label
        if ( !CTool->IsVisible( lab ) ) {
          isVisible = Standard_False;
          style.SetVisibility( Standard_False );
        }
      }
      if ( CTool->GetColor ( lab, XCAFDoc_ColorGen, C ) ) {
        style.SetColorCurv ( C.GetRGB() );
        style.SetColorSurf ( C );
      }
      if ( CTool->GetColor ( lab, XCAFDoc_ColorSurf, C ) )
        style.SetColorSurf ( C );
      if ( CTool->GetColor ( lab, XCAFDoc_ColorCurv, C ) )
        style.SetColorCurv ( C.GetRGB() );
      if (!style.IsSetColorSurf())
      {
        Handle(XCAFDoc_VisMaterial) aVisMat = aMatTool->GetShapeMaterial (lab);
        if (!aVisMat.IsNull()
         && !aVisMat->IsEmpty())
        {
          // only color can be stored in STEP
          style.SetColorSurf (aVisMat->BaseColor());
        }
      }
      if ( ! style.IsSetColorCurv() && ! style.IsSetColorSurf() && isVisible ) continue;

      TopoDS_Shape sub = XCAFDoc_ShapeTool::GetShape ( lab );
      XCAFPrs_Style* aMapStyle = settings.ChangeSeek (sub);
      if (aMapStyle == NULL)
        settings.Add ( sub, style );
      else
        *aMapStyle = style;
    }
    if ( settings.Extent() <=0 ) continue;

    // Do something
  }
  // Do something
  return Standard_True;
}

The code sample how to get shapes from color label (need to be tested):

//=======================================================================
//function : GetColor
//purpose  : 
//=======================================================================
Standard_Boolean GetShapes(const TDF_Label& theColorL,
                           const XCAFDoc_ColorType type,
                           TDF_LabelSequence& theResShapes)
{
  Handle(TDataStd_TreeNode) Node;
  if (!theColorL.FindAttribute(XCAFDoc::ColorRefGUID(type), Node))
  {
    return false;
  }
  theResShapes.Append(Node->Label()); // need to check what is need to put (father->label or just label)
  for (; Node->HasNext(); Node = Node->Next())
  {
    theResShapes.Append(Node->Label());
  }
  return Standard_True;
}

Quastion 2:

I think you work with only "part" shape name. Assembly components have 2 name (part name and own name).
if (XCAFDoc_ShapeTool::GetReferredShape(InputL, OutPutL)) give you own label of the part ( return false if you have not reference and OutPutL will be equal with InputL.

If you need more information, please let me now.

Thank you for your interest in OCCT.
Best regards, Dmitrii.