Reading STEP GD&T information

Hi,

I'm trying to read GD&T entities from a STEP file using the standard StepControl_Reader in OpenCascade.  The file that I'm trying to read the GD&T information from conforms to the AP242 standard, although I believe that most of the things that I'm trying to extract from the file are actually from AP214 (e.g. geometric tolerances with datum ref.)

I'm able to load the file successfully, but the STEP reader complains about "unknown entities" and I'm unable to read the GD&T entities after I've loaded the file.  The strange thing is that if I poke around in Interface_FileReaderTool::LoadModel, I can see instances of e.g. StepDimTol_GeoTolAndGeoTolWthDatRef being created, but I'm unable to recover them later after that function is done doing its thing.

 

Here is the code that I'm using, it's just cobbled together from some similar code that I found somewhere.  Does anyone know what else I should be doing to read GD&T entities from STEP files?

Thanks

 

STEPControl_Reader stepreader;
    auto reader_success = occt_read_CAD(stepreader, path, progress_callback); // reads file, transfers roots...
    if (!reader_success.second)
        return reader_success;

    // Read GD&T / PMI information from file, spam on console (testing)
    handle<XSControl_WorkSession> ws = stepreader.WS();
    handle<XSControl_TransferReader> tr = ws->TransferReader();
    handle<Transfer_TransientProcess> tp  = tr->TransientProcess();
    handle<Interface_InterfaceModel> model = ws->Model();

    Standard_Integer num_entities = model->NbEntities();
    const Interface_Graph & graph = tp->Graph();
    
    for (Standard_Integer i = 1 ; i <= num_entities ; i++)
    {
        handle<Standard_Transient> entity = model->Value(i);
        if (!entity->IsKind(StepRepr_ShapeAspect::get_type_descriptor()))
            continue;

        auto shape_aspect = handle<StepRepr_ShapeAspect>::DownCast(entity);

        // Find representation item for current shape aspect
        handle<StepRepr_RepresentationItem> ri;
        handle<StepRepr_PropertyDefinition> prop_def;

        Interface_EntityIterator ei = graph.Sharings(shape_aspect);
        for (ei.Start() ; ei.More() && prop_def.IsNull() ; ei.Next())
            prop_def = handle<StepRepr_PropertyDefinition>::DownCast(ei.Value());

        if (prop_def.IsNull())
            continue;

        Interface_EntityIterator prop_def_ei = graph.Sharings(prop_def);
        for (prop_def_ei.Start() ; prop_def_ei.More() ; prop_def_ei.Next())
        {
            auto shape_def_repr = handle<StepShape_ShapeDefinitionRepresentation>::DownCast(prop_def_ei.Value());
            if (shape_def_repr.IsNull())
                continue;

            handle<StepRepr_Representation> repr = shape_def_repr->UsedRepresentation();
            if (!repr.IsNull() && repr->NbItems() > 0)
                ri = repr->ItemsValue(1);    // break?
        }

        if (ri.IsNull())
            continue;

        // Read DG&T entities
        ei = graph.Sharings(shape_aspect);
        for (ei.Start() ; ei.More() ; ei.Next())
        {
            if (ei.Value()->IsKind(StepDimTol_GeometricTolerance::get_type_descriptor()))
            {
                auto gtol = handle<StepDimTol_GeometricTolerance>::DownCast(ei.Value());
                handle<StepBasic_MeasureWithUnit> magnitude = gtol->Magnitude();
                Standard_Real mag_val = magnitude->ValueComponent();
                std::cout << "Got StepDimTol_GeometricTolerance magnitude: " << mag_val << endl;
            }
        }
    }

Qr Qr's picture

You may want to try out STEPCAFControl_Reader which translates the product structure with all metadata to XDE OCAF document.

Irsch Caldsh's picture

Thanks for your reply,

Yeah, in my original example, I was schlepping some of the code from STEPCAFControl_Reader to read the GD&T information.  The reason I wasn't using STEPCAFControl_Reader in the first place was because it's coupled to the Application Framework module, which I'd kind of like to avoid using for various reasons.

The good news is that I am actually able to read the GD&T information from my file, but the bad news is that the GD&T entities don't seem to be subentities of StepRepr_ShapeAspect instances, so I don't see how I can get the geometry associated with the GD&T entities.  Maybe I'm still doing something wrong, or I suppose it could just be the GD&T information in my file.

Here is the code that I'm currently using to read the GD&T info.  I've also attached the file that I'm reading the GD&T information from

