Add Unit (IfcUnit) to IfcPropertySingleValue

A python script produces an IFC-file wherein the following line appears several times:

PropertySingleValueWriter = ifcfile.createIfcPropertySingleValue("{}".format(V), "{}".format(k), ifcfile.create_entity("IfcText", str((val["{}".format(k)]))), None)

This produces (as one represantive example)

#598=IFCPROPERTYSINGLEVALUE('Object','Wall',IFCTEXT('12.3'),$);

The last argument None stands for the unit which, in this case, has not been given yet and was translated as $ in the output IFC-file. The unit known by line

#7=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);

in the IFC-file should now be inserted instead. This can be done manually in the IFC-file by writing #7 into the line,

#598=IFCPROPERTYSINGLEVALUE('Object','Wall',IFCTEXT('12.3'),#7);

Using an adapted python script would be much more efficient. However, I have not found the correct scripting yet to add #7 as a simple text. My attempts have been so far,

[1] PropertySingleValueWriter = ifcfile.createIfcPropertySingleValue("{}".format(V), "{}".format(k), ifcfile.create_entity("IfcText", str((val["{}".format(k)]))), "#7")
[2] PropertySingleValueWriter = ifcfile.createIfcPropertySingleValue("{}".format(V), "{}".format(k), ifcfile.create_entity("IfcText", str((val["{}".format(k)]))), "'#7'")
[3] PropertySingleValueWriter = ifcfile.createIfcPropertySingleValue("{}".format(V), "{}".format(k), ifcfile.create_entity("IfcText", str((val["{}".format(k)]))), "'{}'".format("#7"))
[4] PropertySingleValueWriter = ifcfile.createIfcPropertySingleValue("{}".format(V), "{}".format(k), ifcfile.create_entity("IfcText", str((val["{}".format(k)]))), ifcfile.create_entity("IfcText", "#7"))

They either produce an error ([1], [2], [3]) or explicitly write IFCTEXT('#7') ([4]) into the IFC-file which is not interpretable as a connection to the line #7.

Which is the correct scripting in the python file in order to get the connection to line #7 as achievable by manual editing?

Beware! Text is NOT a length unit.

Iā€™m not sure about IfcDoc, but if you can use IronPython then here is some sample c# code on how to use the open source Geometry Gym toolkit to inject a unit into all length properties (check if I missed in measure types) that might be an approach you consider.
Other samples are here: GeometryGym/GeometryGymIFCExamples: Examples to demonstrate use of https://github.com/jmirtsch/GeometryGymIFC classes

	static void Main(string[] args)
		{
			DatabaseIfc db = new DatabaseIfc(args[0]);

			IfcSIUnit lengthUnitMetre = new IfcSIUnit(db, IfcUnitEnum.LENGTHUNIT, IfcSIPrefix.NONE, IfcSIUnitName.METRE);
			foreach(IfcPropertySingleValue propertySingleValue in db.OfType<IfcPropertySingleValue>())
			{
				if (propertySingleValue.NominalValue == null && propertySingleValue.NominalValue is IfcLengthMeasure || propertySingleValue.NominalValue is IfcPositiveLengthMeasure ||
					propertySingleValue.NominalValue is IfcNonNegativeLengthMeasure)
					propertySingleValue.Unit = lengthUnitMetre;
			}
			db.WriteFile(args[1]);
1 Like