Get length scale factor of STEP CAD file with OpenCASCADE

Stack Overflow Asked by JacobP on July 23, 2020

I am trying to get the length unit conversion factor in OpenCASCADE, when importing a STEP format CAD file. In my test file the entity #184 sets the length to meters and during import will be converted to milimeters used by OpenCASCADE internally by default


I belive the function below is how it should be done, but no matter what i try the "Length_Unit" STEP entity is not matched, and therefore I can’t get the scaling factor.

void step_unit_scaling(std::string const &file_name) {

  STEPControl_Reader reader;
  reader.ReadFile( file_name.c_str() );

  const Handle(Interface_InterfaceModel) Model = reader.Model();
  Handle(StepData_StepModel) aSM = Handle(StepData_StepModel)::DownCast(Model);

  Standard_Integer NbEntities = Model->NbEntities();
  for (int i=1; i<=NbEntities; i++) {
    Handle(Standard_Transient) enti = aSM->Entity(i);
    if (enti->IsKind (STANDARD_TYPE(StepBasic_LengthMeasureWithUnit))) {
      Handle(StepBasic_LengthMeasureWithUnit) MWU = Handle(StepBasic_LengthMeasureWithUnit)::DownCast(enti);
      Standard_Real scal_mm = MWU->ValueComponent();
      std::cout << " --- !!! MATCH !!! --- scal_mm = " << scal_mm << std::endl;

Does anyone know if this is the correct approach, or if there perhaps is a better way.

One Answer

If you search for an entity of a given type, you should check the types to find an error. The following line will show the actual entity type.

std::cout << "Entity type " << enti->DynamicType()->Name() << std::endl;

When I play with STEP files here, I see that your STEP line leads to an entity of type StepBasic_SiUnitAndLengthUnit. With this code I can test for some expected SI units:

if (enti->IsKind(STANDARD_TYPE(StepBasic_SiUnitAndLengthUnit)))
    Handle(StepBasic_SiUnitAndLengthUnit) unit =

    if (unit->HasPrefix() &&
            (StepBasic_SiUnitName::StepBasic_sunMetre == unit->Name()) &&
            (StepBasic_SiPrefix::StepBasic_spMilli == unit->Prefix()))
        std::cout << "SI Unit is millimetre." << std::endl;
    else if (!unit->HasPrefix() &&
                     (StepBasic_SiUnitName::StepBasic_sunMetre == unit->Name()))
        std::cout << "SI Unit is metre." << std::endl;
        std::cout << "I did not understand that unit..." << std::endl;

Answered by Benjamin Bihler on July 23, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP