How do I add app data to STEP file?

Hello,

I am using the OpenCascade data exchange module in order to create a STEP file. I cannot find any way to add my own application specific data (such as a string or integer) to a shape. I tried using SetCVal() and SetIVal() but they didn't work or I wasn't using them correctly. Can someone please help?

Thanks, Shaun.

Andrey Betenev's picture

Hello Shaun,

Generally speaking, it depends on what kind of data you want to put to the STEP file. The data should be encoded in the STEP file in accordance with STEP standard, and this depends on the meaning of that data.

For instance, you may want to set a name for PRODUCT that is written to the STEP file. For that, please set parameter "write.step.product.name" before writing shape to STEP:

Interface_Static::SetCVal("write.step.product.name", "<YourProductName>");

For writing other kind of data, you will need other actions. Please give more details if you need more detailed advise.

Hope this helps a bit

Best Regards,
Andrey

Shaun Bloom's picture

Hello Andrey,

Thanks for your quick response to my post! I have data that I would like to put in a STEP file in keyword value pairs like this:

SURF_PROP 001

where "SURF_PROP" is a keyword for the surface property of an object and "001" is an integer (in this case) representing surface property 001. I need a generic mechanism for putting data like this into the STEP file.

By looking at the STEP documentation in OpenCascade I was only able to find two ways to put data into the STEP file: (1) STEPControlStd_Writer::Transfer() to transfer TopoDS_Shape's and (2) Interface_Static::Set{I,C,R}Val() to transfer predefined STEP types. It was not clear to me that this method of data transfer could transfer my generic data or not and even if it could, I didn't know how to attach it to a specific STEP entity (i.e. to the TopoDS_Shape). Some code that I tried looked like this:

STEPControlStd_Writer writer;

writer.Model( Standard_True );

if ( !Interface_Static::SetCVal( "write.step.product.name",

(char*)getModelRoot().getTail()->getPart()->getName().c_str() ) ) {

//... error...

}

const TopoDS_Shape& shape = getModelRoot().getTail()->getPart()->getShape();

IFSelect_ReturnStatus status = writer.Transfer( shape, STEPControlStd_AsIs );

if ( !Interface_Static::SetIVal( "SURF_PROP", 01 ) ) { // BUG!!

// ... error ...

}

Thanks for your help,

Shaun

Andrey Betenev's picture

> Hello Andrey,

> Thanks for your quick response to my post! I
> have data that I would like to put in a STEP
> file in keyword value pairs like this:

> SURF_PROP 001

> where "SURF_PROP" is a keyword for
> the surface property of an object and
> "001" is an integer (in this case)
> representing surface property 001. I need a
> generic mechanism for putting data like this
> into the STEP file.

Hello Shaun,

Unfortunately, there are no universal and compatible way to store any kind of data in STEP (at least I do not know such). Specific STEP constructs which are to be used to represent various kinds of data are defined by STEP standard and associated documents. Please refer to such documents to find out how to represent the data you are interested in.

> By looking at the STEP documentation in
> OpenCascade I was only able to find two ways
> to put data into the STEP file: (1)
> STEPControlStd_Writer::Transfer() to
> transfer TopoDS_Shape's and (2)
> Interface_Static::Set{I,C,R}Val() to

No, no, Interface_Static parameters do not define data to be put to STEP, they just define some parameters for translator.

OpenCASCADE currently implements direct support for some kinds of data:

  • shapes, assemblies and basic product data are supported by translation of shapes (method STEPControlStd_Writer::Transfer())
  • names of PRODUCTs are supported by parameter "write.step.product.name"
  • some tools supporting colors and validation properties (volume, area etc) can be found in package STEPConstruct

> transfer predefined STEP types. It was not
> clear to me that this method of data
> transfer could transfer my generic data or
> not and even if it could, I didn't know how
> to attach it to a specific STEP entity (i.e.
> to the TopoDS_Shape). Some code that I tried
> looked like this:

> STEPControlStd_Writer writer;

> writer.Model( Standard_True );

> if ( !Interface_Static::SetCVal(
> "write.step.product.name",

>
> (char*)getModelRoot().getTail()->getPart()->getName().c_str()
> ) ) {

> //... error...

> }

> const TopoDS_Shape& shape =
> getModelRoot().getTail()->getPart()->getShape();

