I can read the color of solid, but not the color of face from step files

I exported a model to the step file. I use

aColorTool->SetColor(aLabel,surfcolor,XCAFDoc_ColorSurf);

Save solid and face color information.
Then I import this step file that I use

aColorTool->GetColor(aLabel,XCAFDoc_ColorSurf,surfcolor);

Read solid and face color information.
The weird thing is, I can read all the solid color information accurately, but for all the faces, it always returns false when read with this statement.

Besides, I tried

TopLoc_Location aLoc;
XCAFPrs_IndexedDataMapOfShapeStyle aSettingsFree;
XCAFPrs::CollectStyleSettings(aRootLabel,aLoc,aSettingsFree);
XCAFPrs_Style theStyle = aSettingsFree.FindFromKey(aShape);

It can't find the color of the face either.

I really need some help. Thank you so much.

Dmitrii Pasukhin's picture

Hello, it is not clear the issue. The issue with getting color that exists in doc or export/import lose colours.

When you making search, please be sure that the shape has the same location (object) as shape inside tree.

Best regards, Dmitrii.

Best regards, Dmitrii.

gkv311 n's picture

It might be possible that the issue is not with reading colors, but rather in writing them - you might misuse API or fill in XCAF document with information that cannot be exported into STEP format.

So, first of all - try opening created STEP file in viewers like CAD Assistant. If you don't see face colors - then the issue is in code assigning colors before STEP export. Try sharing some code sample / model to see what might be done wrong.

If CAD Assistant shows the face colors, then the issue with reading information from XCAF document.

Zeping Li's picture

Thank you very much for your analysis. I have tested with CAD assistant, and the color can be read successfully, which shows that there is no problem with the step file I exported, but the problem should be in the reading process. The code I read has been shown below.

When I debug, I find that the label can not get the problem, that is, the code at the * in the code. Strangely enough, only the FACE and SHELL labels can not be obtained, SOLID labels can be obtained (of course, you can also read the SOLID color).

I've been struggling with this problem for a long time and really need help.

Best wishes.

Zeping Li's picture

My code is show as follow. The error occurred at * , Why I can not get the label.
Thanks Very Very MUCH!

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Handle(TDocStd_Document) doc;
Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication();
anApp->NewDocument("MDTV-XCAF", doc);

STEPCAFControl_Reader aStepReader;
aStepReader.SetColorMode(true);
aStepReader.SetNameMode(true);

aStepReader.ReadFile(pFilename);
aStepReader.Transfer(doc);

TDF_Label aRootLabel = doc->Main();
Handle(XCAFDoc_ShapeTool) myAssembly = XCAFDoc_DocumentTool::ShapeTool(aRootLabel);
Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(aRootLabel);
Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool(aRootLabel);

//****save the information about shapes in step file********
std::deque< step_file_object_info > allShapes;

TDF_LabelSequence labels;
myAssembly->GetFreeShapes(labels);
int N = labels.Length();

