ifcplusplus icon indicating copy to clipboard operation
ifcplusplus copied to clipboard

IFCMASSMEASURE and some other IFC types are not read when they have explicit IFC constructors

Open alas2 opened this issue 5 years ago • 4 comments

For example, '#74= IFCQUANTITYWEIGHT('GrossWeight',$,$,IFCMASSMEASURE(196000.),$);'

readReal() in ReaderUtil.h expects double only i.e. 196000. not IFCMASSMEASURE(196000.). The same applies for readInteger(), readLogical(), readBool(), and readIntegerValue()

alas2 avatar Nov 30 '20 23:11 alas2

I just tested an example: #266940= IFCPROPERTYSINGLEVALUE('Weight',$,IFCMASSMEASURE(0.89336550494179),$);

It is read correctly.

Please check again, and use a debugger to reproduce a possible problem. If the problem persists, please provide the complete IFC file.

ifcquery avatar Dec 15 '20 21:12 ifcquery

Thanks.

The file that I have is very large and it is difficult to reduce it.

By looking at the IFC++ code, the sample you have should work fine as IFCQUANTITYWEIGHT reads doubles... etc different than IFCPROPERTYSINGLEVALUE.

void IfcPropertySingleValue::readStepArguments( const std::vectorstd::wstring& args, const std::map<int,shared_ptr<BuildingEntity> >& map ) { const size_t num_args = args.size(); if( num_args != 4 ){ std::stringstream err; err << "Wrong parameter count for entity IfcPropertySingleValue, expecting 4, having " << num_args << ". Entity ID: " << m_entity_id << std::endl; throw BuildingException( err.str().c_str() ); } m_Name = IfcIdentifier::createObjectFromSTEP( args[0], map ); m_Description = IfcText::createObjectFromSTEP( args[1], map ); m_NominalValue = IfcValue::createObjectFromSTEP( args[2], map ); m_Unit = IfcUnit::createObjectFromSTEP( args[3], map ); }

IfcValue::createObjectFromSTEP( args[2], map ) { ... // call readSelectType( arg, result_object, map ); // This function take care whether the value is IFCMASSMEASURE(0.89336550494179) or 0.89336550494179 }

While IfcQuantityWeight

void IfcQuantityWeight::readStepArguments( const std::vectorstd::wstring& args, const std::map<int,shared_ptr<BuildingEntity> >& map ) { const size_t num_args = args.size(); if( num_args != 5 ){ std::stringstream err; err << "Wrong parameter count for entity IfcQuantityWeight, expecting 5, having " << num_args << ". Entity ID: " << m_entity_id << std::endl; throw BuildingException( err.str().c_str() ); } m_Name = IfcLabel::createObjectFromSTEP( args[0], map ); m_Description = IfcText::createObjectFromSTEP( args[1], map ); readEntityReference( args[2], m_Unit, map ); m_WeightValue = IfcMassMeasure::createObjectFromSTEP( args[3], map ); m_Formula = IfcLabel::createObjectFromSTEP( args[4], map ); }

Within this function fcMassMeasure::createObjectFromSTEP( args[3], map ) { // Call readReal( arg, type_object->m_value );

}

inline void readReal( const std::wstring& attribute_value, double& target ) { target = std::stod( attribute_value ); // Here is the bug if you have IFCMASSMEASURE(0.89336550494179) }

alas2 avatar Dec 15 '20 22:12 alas2

IFCQUANTITYWEIGHT -Not Read.zip

Please find attached file where IFCQUANTITYWEIGHT are NOT read. The issue same as mentioned alas2 commented on Dec 1, 2020 in all the above functions.

Am hoping this will be fixed as every time we update the library we have to keep track of our local changes to fix this.

Best regards,

alas2 avatar Apr 30 '24 04:04 alas2

IfcMassMeasure is not defined as SELECT data type:

TYPE IfcMassMeasure = REAL; END_TYPE;

Whereas IfcValue is defined as SELECT type:

TYPE IfcValue = SELECT (IfcDerivedMeasureValue ,IfcMeasureValue ,IfcSimpleValue); END_TYPE;

SELECT types need the explicit type written out like this: #721= IFCPROPERTYSINGLEVALUE('Reference',$,IFCIDENTIFIER('X022'),$);

Because otherwise it wouldn't be clear which one it is. For MassMeasure that is not the case, it is always a real number.

I can implement a change for all classes derived from IfcPhysicalSimpleQuantity, but currently that is not a priority

ifcquery avatar Apr 30 '24 08:04 ifcquery