how to get the id of entity in STEP file?

hi:
while I imported a STEP file by OCC,compare to the text content in STEP file,there are many id of entity just like "#11=","#5="ect,the id show the topology relationship with the other entity.
my question is,if can get these id information by Opencascade?is there any way to got it and as same as it show in STEP file?
thanks
jason

Dmitrii Pasukhin's picture

Hello, Yes it is possible.

Code sample to find entity's ID:

STEPCAFControl_Reader aReader;
// reading
const Handle(StepData_StepModel)& aModel = aReader.Reader().StepModel();
const Handle(Standard_Transient)& anEntity = NULL;
const Standard_Integer anID = aModel->IdentLabel(anEntity);
if (anID <=0)
{
  // No find
}

Way to find entity by id is not the best. You can upgrade StepData_StepModel to find using key-values from "theidnums" field.

DRAW:

entity #1234

C++ (in this case you iterate for all entities to find needed, not perfomance way):

STEPCAFControl_Reader aReader;
// reading
Standard_CString anID = "1234";
Handle(Standard_Transient) anEntity = IFSelect_Functions::GiveEntity(aReader.Reader().WS(), anID);

After that, you can navigate on the entity's graph:

const Handle(XSControl_TransferReader) &aTR = WS->TransferReader();
const Handle(Transfer_TransientProcess) &aTP = aTR->TransientProcess();
const Interface_Graph& aGraph = aTP->Graph();
Interface_EntityIterator anIterSharings = aGraph.Sharings(theEnity);
Interface_EntityIterator anIterShared = aGraph.Shared(theEnity);

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

jason jiang's picture

hi,Dmitrii:
Thans for your reply.
In sample 1,the new questions are:1,because the instance of STEPCAFControl_Reader is null, how can I get the StepData_StepModel?is it generated while loading a step file? 2,what is anEntity?just like an Edge,a Face,a Wire,or a Vertex?if it is,how to translate these different entity?3,how to only determine a entity?then,the only identlable can be given.
In sample 2,the instance of Reader also is null,how to assignment?and the param seems wrong,can not be compiled in VS2017.
Finally,could could you give me a complete sample code?
BestRegards
Jason

Dmitrii Pasukhin's picture

Hello,

Entity - is STEP object, for example #13 = EDGE_LOOP.

Full code sample:

TCollection_AsciiString aFileName = "d:/test.stp"
STEPCAFControl_Reader aReader;
aReader.ReadFile (aFileName.ToCString()); // There you create a model and parse STEP file to internal entities
Handle(TDocStd_Document) aDoc;
Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
anApp->NewDocument("BinXCAF", aDoc);
Standard_CString aDocName = "D";
TDataStd_Name::Set (aDoc->GetData()->Root(), aDocName);
aReader.Transfer(); // optional, in this case you transfer STEP to OCC document (shapes, attributes)
const Handle(StepData_StepModel)& aModel = aReader.Reader().StepModel();
Standard_Integer nb = aModel->NbEntities();
const Handle(XSControl_TransferReader) &aTR = aReader.Reader().WS()->TransferReader();
const Handle(Transfer_TransientProcess) &aTP = aTR->TransientProcess();
const Interface_Graph& aGraph = aTP->Graph();
// i is internal index
for (i = 1; i <= nb; i++)
{
  const Handle(Standard_Transient)& anEntity = aModel->Value(i);
  // Just for example
  if (anEntity->IsKind(STANDARD_TYPE(StepBasic_ProductDefinition))
  {
    Handle(StepBasic_ProductDefinition) aPD =
        Handle(StepBasic_ProductDefinition)::DownCast(anEntity);
    // Find ID, that is #1234 in the step file
    const Standard_Integer anID = aModel->IdentLabel(anEntity);
    if (anID <=0)
    {
      // No find
      continue;
    }
    // do something
    for(Interface_EntityIterator anIterSharings = aGraph.Sharings(theEnity); anIterSharings.More(); anIterSharings.Next())
    {
      const Handle(Standard_Transient)& aSharingsEnt = anIterSharings.Value();
    }
    for(Interface_EntityIterator anIterShared = aGraph.Shared(theEnity); anIterShared.More(); anIterShared.Next())
    {
      const Handle(Standard_Transient)& aSharedsEnt = anIterShared.Value();
    }
  }
}

// Example to get entity by ID
Standard_CString anID = "1234";
Handle(Standard_Transient) anEntity = IFSelect_Functions::GiveEntity(aReader.Reader().WS(), anID);

Best regards, Dmitrii.

jason jiang's picture

Dmitrii:
Thanks,in this sample,the Reader transfer to TDocStd_Document is not necessary,is right?the const Handle(Standard_Transient)& anEntity how to transfer to TopoDS_Shape,Face,Wire,Edge ect?if it can be transfered,the the entity of STEP FILE and OPENCASCADE object is related.
finally,if want to get the name of entity if STEP file,just like this:tandard_CString shapetypename = aModel->TypeName(anEntity);is it right?
thanks agin.
Jason.

Dmitrii Pasukhin's picture

TopoDS_Shape genereted only after Transfer operation (you need to create document). Or you can use STEPControl_Reader

STEPControl_Reader aReader;
aReader.ReadFile ("D:/test.stp");
// and after use code from:
// "occt\src\XSDRAWSTEP\XSDRAWSTEP.cxx"
// 82::static Standard_Integer stepread (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
// or STEPCAFControl_Provider::Read
// "occt\src\STEPCAFControl\STEPCAFControl_Provider.cxx"

To get TopoDS object from Enitity you can use the next code:

Handle(Transfer_Binder) aBinder = aTP->Find(anEntity);
if (aBinder.IsNull())
{
 continue;
}
TopoDS_Shape aShape = TransferBRep::ShapeResult(aBinder);
if (aShape.IsNull())
{
  continue;
}
// After you can check  shape type or something else

Whan name do you means? If it is description - you need to make downcast and get field value. If it is type name of entity "EDGE_LOOP", that write after #12345 = ... It is possible, but not for all cases. You can get only type name of  simple entity. For complex entity it is not possible.

Best regards, Dmitrii.

jason jiang's picture

Dmitrii:
Thanks,I tested by your way and code,it is ok.
Thanks
Jason.

jason jiang's picture

Dmitrii:
An other relative question is:if I hava gotten an entity such as a Shape,face,wire,edge,vertex etc,How can I find it in step/stp file?refer the code you gave,I traverse whole stp file by compare every entities,but not fond the right one.such as if want to find a face in step file,the code just like below:
Handle(Transfer_Binder) binder;
binder = aTP->Find(anEntity);
if (binder.IsNull()) {
continue;
}
TopoDS_Shape shape = TransferBRep::ShapeResult(binder);
if (shape.ShapeType() != TopAbs_FACE)
{
continue;
}
TopoDS_Face face = TopoDS::Face(shape);
if(face.IsSame(searchshape))//searchshape is the one I got in OCC and want to find it in step file.
//if (shape.IsSame(searchshape))
{
AfxMessageBox(_T("found"));
iffond = true;
}
else {
AfxMessageBox(_T("not same"));
}
Above code show that it can not find the right one I want.
Then,what is the problem?could you give a suggestion?
Thanks
Jason.

haibo xu's picture

Hi @Dmitrii Pasukhin
How do we get the Entity value from the Entity Object in pythonocc? such as
#2830 = CARTESIAN_POINT('',(-5.303300858899,3.,5.303300858899)); I need get the value ('',(-5.303300858899,3.,5.303300858899))

Under is my code
step_reader = STEPControl_Reader()
status = step_reader.ReadFile(filename)
model = step_reader.StepModel();
nbNum = model.NbEntities()
for index in range(nbNum):
entity = model.Entity(index + 1);
print(index + 1, model.StringLabel(entity).ToCString(),"=",model.TypeName(entity))
StepBasic_ProductDefinition.DownCast(entity);