> IFSelect_ReturnStatus status =
> writer.Transfer( shape, STEPControlStd_AsIs
> );

This should work if you want just to write name of your shape: the string returned by ...->getName() will become name of STEP PRODUCT entity generated for your shape.

> if ( !Interface_Static::SetIVal(
> "SURF_PROP", 01 ) ) { // BUG!!

> // ... error ...

> }

This is not valid code, do not try this way.

---

Note that if you want to put your own data, not supported directly by STEP, you do it on your own risk to be not compatible with other translators.

For putting any kind of data you have to work with STEP on low level. The procedure in short is the following:

  1. Write shape in a normal way
  2. Get STEP model from STEPControlStd_Writer by method Model()
  3. Find a STEP entity which results from translation of your shape, e.g. by method STEPConstruct::FindEntity()
  4. then either:
    • put your data to fields of this entity, for instance string can be put to name of eny entity which is subtype of StepRepr_RepresentationItem
    • or create some new entities referring that one, and add them to the model by call to method AddWithRefs()

Sorry if it is not so simple as expected

Best Regards, Andrey

> Thanks for your help,

> Shaun

Shaun Bloom's picture

Hello again,

I am attempting to implement the algorithm you suggest. Here is what I am doing:

STEPControlStd_Writer writer;

IFSelect_ReturnStatus status = writer.Transfer( part.getShape(), STEPControlStd_AsIs );

Handle_StepRepr_RepresentationItem entityOfShape = STEPConstruct::FindEntity( writer.WS()->TransferWriter()->FinderProcess(), part.getShape() );

// Also tried this way

//Handle_StepRepr_RepresentationItem entityOfShape = STEPConstruct::FindEntity( writer.WS()->MapWriter(), part.getShape() );

// ... entityOfShape is invalid at this point ...

The problem is that I cannot seem to obtain a valid entityOfShape and I suspect that I did not start with a valid pointer to the FinderProcess (the first argument to FindEntity()). Can you point out what is wrong with this code?

Also, I am willing to use a "comment" section of the AP214 STEP format if there is one in order to keep the format consistent with the rest of the world. Do you know of such a field that can be attached to an entity?

Thanks again for your help,

-- Shaun.

Andrey Betenev's picture

Hello Shaun,

Here are some remarks on your code:

> Hello again,

> I am attempting to implement the algorithm
> you suggest. Here is what I am doing:

> STEPControlStd_Writer writer;

> IFSelect_ReturnStatus status =
> writer.Transfer( part.getShape(),
> STEPControlStd_AsIs );

Everything is fine until that moment

> Handle_StepRepr_RepresentationItem
> entityOfShape = STEPConstruct::FindEntity(
> writer.WS()->TransferWriter()->FinderProcess(),
> part.getShape() );

> // Also tried this way

> //Handle_StepRepr_RepresentationItem
> entityOfShape = STEPConstruct::FindEntity(
> writer.WS()->MapWriter(), part.getShape()
> );

> // ... entityOfShape is invalid at this
> point ...

> The problem is that I cannot seem to obtain
> a valid entityOfShape and I suspect that I
> did not start with a valid pointer to the
> FinderProcess (the first argument to
> FindEntity()). Can you point out what is
> wrong with this code?

No, both ways to get pointer to FinderProcess are OK (they give same object)

The problem is that the function FindEntity() is intended to find STEP entity of the type StepRepr_RepresentationItem which is not generated for the whole shape in your case. You would need this if you wanted to attach your data to individual faces, edges etc. (I thought you needed this)

If you need to attach your data to whole shape, you can get corresponding STEP entity StepShape_ShapeDefinitilonalRepresentation, from which you can access PRODUCT and a plenty of other STEP entities generated for representation of your shape.

For that, use the following code (this is adjusted code of FindEntity)

Handle(StepShape_ShapeDefinitionRepresentation) SDR;

Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FinderProcess, Shape );

FinderProcess->FindTypedTransient (mapper,STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation), SDR);

> Also, I am willing to use a
> "comment" section of the AP214
> STEP format if there is one in order to keep
> the format consistent with the rest of the
> world. Do you know of such a field that can
> be attached to an entity?

There is a header in the STEP file which contains some general information. You can access the corresponding entities by method HeaderEntity() (and others) of the class StepData_StepModel

Best Regards, Andrey

> Thanks again for your help,

> -- Shaun.