for (size_t i = 1; i <= N; ++i) {
bool labelNull = false;
const TDF_Label& labelFree = labels.Value((const Standard_Integer)i);
TopoDS_Shape shapeFree = XCAFDoc_ShapeTool::GetShape(labelFree);
TopAbs_ShapeEnum typeFree = shapeFree.ShapeType();

Handle(TDataStd_Name) bName; QString nameFree;
if (labelFree.FindAttribute(TDataStd_Name::GetID(), bName)) {
TCollection_HExtendedString occName = bName->Get();
nameFree = QString::fromStdU16String(occName.ToExtString());
}
else {
nameFree = "NULL";
}

TopLoc_Location aLoc;
XCAFPrs_IndexedDataMapOfShapeStyle aSettingsFree;
XCAFPrs::CollectStyleSettings(labelFree, aLoc, aSettingsFree);

if (aSettingsFree.Size() == 0) continue;

Quantity_ColorRGBA defaultcolori(230.0f / 255.0f, 230.0f / 255.0f, 25.0f / 255.0f, 1.0f);

for (size_t i = 1; i <= aSettingsFree.Size(); ++i) {
TopoDS_Shape shapei = aSettingsFree.FindKey(i);
TopAbs_ShapeEnum typei = shapei.ShapeType();
// *****************this will have a problem!***********************************************
// *****************the labeli will be NULL when the shapei is FACE or SHELL*********************
// ***********But the labeli will be right when the shapei is Solid*********************
TDF_Label labeli = myAssembly->FindShape(shapei);
if (labeli.IsNull()) myAssembly->Search(shapei, labeli, Standard_True, Standard_True, Standard_True);
if (labeli.IsNull()) {
labelNull = true;
continue;
}

//*********I can not get the right label about shapei (face or shell)******************************

Handle(TDataStd_Name) bName; QString namei;
if (labeli.FindAttribute(TDataStd_Name::GetID(), bName)) {
TCollection_HExtendedString occName = bName->Get();
namei = QString::fromStdU16String(occName.ToExtString());
}
else {
namei = "NULL";
}

Quantity_ColorRGBA surfcolori(defaultcolori);
Quantity_ColorRGBA curvcolori(defaultcolori);

XCAFPrs_Style keyStyle = aSettingsFree.FindFromIndex(i);
surfcolori = keyStyle.GetColorSurfRGBA();
Quantity_Color myColorCurv = keyStyle.GetColorCurv();
curvcolori.SetRGB(myColorCurv);

allShapes.push_back(step_file_object_info());
allShapes.back().name = namei;
allShapes.back().label = labeli;
allShapes.back().shape = shapei;
allShapes.back().type = typei;
allShapes.back().surfcolor = surfcolori;
allShapes.back().curvcolor = curvcolori;
allShapes.back().isFree = false;

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Best wishes!!

Dmitrii Pasukhin's picture

Please update message, attaching code as a c++ snipped. Check advanced redactor and insert the code as a block.

Best regards, Dmitrii.

Zeping Li's picture

OK! My code is show as follow. The error occurred at * , Why I can not get the label. Thank YOU Very Very MUCH! ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Handle(TDocStd_Document) doc;
Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication();
anApp->NewDocument("MDTV-XCAF", doc);

STEPCAFControl_Reader aStepReader;
aStepReader.SetColorMode(true);
aStepReader.SetNameMode(true);

aStepReader.ReadFile(pFilename);
aStepReader.Transfer(doc);


TDF_Label aRootLabel = doc->Main();
Handle(XCAFDoc_ShapeTool) myAssembly = XCAFDoc_DocumentTool::ShapeTool(aRootLabel);
Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(aRootLabel);
Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool(aRootLabel);

//save the information about shapes in step file
std::deque< step_file_object_info > allShapes;


TDF_LabelSequence labels;
myAssembly->GetFreeShapes(labels);

int N = labels.Length();
for (size_t i = 1; i <= N; ++i) {
    bool labelNull = false;
    Quantity_ColorRGBA defaultcolori(230.0f / 255.0f, 230.0f / 255.0f, 25.0f / 255.0f, 1.0f);


    const TDF_Label& labelFree = labels.Value((const Standard_Integer)i);
    TopoDS_Shape shapeFree = XCAFDoc_ShapeTool::GetShape(labelFree);
    TopAbs_ShapeEnum typeFree = shapeFree.ShapeType();


    Handle(TDataStd_Name) bName; QString nameFree;
    if (labelFree.FindAttribute(TDataStd_Name::GetID(), bName)) {
        TCollection_HExtendedString occName = bName->Get();
        nameFree = QString::fromStdU16String(occName.ToExtString());
    }
    else {
        nameFree = "NULL";
    }


    TopLoc_Location aLoc;
    XCAFPrs_IndexedDataMapOfShapeStyle aSettingsFree;
    XCAFPrs::CollectStyleSettings(labelFree, aLoc, aSettingsFree);
    if (aSettingsFree.Size() == 0) continue;


    for (size_t i = 1; i <= aSettingsFree.Size(); ++i) {
        TopoDS_Shape shapei = aSettingsFree.FindKey(i);
        TopAbs_ShapeEnum typei = shapei.ShapeType();

        // *****************this will have a problem!***********************************
        // ************the labeli will be NULL when the shapei is FACE or SHELL********
        // ********But the labeli will be right when the shapei is Solid*************



        TDF_Label labeli = myAssembly->FindShape(shapei);
        if (labeli.IsNull()) myAssembly->Search(shapei, labeli, Standard_True, Standard_True, Standard_True);
        if (labeli.IsNull()) {
            labelNull = true;
            continue;
        }


        //*********I can not get the right label about shapei (face or shell)**********


        //get name
        Handle(TDataStd_Name) bName; QString namei;
        if (labeli.FindAttribute(TDataStd_Name::GetID(), bName)) {
            TCollection_HExtendedString occName = bName->Get();
            namei = QString::fromStdU16String(occName.ToExtString());
        }
        else {
            namei = "NULL";
        }

        //get color
        Quantity_ColorRGBA surfcolori(defaultcolori);
        Quantity_ColorRGBA curvcolori(defaultcolori);

        XCAFPrs_Style keyStyle = aSettingsFree.FindFromIndex(i);
        surfcolori = keyStyle.GetColorSurfRGBA();
        Quantity_Color myColorCurv = keyStyle.GetColorCurv();
        curvcolori.SetRGB(myColorCurv);


        //save result
        allShapes.push_back(step_file_object_info());
        allShapes.back().name = namei;
        allShapes.back().label = labeli;
        allShapes.back().shape = shapei;
        allShapes.back().type = typei;
        allShapes.back().surfcolor = surfcolori;
        allShapes.back().curvcolor = curvcolori;
        allShapes.back().isFree = false;

    }
}    

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Best wishes!!

Dmitrii Pasukhin's picture

Thank you for example. But first need to clarify that issue is not on export stage. Could you please check your exported STP file with some STP viewed or analyse? CAD Assistant, NIST STP Analyzer, Autodesk free web viewer and any other. Or at least check the file content for container something like "COLOR_RGB".

Best regards, Dmitrii.

Zeping Li's picture

Thank your analyze, Dmitrii. I have tested with CAD assistant, and the color can be read successfully, which shows that there is no problem with the step file I exported, but the problem should be in the reading process. At the same time ,I test the HFSS and CST. the color can also be read successfully .

In the step files, I look for "COLOR_RGB" ,the result is NOT FOUND. I look for "COLOUR_RGB"(there is a "U"), I find it ,and "COLOUR_RGB" appears eight times in my step file. My step file struct can be show as the picture 1.

When I debug, I find that the label can not get the problem, that is, the code at the * in the code. Strangely , only the FACE and SHELL labels can not be obtained(so when I used "aColorTool->GetColor(aLabel,XCAFDoc_ColorSurf,surfcolor) ", it will be failed), SOLID labels can be obtained (of course, I can also read the SOLID color by "aColorTool->GetColor(aLabel,XCAFDoc_ColorSurf,surfcolor) ").

I've been struggling with this problem for a long long time and really need help.
Best Wishes!

Attachments: 
Zeping Li's picture

After a long process of testing and changing, I discovered something new:
I couldn't get a valid label through myAssembly->Search(aShape,aLabel,Standard_True,Standard_True) when the shape was face.
But,
When I get the shape of shell, I can get a valid label by going to myAssembly->Search(aShape,aLabel,Standard_True,Standard_True), But the shell label always returns false when used with ColorTool->GetColor(aLabel,XCAFDoc_ColorSurf,surfcolor).