How to import STEP files with OpenCascade and display with coin3d with the correct colors?

I am trying to import STEP files from OpenCascade and display them on the screen using the coin3d library compatible with Open Inventor. Unfortunately, I always get either working colors or the right geometry, the correctly placed parts with the right colors do not seem to work.

Handle(XCAFDoc_ShapeTool) Assembly;
Assembly = XCAFDoc_DocumentTool::ShapeTool(scene->document->Main());

STEPCAFControl_Reader stepReader;
stepReader.SetColorMode(true);
stepReader.SetNameMode(true);
stepReader.SetLayerMode(true);
const auto stepStat = stepReader.ReadFile(fn.c_str());
if(stepStat != IFSelect_ReturnStatus::IFSelect_RetDone) {
    return false;
}

stepReader.Transfer(scene->document);

TDF_LabelSequence frshapes;
Assembly->GetShapes(frshapes);

if (frshapes.Length() == 0) {
    return false;
} else if (frshapes.Length() == 1) {
    TopoDS_Shape shape = Assembly->GetShape(frshapes.Value(1));
    loadShape(scene, shape, noPerVertexNormals, qualityNormals);
} else {
    for (Standard_Integer i=1; i<frshapes.Length(); i++) {
        TopoDS_Shape S = Assembly->GetShape(frshapes.Value(i));

        TDF_Label aLabel = Assembly->FindShape(S, Standard_False);
        if ( (!aLabel.IsNull()) && (Assembly->IsShape(aLabel)) ) {
            if (Assembly->IsFree(aLabel) ) {
                loadShape(scene, S, noPerVertexNormals, qualityNormals);
            }
        }
    }
}

I also tried to create a complex form if there is more than one form, since I found it on the OpenCascade forum, but it does not matter.

In general, simple STEP files found in pure import mode (I assume they have only one part), but more complex objects with several parts exported from solid jobs come with either the correct geometry or the right colors, but never both.

:

if (Assembly->IsFree(aLabel) ) {
    loadShape(scene, S, noPerVertexNormals, qualityNormals);                }

IsFree (aLabel), , .

, if (! Assembly- > IsFree (aLabel))... , , , .

, , , , , , - .

, / /, , , Transformation(), Location Rotation - 0.

, :

void loadShape(const std::shared_ptr<Scene> &scene, const TopoDS_Shape &shape, bool noPerVertexNormals, bool qualityNormals)
{
    TopExp_Explorer ex;

    Handle(XCAFDoc_ColorTool) Colors;

    Colors = XCAFDoc_DocumentTool::ColorTool(scene->document->Main());

    SceneShape * so = new SceneShape;
    so->setShape(shape);

    // this is all zero
    gp_XYZ aggi = shape.Location().Transformation().TranslationPart();
    std::cout << aggi.X() << "," << aggi.Y() << "," << aggi.Z() << std::endl;
    gp_Quaternion aggiaggi = shape.Location().Transformation().GetRotation();
    std::cout << aggiaggi.X() << "," << aggiaggi.Y() << "," << aggiaggi.Z() << "," << aggiaggi.W() << std::endl << std::endl;

    BRepMesh_IncrementalMesh bMesh(so->shape(), 1 /* ? */,Standard_False, 0.5, Standard_True);

    SoMaterial *fallBackMat = new SoMaterial;
    fallBackMat->ref();
    fallBackMat->diffuseColor.setValue(0.64f, 0.64f, 0.64f);

    Quantity_Color fbColor;
    if (Colors->GetColor(so->shape(), XCAFDoc_ColorGen, fbColor) || Colors->GetColor(so->shape(), XCAFDoc_ColorSurf, fbColor) || Colors->GetColor(so->shape(), XCAFDoc_ColorCurv, fbColor)) {
        fallBackMat->diffuseColor.setValue(static_cast<float>(fbColor.Red()), static_cast<float>(fbColor.Green()), static_cast<float>(fbColor.Blue()));
    }

    so->root()->addChild(fallBackMat);

    SoMaterial *selectionMat = new SoMaterial;
    selectionMat->emissiveColor.setValue(.9f, .9f, .6f);

    int i = 1;
    for (ex.Init(so->shape(), TopAbs_FACE); ex.More(); ex.Next(),i++) {
        const TopoDS_Face& aFace = TopoDS::Face(ex.Current());

        ObjectPart *part = new ObjectPart;
        part->setFace(aFace);

        selectionMat->ref();

        part->selectedRoot()->addChild(selectionMat);

        Quantity_Color color;
        if (
                Colors->GetColor(aFace, XCAFDoc_ColorGen, color) ||
                Colors->GetColor(aFace, XCAFDoc_ColorSurf, color) ||
                Colors->GetColor(aFace, XCAFDoc_ColorCurv, color)
        ) {

            SoMaterial *myMaterial = new SoMaterial;
            myMaterial->ref();
            myMaterial->diffuseColor.setValue(static_cast<float>(color.Red()), static_cast<float>(color.Green()), static_cast<float>(color.Blue()));
            part->unselectedRoot()->addChild(myMaterial);
        } else {
            fallBackMat->ref();
            part->unselectedRoot()->addChild(fallBackMat);
        }

        Standard_Integer nbNodesInFace,nbTriInFace;
        SbVec3f* vertices=0;
        SbVec3f* vertexnormals=0;
        int32_t* cons=0;

        // this subroutine is taken from FreeCAD which can import the models correctly, so i assume it is not the problem
        transferToArray(aFace, &vertices, &vertexnormals, &cons, nbNodesInFace, nbTriInFace, noPerVertexNormals, qualityNormals);

        if (!vertices)
            continue;

        part->selectedRoot()->addChild(part->selectedPolygonRoot());
        part->unselectedRoot()->addChild(part->unselectedPolygonRoot());

        if (!noPerVertexNormals) {
            SoNormal * norm = new SoNormal;
            norm->vector.setValues(0, nbNodesInFace, vertexnormals);

            part->selectedPolygonRoot()->addChild(norm);
            part->unselectedPolygonRoot()->addChild(norm);

            SoNormalBinding * normb = new SoNormalBinding;
            normb->value = SoNormalBinding::PER_VERTEX_INDEXED;
            part->selectedPolygonRoot()->addChild(normb);
            part->unselectedPolygonRoot()->addChild(normb);
        }

        SoCoordinate3 * coords = new SoCoordinate3;
        coords->point.setValues(0,nbNodesInFace, vertices);

        part->selectedPolygonRoot()->addChild(coords);
        part->unselectedPolygonRoot()->addChild(coords);

        SoIndexedFaceSet * faceset = new SoIndexedFaceSet;
        faceset->coordIndex.setValues(0,4*nbTriInFace,(const int32_t*) cons);
        faceset->setUserData((void *) part);

        part->selectedPolygonRoot()->addChild(faceset);
        part->unselectedPolygonRoot()->addChild(faceset);

        so->addPart(part);

        delete [] vertexnormals;
        delete [] vertices;
        delete [] cons;
    }

    scene->addShape(so);
}

? ?

+4

Source: https://habr.com/ru/post/1618118/


All Articles