// Read GD&T / PMI information from file, spam on console (testing)
    handle<XSControl_WorkSession> ws = stepreader.WS();
    handle<XSControl_TransferReader> tr = ws->TransferReader();
    handle<Transfer_TransientProcess> tp  = tr->TransientProcess();
    handle<Interface_InterfaceModel> model = ws->Model();

    Standard_Integer num_entities = model->NbEntities();
    const Interface_Graph & graph = tp->Graph();
    
    for (Standard_Integer i = 1 ; i <= num_entities ; i++)
    {
        handle<Standard_Transient> entity = model->Value(i);

        // Read DG&T entities
        Interface_EntityIterator ei = graph.Sharings(entity);
        for (ei.Start() ; ei.More() ; ei.Next())
        {
            if (ei.Value()->IsKind(StepDimTol_GeometricTolerance::get_type_descriptor()))
            {
                auto gtol = handle<StepDimTol_GeometricTolerance>::DownCast(ei.Value());
                handle<StepBasic_MeasureWithUnit> magnitude = gtol->Magnitude();
                Standard_Real mag_val = magnitude->ValueComponent();
                std::cout << "Got StepDimTol_GeometricTolerance!\n"
                    << "\tName: " << string(gtol->Name()->ToCString()) << "\n"
                    << "\tMagnitude: " << gtol->Magnitude()->ValueComponent() << endl;
            }
        }
    }

.

Forum supervisor's picture

Dear Irsch,

Your technical question looks interesting and the answer advice of Mr. qa qa is valuable as usual, thanks. OPEN CASCADE has rich 3D expertise, knowledge and proven ready to use solutions including Open CASCADE Technology Data Exchange modules and added-value software components related to this domain.

You can share general context and some additional info about your application needs that could allow finding most optimal implementataion approach. Welcome to our resources and communicate via Contact Form to exchange information about our services and experience and needs of your company projects. It could help to install our frutful efficient collaboration.

Best regards, Forum supervisor

Irsch Caldsh's picture

Ok, I think I've got it.  What I needed to to was for each dimension tolerance entity in the model, find the StepAP242 geometric item specific usage associated with the tolerance's shape aspect.  Here is the code I used, if anyone is interested:

// Read GD&T / PMI information from file, spam on console (testing)
    handle<XSControl_WorkSession> ws = stepreader.WS();
    handle<XSControl_TransferReader> tr = ws->TransferReader();
    handle<Transfer_TransientProcess> tp  = tr->TransientProcess();
    handle<Interface_InterfaceModel> model = ws->Model();

    Standard_Integer num_entities = model->NbEntities();
    const Interface_Graph & graph = tp->Graph();
    
    for (Standard_Integer i = 1 ; i <= num_entities ; i++)
    {
        handle<Standard_Transient> entity = model->Value(i);

        // Read DG&T entities
        Interface_EntityIterator ei = graph.Sharings(entity);
        for (ei.Start() ; ei.More() ; ei.Next())
        {
            if (ei.Value()->IsKind(StepDimTol_GeometricTolerance::get_type_descriptor()))
            {
                auto gtol = handle<StepDimTol_GeometricTolerance>::DownCast(ei.Value());

                handle<StepBasic_MeasureWithUnit> magnitude = gtol->Magnitude();
                Standard_Real mag_val = magnitude->ValueComponent();
                StepDimTol_GeometricToleranceTarget gtol_target = gtol->TolerancedShapeAspect();
                auto sa = gtol_target.ShapeAspect();

                // Find STEP representation item for this shape aspect
                handle<StepRepr_RepresentationItem> ri;

                if (sa)
                {
                    Interface_EntityIterator sa_ei = graph.Sharings(sa);
                    for (sa_ei.Start() ; sa_ei.More() && ri.IsNull() ; sa_ei.Next())
                    {
                        auto ei_val = sa_ei.Value();
                        
                        auto ap242_ru = handle<StepAP242_ItemIdentifiedRepresentationUsage>::DownCast(ei_val);
                        if (ap242_ru && ap242_ru->NbIdentifiedItem() > 0)
                        {
                            ri = ap242_ru->IdentifiedItemValue(1);
                        }
                    }
                }

                handle<StepShape_TopologicalRepresentationItem> topo_item;
                Standard_Integer index = 0;
                string typestr;

                if (sa && ri)
                {
                    topo_item = handle<StepShape_TopologicalRepresentationItem>::DownCast(ri);
                    if (topo_item)
                    {
                        index = tp->MapIndex(topo_item);

                        if (topo_item->IsKind(StepShape_Face::get_type_descriptor()))
                            typestr = "FACE";
                        else if (topo_item->IsKind(StepShape_Edge::get_type_descriptor()))
                            typestr = "EDGE";
                        else if (topo_item->IsKind(StepShape_Vertex::get_type_descriptor()))
                            typestr = "VERTEX";
                        else
                            typestr = "unkown topo";    // a shell or something. whatever.
                    }
                }

                std::cout << "Got StepDimTol_GeometricTolerance!\n"
                    << "\tName: " << string(gtol->Name()->ToCString()) << "\n"
                    << "\tMagnitude: " << gtol->Magnitude()->ValueComponent();
                
                if (index > 0)
                    std::cout << "\n\t" << typestr << " index: " << index;

                std::cout << std::endl;
            }
        }