util.unit to support converting aggregate of aggregates

This commit is contained in:
Andrej730
2024-04-23 17:51:39 +05:00
parent db31574103
commit 1c729a74d1
3 changed files with 102 additions and 14 deletions
@@ -683,8 +683,14 @@ def is_attr_type(
return cur_decl
if isinstance(cur_decl, ifcopenshell_wrapper.aggregation_type):
res = cur_decl.type_of_element()
cur_decl = res.declared_type()
# support aggregate of aggregates, as in IfcCartesianPointList3D.CoordList
def get_declared_type_from_aggregate(cur_decl):
cur_decl = cur_decl.type_of_element()
if not isinstance(cur_decl, ifcopenshell_wrapper.aggregation_type):
return cur_decl.declared_type()
return get_declared_type_from_aggregate(cur_decl)
cur_decl = get_declared_type_from_aggregate(cur_decl)
if hasattr(cur_decl, "name") and cur_decl.name() == ifc_unit_type_name:
return cur_decl
while hasattr(cur_decl, "declared_type") is True:
@@ -733,14 +739,16 @@ def convert_file_length_units(ifc_file: ifcopenshell.file, target_units: str) ->
old_length = [u for u in unit_assignment.Units if getattr(u, "UnitType", None) == "LENGTHUNIT"][0]
new_length = ifcopenshell.api.run("unit.add_si_unit", file_patched, unit_type="LENGTHUNIT", prefix=prefix)
# support tuple of tuples, as in IfcCartesianPointList3D.CoordList
def convert_value(value):
if not isinstance(value, tuple):
return convert_unit(value, old_length, new_length)
return tuple(convert_value(v) for v in value)
# Traverse all elements and their nested attributes in the file and convert them
for element, attr, val in iter_element_and_attributes_per_type(file_patched, "IfcLengthMeasure"):
if isinstance(val, tuple):
new_value = [convert_unit(v, old_length, new_length) for v in val]
setattr(element, attr.name(), tuple(new_value))
else:
new_value = convert_unit(val, old_length, new_length)
setattr(element, attr.name(), new_value)
new_value = convert_value(val)
setattr(element, attr.name(), new_value)
file_patched.remove(old_length)
unit_assignment.Units = tuple([new_length, *unit_assignment.Units])
@@ -0,0 +1,79 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1');
FILE_NAME('mill.ifc','2024-04-23T16:52:20+05:00',(),(),'IfcOpenShell v0.7.0-f7c03db75','BlenderBIM 0.0.240422-998f9c6','Nobody');
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
#1=IFCPROJECT('3Q4HLVId9C$OJq2NqKnvVO',$,'My Project',$,$,$,$,(#14,#26),#9);
#2=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#3=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#4=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#5=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#6=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#7=IFCMEASUREWITHUNIT(IFCREAL(0.0174532925199433),#6);
#8=IFCCONVERSIONBASEDUNIT(#5,.PLANEANGLEUNIT.,'degree',#7);
#9=IFCUNITASSIGNMENT((#4,#2,#8,#3));
#10=IFCCARTESIANPOINT((0.,0.,0.));
#11=IFCDIRECTION((0.,0.,1.));
#12=IFCDIRECTION((1.,0.,0.));
#13=IFCAXIS2PLACEMENT3D(#10,#11,#12);
#14=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#13,$);
#15=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#14,$,.MODEL_VIEW.,$);
#16=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Model',*,*,*,*,#14,$,.GRAPH_VIEW.,$);
#17=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Box','Model',*,*,*,*,#14,$,.MODEL_VIEW.,$);
#18=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#14,$,.SECTION_VIEW.,$);
#19=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#14,$,.ELEVATION_VIEW.,$);
#20=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#14,$,.MODEL_VIEW.,$);
#21=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Model',*,*,*,*,#14,$,.PLAN_VIEW.,$);
#22=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Profile','Model',*,*,*,*,#14,$,.ELEVATION_VIEW.,$);
#23=IFCCARTESIANPOINT((0.,0.));
#24=IFCDIRECTION((1.,0.));
#25=IFCAXIS2PLACEMENT2D(#23,#24);
#26=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Plan',2,1.E-05,#25,$);
#27=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Plan',*,*,*,*,#26,$,.GRAPH_VIEW.,$);
#28=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Plan',*,*,*,*,#26,$,.PLAN_VIEW.,$);
#29=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Annotation','Plan',*,*,*,*,#26,$,.PLAN_VIEW.,$);
#30=IFCSITE('1T8u08wvPCnhfVRFeG_Je7',$,'My Site',$,$,#53,$,$,$,$,$,$,$,$);
#36=IFCBUILDING('0AGAIai5z9HOTud5I6CjMh',$,'My Building',$,$,#59,$,$,$,$,$,$);
#42=IFCBUILDINGSTOREY('2lMUoFnMv5KOSnzZ9_MPZv',$,'My Storey',$,$,#65,$,$,$,$);
#48=IFCRELAGGREGATES('0cjacslobAjw8I_uTLtTuK',$,$,$,#1,(#30));
#49=IFCCARTESIANPOINT((0.,0.,0.));
#50=IFCDIRECTION((0.,0.,1.));
#51=IFCDIRECTION((1.,0.,0.));
#52=IFCAXIS2PLACEMENT3D(#49,#50,#51);
#53=IFCLOCALPLACEMENT($,#52);
#54=IFCRELAGGREGATES('126VmVXPD0pAP2uJz6QYat',$,$,$,#30,(#36));
#55=IFCCARTESIANPOINT((0.,0.,0.));
#56=IFCDIRECTION((0.,0.,1.));
#57=IFCDIRECTION((1.,0.,0.));
#58=IFCAXIS2PLACEMENT3D(#55,#56,#57);
#59=IFCLOCALPLACEMENT(#53,#58);
#60=IFCRELAGGREGATES('1KLZsOP9zAivCjkiTn31bt',$,$,$,#36,(#42));
#61=IFCCARTESIANPOINT((0.,0.,0.));
#62=IFCDIRECTION((0.,0.,1.));
#63=IFCDIRECTION((1.,0.,0.));
#64=IFCAXIS2PLACEMENT3D(#61,#62,#63);
#65=IFCLOCALPLACEMENT(#59,#64);
#66=IFCACTUATOR('3RT$GBDjj6VhZQ2OYV3P13',$,'Cube',$,$,#95,#84,$,.ELECTRICACTUATOR.);
#72=IFCINDEXEDPOLYGONALFACE((1,2,4,3));
#73=IFCINDEXEDPOLYGONALFACE((3,4,8,7));
#74=IFCINDEXEDPOLYGONALFACE((7,8,6,5));
#75=IFCINDEXEDPOLYGONALFACE((5,6,2,1));
#76=IFCINDEXEDPOLYGONALFACE((3,7,5,1));
#77=IFCINDEXEDPOLYGONALFACE((8,4,2,6));
#78=IFCCARTESIANPOINTLIST3D(((-999.999938964844,-999.999938964844,-999.999938964844),(-999.999938964844,-999.999938964844,999.999938964844),(-999.999938964844,999.999938964844,-999.999938964844),(-999.999938964844,999.999938964844,999.999938964844),(999.999938964844,-999.999938964844,-999.999938964844),(999.999938964844,-999.999938964844,999.999938964844),(999.999938964844,999.999938964844,-999.999938964844),(999.999938964844,999.999938964844,999.999938964844)));
#79=IFCPOLYGONALFACESET(#78,.T.,(#72,#73,#74,#75,#76,#77),$);
#80=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#79));
#81=IFCCARTESIANPOINT((-1000.,-1000.,-1000.));
#82=IFCBOUNDINGBOX(#81,2000.,2000.,2000.);
#83=IFCSHAPEREPRESENTATION(#17,'Box','BoundingBox',(#82));
#84=IFCPRODUCTDEFINITIONSHAPE($,$,(#83,#80));
#85=IFCRELCONTAINEDINSPATIALSTRUCTURE('107zrsI95BsfGJXI83megf',$,$,$,(#66),#42);
#91=IFCCARTESIANPOINT((0.,5000.,0.));
#92=IFCDIRECTION((0.,0.,1.));
#93=IFCDIRECTION((1.,0.,0.));
#94=IFCAXIS2PLACEMENT3D(#91,#92,#93);
#95=IFCLOCALPLACEMENT(#65,#94);
ENDSEC;
END-ISO-10303-21;
@@ -41,9 +41,10 @@ def test_file_units_length_convert(ifc_file):
elem_id = element.id()
original_element = f.by_id(elem_id)
original_val = getattr(original_element, attr.name())
if isinstance(original_val, tuple):
# assert element is equal to original element times scale
assert val == tuple([v * scale for v in original_val])
else:
# assert element is equal to original element times scale
assert val == original_val * scale
def convert_value(value):
if not isinstance(value, tuple):
return value * scale
return tuple(convert_value(v) for v in value)
# assert element is equal to original element times scale
assert val == convert_value(original_val)