diff --git a/src/blenderbim/blenderbim/bim/module/georeference/prop.py b/src/blenderbim/blenderbim/bim/module/georeference/prop.py index 26a47f819c..cbe0eb5bec 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/prop.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/prop.py @@ -117,16 +117,21 @@ class BIMGeoreferenceProperties(PropertyGroup): # These are only for reference to capture data about a host model from a linked model # If you relink a model from a new host origin, we can autodetect it in theory with this host_model_origin: StringProperty(name="Host Model Origin") + host_model_origin_si: StringProperty(name="Host Model Origin SI") host_model_project_north: StringProperty(name="Host Model Angle to Grid North") # These are only for reference, calculated using tool.Loader.calculate_model_origin + # TODO perform calculate_model_origin at load time, not as an explicit step. model_origin: StringProperty(name="Model Origin") + model_origin_si: StringProperty(name="Model Origin SI") model_project_north: StringProperty(name="Model Angle to Grid North") # True if there is a temporary Blender session coordinate system has_blender_offset: BoolProperty(name="Has Blender Offset") # These E, N, H, and project north are the absolute map coordinates of the Blender session + # If has_blender_offset is True, this is equivalent to model_origin and model_project_north. + # TODO consolidate this with model_origin and model_project_north. blender_eastings: StringProperty(name="Blender Eastings", default="0") blender_northings: StringProperty(name="Blender Northings", default="0") blender_orthogonal_height: StringProperty(name="Blender Orthogonal Height", default="0") diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index 68f7360c9d..2e6fd94f7b 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -1053,6 +1053,7 @@ class LoadLink(bpy.types.Operator): pprops = bpy.context.scene.BIMProjectProperties gprops = bpy.context.scene.BIMGeoreferenceProperties tool.Loader.calculate_model_origin(tool.Ifc.get()) + code = f""" import bpy @@ -1060,6 +1061,7 @@ def run(): gprops = bpy.context.scene.BIMGeoreferenceProperties # Our model origin becomes their host model origin gprops.host_model_origin = "{gprops.model_origin}" + gprops.host_model_origin_si = "{gprops.model_origin_si}" gprops.host_model_project_north = "{gprops.model_project_north}" gprops.has_blender_offset = {gprops.has_blender_offset} gprops.blender_eastings = "{gprops.blender_eastings}" @@ -1112,7 +1114,7 @@ except Exception as e: data = json.load(f) gprops = bpy.context.scene.BIMGeoreferenceProperties - for prop in ("model_origin", "model_project_north"): + for prop in ("model_origin", "model_origin_si", "model_project_north"): if (value := data.get(prop, None)) is not None: setattr(gprops, prop, value) @@ -1396,8 +1398,10 @@ class LoadLinkedProject(bpy.types.Operator): if tool.Loader.settings.false_origin_mode == "MANUAL" and tool.Loader.settings.false_origin: tool.Loader.set_manual_blender_offset(self.file) elif tool.Loader.settings.false_origin_mode == "AUTOMATIC": - if gprops.host_model_origin: - tool.Loader.settings.false_origin = list(map(float, gprops.host_model_origin.split(","))) + if gprops.host_model_origin_si: + tool.Loader.settings.false_origin = [ + float(o) / self.unit_scale for o in gprops.host_model_origin_si.split(",") + ] tool.Loader.settings.project_north = float(gprops.host_model_project_north) tool.Loader.set_manual_blender_offset(self.file) else: @@ -1407,8 +1411,10 @@ class LoadLinkedProject(bpy.types.Operator): self.json_filepath = self.filepath + ".cache.json" data = { "host_model_origin": gprops.host_model_origin, + "host_model_origin_si": gprops.host_model_origin_si, "host_model_project_north": gprops.host_model_project_north, "model_origin": gprops.model_origin, + "model_origin_si": gprops.model_origin_si, "model_project_north": gprops.model_project_north, "has_blender_offset": gprops.has_blender_offset, "blender_eastings": gprops.blender_eastings, diff --git a/src/blenderbim/blenderbim/tool/loader.py b/src/blenderbim/blenderbim/tool/loader.py index 236ed63d25..9e90e579d3 100644 --- a/src/blenderbim/blenderbim/tool/loader.py +++ b/src/blenderbim/blenderbim/tool/loader.py @@ -610,11 +610,13 @@ class Loader(blenderbim.core.tool.Loader): return placement = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement) offset_point = [placement[0][3], placement[1][3], placement[2][3]] - cls.settings.false_origin = ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, *offset_point) + cls.settings.false_origin = ifcopenshell.util.geolocation.auto_xyz2enh( + ifc_file, *offset_point, should_return_in_map_units=False + ) # Prioritise coordinate operation angles angle = ifcopenshell.util.geolocation.get_grid_north(ifc_file) - if np.isclose(angle, 0.): + if np.isclose(angle, 0.0): # Fallback to the placement angle as a good guess xaa, xao = placement[:, 0][0:2] angle = ifcopenshell.util.geolocation.xaxis2angle(xaa, xao) @@ -680,7 +682,9 @@ class Loader(blenderbim.core.tool.Loader): offset_point = cls.get_offset_point(ifc_file) if offset_point is None: return - cls.settings.false_origin = ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, *offset_point) + cls.settings.false_origin = ifcopenshell.util.geolocation.auto_xyz2enh( + ifc_file, *offset_point, should_return_in_map_units=False + ) if angle := ifcopenshell.util.geolocation.get_grid_north(ifc_file): cls.settings.project_north = angle cls.set_manual_blender_offset(ifc_file) @@ -747,7 +751,10 @@ class Loader(blenderbim.core.tool.Loader): gprops.model_origin = ( f"{gprops.blender_eastings},{gprops.blender_northings},{gprops.blender_orthogonal_height}" ) + gprops.model_origin_si = f"{float(gprops.blender_eastings) * cls.unit_scale},{float(gprops.blender_northings) * cls.unit_scale},{float(gprops.blender_orthogonal_height) * cls.unit_scale}" gprops.model_project_north = gprops.blender_project_north else: - gprops.model_origin = ",".join(map(str, ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, 0, 0, 0))) + enh = ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, 0, 0, 0, should_return_in_map_units=False) + gprops.model_origin = ",".join(map(str, enh)) + gprops.model_origin_si = ",".join([str(o * cls.unit_scale) for o in enh]) gprops.model_project_north = str(ifcopenshell.util.geolocation.get_grid_north(ifc_file)) diff --git a/src/blenderbim/test/bim/feature/project.feature b/src/blenderbim/test/bim/feature/project.feature index 5473a07cb5..b3f86665b6 100644 --- a/src/blenderbim/test/bim/feature/project.feature +++ b/src/blenderbim/test/bim/feature/project.feature @@ -780,6 +780,21 @@ Scenario: Link IFC - automatic false origin mode - two different false origins a And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "-17.696,-7.866,0" And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "-13.268,0.464,0" +Scenario: Link IFC - automatic false origin mode - three identical false origins but different project and map units + Given an empty Blender session + # Not currently possible via UI + And I set "scene.BIMProjectProperties.distance_limit" to "5" + And I set "scene.BIMProjectProperties.false_origin_mode" to "AUTOMATIC" + When I press "bim.link_ifc(filepath='{cwd}/test/files/geolocation-unit1.ifc', use_cache=False)" + And I press "bim.link_ifc(filepath='{cwd}/test/files/geolocation-unit2.ifc', use_cache=False)" + And I press "bim.link_ifc(filepath='{cwd}/test/files/geolocation-unit3.ifc', use_cache=False)" + Then the object "Col:IfcProject/geolocation-unit1.ifc:Chunk" exists + And the object "Col:IfcProject/geolocation-unit2.ifc:Chunk" exists + And the object "Col:IfcProject/geolocation-unit3.ifc:Chunk" exists + And the object "Col:IfcProject/geolocation-unit1.ifc:Chunk" has a vertex at "7.294,-5.366,-1" + And the object "Col:IfcProject/geolocation-unit2.ifc:Chunk" has a vertex at "7.294,-5.366,-1" + And the object "Col:IfcProject/geolocation-unit3.ifc:Chunk" has a vertex at "7.294,-5.366,-1" + Scenario: Toggle link visibility - wireframe mode Given an empty IFC project And I press "bim.link_ifc(filepath='{cwd}/test/files/basic.ifc')" diff --git a/src/blenderbim/test/files/geolocation-unit1.ifc b/src/blenderbim/test/files/geolocation-unit1.ifc new file mode 100644 index 0000000000..b4540ac2b0 --- /dev/null +++ b/src/blenderbim/test/files/geolocation-unit1.ifc @@ -0,0 +1,82 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1'); +FILE_NAME('r.ifc','2024-07-12T22:17:19+10:00',(),(),'IfcOpenShell 0.0.0','BlenderBIM 0.0.0-c79e490','Nobody'); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCPROJECT('1LzO1Igj5ANQ5AiOvjUjnG',$,'My Project',$,$,$,$,(#14,#26),#9); +#2=IFCSIUNIT(*,.LENGTHUNIT.,$,.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('1ecpRa9fj2dR3uR4bvVJbA',$,'My Site',$,$,#95,$,$,$,$,$,$,$,$); +#36=IFCBUILDING('0945uAN0X9tRF28u6js$Qk',$,'My Building',$,$,#105,$,$,$,$,$,$); +#42=IFCBUILDINGSTOREY('3RGH4hDLf2bRUeQ6Ycqsc1',$,'My Storey',$,$,#115,$,$,$,$); +#48=IFCRELAGGREGATES('1xModsFiP07g2M6E5lNo1O',$,$,$,#1,(#30)); +#54=IFCRELAGGREGATES('3BWUpJ9Vn4rxK4EIby6PKK',$,$,$,#30,(#36)); +#60=IFCRELAGGREGATES('1SRTd02pj3PuTit88LkMvI',$,$,$,#36,(#42)); +#66=IFCACTUATOR('0Tzlo1K_XCzvVZWouybqQT',$,'Cube',$,$,#125,#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(((-1.,-1.,-1.),(-1.,-1.,1.),(-1.,1.,-1.),(-1.,1.,1.),(1.,-1.,-1.),(1.,-1.,1.),(1.,1.,-1.),(1.,1.,1.))); +#79=IFCPOLYGONALFACESET(#78,.T.,(#72,#73,#74,#75,#76,#77),$); +#80=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#79)); +#81=IFCCARTESIANPOINT((-1.,-1.,-1.)); +#82=IFCBOUNDINGBOX(#81,2.,2.,2.); +#83=IFCSHAPEREPRESENTATION(#17,'Box','BoundingBox',(#82)); +#84=IFCPRODUCTDEFINITIONSHAPE($,$,(#83,#80)); +#85=IFCRELCONTAINEDINSPATIALSTRUCTURE('3o6MjWMX54fh13NM0ZRFCA',$,$,$,(#66),#42); +#91=IFCCARTESIANPOINT((10.,0.,0.)); +#92=IFCDIRECTION((0.,0.,1.)); +#93=IFCDIRECTION((0.866025399898532,0.500000006730587,0.)); +#94=IFCAXIS2PLACEMENT3D(#91,#92,#93); +#95=IFCLOCALPLACEMENT($,#94); +#101=IFCCARTESIANPOINT((-1.77635683940025E-15,0.,0.)); +#102=IFCDIRECTION((0.,0.,1.)); +#103=IFCDIRECTION((1.,0.,0.)); +#104=IFCAXIS2PLACEMENT3D(#101,#102,#103); +#105=IFCLOCALPLACEMENT(#95,#104); +#111=IFCCARTESIANPOINT((1.77635683940025E-15,0.,0.)); +#112=IFCDIRECTION((0.,0.,1.)); +#113=IFCDIRECTION((1.,0.,0.)); +#114=IFCAXIS2PLACEMENT3D(#111,#112,#113); +#115=IFCLOCALPLACEMENT(#105,#114); +#121=IFCCARTESIANPOINT((8.66025399898532,-5.00000006730587,0.)); +#122=IFCDIRECTION((0.,0.,1.)); +#123=IFCDIRECTION((0.866025399898532,-0.500000006730587,0.)); +#124=IFCAXIS2PLACEMENT3D(#121,#122,#123); +#125=IFCLOCALPLACEMENT(#115,#124); +#126=IFCPROJECTEDCRS('EPSG:3857',$,$,$,$,$,#128); +#127=IFCMAPCONVERSION(#14,#126,10000.,0.,0.,$,$,1000.); +#128=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.); +ENDSEC; +END-ISO-10303-21; diff --git a/src/blenderbim/test/files/geolocation-unit2.ifc b/src/blenderbim/test/files/geolocation-unit2.ifc new file mode 100644 index 0000000000..ed02757d58 --- /dev/null +++ b/src/blenderbim/test/files/geolocation-unit2.ifc @@ -0,0 +1,81 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1'); +FILE_NAME('r2.ifc','2024-07-12T22:36:11+10:00',(),(),'IfcOpenShell 0.0.0','BlenderBIM 0.0.0-c79e490','Nobody'); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCPROJECT('1LzO1Igj5ANQ5AiOvjUjnG',$,'My Project',$,$,$,$,(#14,#26),#9); +#2=IFCSIUNIT(*,.LENGTHUNIT.,$,.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('1ecpRa9fj2dR3uR4bvVJbA',$,'My Site',$,$,#95,$,$,$,$,$,$,$,$); +#36=IFCBUILDING('0945uAN0X9tRF28u6js$Qk',$,'My Building',$,$,#105,$,$,$,$,$,$); +#42=IFCBUILDINGSTOREY('3RGH4hDLf2bRUeQ6Ycqsc1',$,'My Storey',$,$,#115,$,$,$,$); +#48=IFCRELAGGREGATES('1xModsFiP07g2M6E5lNo1O',$,$,$,#1,(#30)); +#54=IFCRELAGGREGATES('3BWUpJ9Vn4rxK4EIby6PKK',$,$,$,#30,(#36)); +#60=IFCRELAGGREGATES('1SRTd02pj3PuTit88LkMvI',$,$,$,#36,(#42)); +#66=IFCACTUATOR('0Tzlo1K_XCzvVZWouybqQT',$,'Cube',$,$,#125,#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(((-1.,-1.,-1.),(-1.,-1.,1.),(-1.,1.,-1.),(-1.,1.,1.),(1.,-1.,-1.),(1.,-1.,1.),(1.,1.,-1.),(1.,1.,1.))); +#79=IFCPOLYGONALFACESET(#78,.T.,(#72,#73,#74,#75,#76,#77),$); +#80=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#79)); +#81=IFCCARTESIANPOINT((-1.,-1.,-1.)); +#82=IFCBOUNDINGBOX(#81,2.,2.,2.); +#83=IFCSHAPEREPRESENTATION(#17,'Box','BoundingBox',(#82)); +#84=IFCPRODUCTDEFINITIONSHAPE($,$,(#83,#80)); +#85=IFCRELCONTAINEDINSPATIALSTRUCTURE('3o6MjWMX54fh13NM0ZRFCA',$,$,$,(#66),#42); +#91=IFCCARTESIANPOINT((10.,0.,0.)); +#92=IFCDIRECTION((0.,0.,1.)); +#93=IFCDIRECTION((0.866025399898532,0.500000006730587,0.)); +#94=IFCAXIS2PLACEMENT3D(#91,#92,#93); +#95=IFCLOCALPLACEMENT($,#94); +#101=IFCCARTESIANPOINT((-1.77635683940025E-15,0.,0.)); +#102=IFCDIRECTION((0.,0.,1.)); +#103=IFCDIRECTION((1.,0.,0.)); +#104=IFCAXIS2PLACEMENT3D(#101,#102,#103); +#105=IFCLOCALPLACEMENT(#95,#104); +#111=IFCCARTESIANPOINT((1.77635683940025E-15,0.,0.)); +#112=IFCDIRECTION((0.,0.,1.)); +#113=IFCDIRECTION((1.,0.,0.)); +#114=IFCAXIS2PLACEMENT3D(#111,#112,#113); +#115=IFCLOCALPLACEMENT(#105,#114); +#121=IFCCARTESIANPOINT((8.66025399898532,-5.00000006730587,0.)); +#122=IFCDIRECTION((0.,0.,1.)); +#123=IFCDIRECTION((0.866025399898532,-0.500000006730587,0.)); +#124=IFCAXIS2PLACEMENT3D(#121,#122,#123); +#125=IFCLOCALPLACEMENT(#115,#124); +#126=IFCPROJECTEDCRS('EPSG:3857',$,$,$,$,$,#2); +#127=IFCMAPCONVERSION(#14,#126,10.,0.,0.,$,$,1.); +ENDSEC; +END-ISO-10303-21; diff --git a/src/blenderbim/test/files/geolocation-unit3.ifc b/src/blenderbim/test/files/geolocation-unit3.ifc new file mode 100644 index 0000000000..d7243abfb4 --- /dev/null +++ b/src/blenderbim/test/files/geolocation-unit3.ifc @@ -0,0 +1,82 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1'); +FILE_NAME('r2.ifc','2024-07-12T22:36:11+10:00',(),(),'IfcOpenShell 0.0.0','BlenderBIM 0.0.0-c79e490','Nobody'); +FILE_SCHEMA(('IFC4')); +ENDSEC; +DATA; +#1=IFCPROJECT('1LzO1Igj5ANQ5AiOvjUjnG',$,'My Project',$,$,$,$,(#14,#26),#9); +#2=IFCSIUNIT(*,.LENGTHUNIT.,$,.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((#128,#4,#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('1ecpRa9fj2dR3uR4bvVJbA',$,'My Site',$,$,#95,$,$,$,$,$,$,$,$); +#36=IFCBUILDING('0945uAN0X9tRF28u6js$Qk',$,'My Building',$,$,#105,$,$,$,$,$,$); +#42=IFCBUILDINGSTOREY('3RGH4hDLf2bRUeQ6Ycqsc1',$,'My Storey',$,$,#115,$,$,$,$); +#48=IFCRELAGGREGATES('1xModsFiP07g2M6E5lNo1O',$,$,$,#1,(#30)); +#54=IFCRELAGGREGATES('3BWUpJ9Vn4rxK4EIby6PKK',$,$,$,#30,(#36)); +#60=IFCRELAGGREGATES('1SRTd02pj3PuTit88LkMvI',$,$,$,#36,(#42)); +#66=IFCACTUATOR('0Tzlo1K_XCzvVZWouybqQT',$,'Cube',$,$,#125,#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(((-100.,-100.,-100.),(-100.,-100.,100.),(-100.,100.,-100.),(-100.,100.,100.),(100.,-100.,-100.),(100.,-100.,100.),(100.,100.,-100.),(100.,100.,100.))); +#79=IFCPOLYGONALFACESET(#78,.T.,(#72,#73,#74,#75,#76,#77),$); +#80=IFCSHAPEREPRESENTATION(#15,'Body','Tessellation',(#79)); +#81=IFCCARTESIANPOINT((-100.,-100.,-100.)); +#82=IFCBOUNDINGBOX(#81,200.,200.,200.); +#83=IFCSHAPEREPRESENTATION(#17,'Box','BoundingBox',(#82)); +#84=IFCPRODUCTDEFINITIONSHAPE($,$,(#83,#80)); +#85=IFCRELCONTAINEDINSPATIALSTRUCTURE('3o6MjWMX54fh13NM0ZRFCA',$,$,$,(#66),#42); +#91=IFCCARTESIANPOINT((1000.,0.,0.)); +#92=IFCDIRECTION((0.,0.,1.)); +#93=IFCDIRECTION((0.866025399898532,0.500000006730587,0.)); +#94=IFCAXIS2PLACEMENT3D(#91,#92,#93); +#95=IFCLOCALPLACEMENT($,#94); +#101=IFCCARTESIANPOINT((-1.77635683940025E-13,0.,0.)); +#102=IFCDIRECTION((0.,0.,1.)); +#103=IFCDIRECTION((1.,0.,0.)); +#104=IFCAXIS2PLACEMENT3D(#101,#102,#103); +#105=IFCLOCALPLACEMENT(#95,#104); +#111=IFCCARTESIANPOINT((1.77635683940025E-13,0.,0.)); +#112=IFCDIRECTION((0.,0.,1.)); +#113=IFCDIRECTION((1.,0.,0.)); +#114=IFCAXIS2PLACEMENT3D(#111,#112,#113); +#115=IFCLOCALPLACEMENT(#105,#114); +#121=IFCCARTESIANPOINT((866.025399898532,-500.000006730587,0.)); +#122=IFCDIRECTION((0.,0.,1.)); +#123=IFCDIRECTION((0.866025399898532,-0.500000006730587,0.)); +#124=IFCAXIS2PLACEMENT3D(#121,#122,#123); +#125=IFCLOCALPLACEMENT(#115,#124); +#126=IFCPROJECTEDCRS('EPSG:3857',$,$,$,$,$,#2); +#127=IFCMAPCONVERSION(#14,#126,10.,0.,0.,$,$,0.01); +#128=IFCSIUNIT(*,.LENGTHUNIT.,.CENTI.,.METRE.); +ENDSEC; +END-ISO-10303-21;