ifcquery / ifcplusplus

IfcPlusPlus is an open source C++ class model, as well as a reader and writer for IFC files in STEP format. Features: Easy and efficient memory management using smart pointers. Parallel reader for very fast parsing on multi-core CPU's. Additionally, there's a simple IFC viewer application, using Qt and OpenSceneGraph. It can be used as starting point for all kinds of applications around the open building model standard IFC.
http://www.ifcquery.com
MIT License
586 stars 211 forks source link

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

Open alas2 opened 3 years ago

alas2 commented 3 years ago

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()

ifcquery commented 3 years ago

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.

alas2 commented 3 years ago

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::vector& args, const std::map<int,shared_ptr >& 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::vector& args, const std::map<int,shared_ptr >& 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 commented 4 months ago

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,

ifcquery commented 4 months ago

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