From 2b27b86b34aeb9c7718743bfef880fb0c509a059 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Thu, 1 Mar 2012 21:17:06 +0000 Subject: [PATCH] - IfcGeom: Major performance improvement by only sewing faces of IfcConnectedFaceSets when needed for boolean operations - Automatic tests for several well known IFC files on the Internet - IfcBlender: Make visibility in render consistent with 3d view - Some compatibility for Ifc2x files with IfcShapeRepresentations and RepresentationIdentifier 'IAI' --- .../io_import_scene_ifc/__init__.py | 2 + src/ifcgeom/IfcGeom.h | 5 + src/ifcgeom/IfcGeomFunctions.cpp | 52 ++++- src/ifcgeom/IfcGeomObjects.cpp | 13 +- src/ifcgeom/IfcGeomShapes.cpp | 18 +- test/bpy.py | 119 +++++++++++ test/run.py | 198 ++++++++++++++++++ 7 files changed, 395 insertions(+), 12 deletions(-) create mode 100644 test/bpy.py create mode 100644 test/run.py diff --git a/src/ifcblender/io_import_scene_ifc/__init__.py b/src/ifcblender/io_import_scene_ifc/__init__.py index 65a672c321..1449d25392 100644 --- a/src/ifcblender/io_import_scene_ifc/__init__.py +++ b/src/ifcblender/io_import_scene_ifc/__init__.py @@ -78,6 +78,7 @@ def import_ifc(filename, use_names, process_relations): else: valid_file = IfcImport.Init(filename) if not valid_file: + IfcImport.CleanUp() return False print("Done reading file") id_to_object = {} @@ -136,6 +137,7 @@ def import_ifc(filename, use_names, process_relations): ob.id, ob_guid, ob_name, ob_type bob.hide = ob_type == 'IfcSpace' or ob_type == 'IfcOpeningElement' + bob.hide_render = bob.hide if ob.id not in id_to_object: id_to_object[ob.id] = [] id_to_object[ob.id].append(bob) diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 7719ce8449..6036f36d14 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -42,6 +42,8 @@ #include "../ifcgeom/IfcShapeList.h" +#define FACESET_AS_COMPOUND 1 + namespace IfcGeom { bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face); bool convert_shapes(const IfcUtil::IfcBaseClass* L, ShapeList& result); @@ -51,6 +53,9 @@ namespace IfcGeom { bool convert_curve(const IfcUtil::IfcBaseClass* L, Handle(Geom_Curve)& result); bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Face& result); bool convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes); + bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid); + bool is_compound(const TopoDS_Shape& shape); + const TopoDS_Shape& ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid); bool profile_helper(int numVerts, float* verts, int numFillets, int* filletIndices, float* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face); float shape_volume(const TopoDS_Shape& s); namespace Cache { diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 8f56bda120..0453cb868e 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -82,6 +82,40 @@ #include "../ifcgeom/IfcGeom.h" +bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) { + BRepOffsetAPI_Sewing builder; + builder.SetTolerance(0.01); + TopExp_Explorer exp(compound,TopAbs_FACE); + if ( ! exp.More() ) return false; + for ( ; exp.More(); exp.Next() ) { + TopoDS_Face face = TopoDS::Face(exp.Current()); + builder.Add(face); + } + builder.Perform(); + shape = builder.SewedShape(); + try { + ShapeFix_Solid sf_solid; + sf_solid.LimitTolerance(0.01); + shape = sf_solid.SolidFromShell(TopoDS::Shell(shape)); + } catch(...) {} + return true; +} + +bool IfcGeom::is_compound(const TopoDS_Shape& shape) { + bool has_solids = TopExp_Explorer(shape,TopAbs_SHELL).More() != 0; + bool has_shells = TopExp_Explorer(shape,TopAbs_SHELL).More() != 0; + bool has_compounds = TopExp_Explorer(shape,TopAbs_COMPOUND).More() != 0; + bool has_faces = TopExp_Explorer(shape,TopAbs_FACE).More() != 0; + return has_compounds && has_faces && !has_solids && !has_shells; +} + +const TopoDS_Shape& IfcGeom::ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid) { + const bool is_comp = IfcGeom::is_compound(shape); + if ( ! is_comp ) return shape; + IfcGeom::create_solid_from_compound(shape,solid); + return solid; +} + bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes) { // Iterate over IfcOpeningElements @@ -116,7 +150,8 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x // Iterate over the shapes of the IfcProduct for ( IfcGeom::ShapeList::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) { - const TopoDS_Shape& entity_shape_unlocated = *(it3->second); + TopoDS_Shape entity_shape_solid; + const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(*(it3->second),entity_shape_solid); const gp_GTrsf& entity_shape_gtrsf = *(it3->first); TopoDS_Shape entity_shape; if ( entity_shape_gtrsf.Form() == gp_Other ) { @@ -128,7 +163,8 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x // Iterate over the shapes of the IfcOpeningElements for ( IfcGeom::ShapeList::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) { - const TopoDS_Shape& opening_shape_unlocated = *(it4->second); + TopoDS_Shape opening_shape_solid; + const TopoDS_Shape& opening_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(*(it4->second),opening_shape_solid); const gp_GTrsf& opening_shape_gtrsf = *(it4->first); if ( opening_shape_gtrsf.Form() == gp_Other ) { Ifc::LogMessage("warning","Applying non uniform transformation to opening of:",entity->entity); @@ -143,12 +179,16 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x const float original_shape_volume = shape_volume(entity_shape); - entity_shape = BRepAlgoAPI_Cut(entity_shape,opening_shape); + BRepAlgoAPI_Cut brep_cut(entity_shape,opening_shape); + + if ( brep_cut.IsDone() ) { + entity_shape = brep_cut; - const float volume_after_subtraction = shape_volume(entity_shape); + const float volume_after_subtraction = shape_volume(entity_shape); - if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) ) - Ifc::LogMessage("warning","Warning subtraction yields unchanged volume:",entity->entity); + if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) ) + Ifc::LogMessage("warning","Warning subtraction yields unchanged volume:",entity->entity); + } } cut_shapes.push_back(IfcGeom::LocationShape(new gp_GTrsf(),new TopoDS_Shape(entity_shape))); } diff --git a/src/ifcgeom/IfcGeomObjects.cpp b/src/ifcgeom/IfcGeomObjects.cpp index 1c378ef056..90d8eadd3d 100644 --- a/src/ifcgeom/IfcGeomObjects.cpp +++ b/src/ifcgeom/IfcGeomObjects.cpp @@ -299,10 +299,15 @@ IfcGeomObjects::IfcGeomObject* _get() { // Has the list of IfcProducts for this representation been initialized? if ( ! entities ) { - if ( shaperep->RepresentationIdentifier() != "Body" && - shaperep->RepresentationIdentifier() != "Facetation" ) { - _nextShape(); - continue; + if ( shaperep->hasRepresentationIdentifier() ) { + const std::string representation_identifier = shaperep->RepresentationIdentifier(); + if ( shaperep->hasRepresentationType() && representation_identifier == "IAI" && shaperep->RepresentationType() != "BoundingBox" ) { + // Allow for Ifc 2x compatibility + } else if ( representation_identifier != "Body" && + representation_identifier != "Facetation" ) { + _nextShape(); + continue; + } } Ifc2x3::IfcProductRepresentation::list prodreps = shaperep->OfProductRepresentation(); entities = Ifc2x3::IfcProduct::list( new IfcTemplatedEntityList() ); diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index 47f5b134f9..a8cc1705f7 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -132,8 +132,8 @@ bool IfcGeom::convert(const Ifc2x3::IfcPolygonalBoundedHalfSpace::ptr l, TopoDS_ if ( ! IfcGeom::convert_wire(l->PolygonalBoundary(),wire) || ! wire.Closed() ) return false; gp_Trsf trsf; convert(l->Position(),trsf); - TopoDS_Shape extrusion = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,20000.0)); - gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-10000.0)); + TopoDS_Shape extrusion = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,200.0)); + gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-100.0)); extrusion.Move(down*trsf); shape = BRepAlgoAPI_Cut(extrusion,halfspace); return true; @@ -179,20 +179,33 @@ bool IfcGeom::convert(const Ifc2x3::IfcBooleanClippingResult::ptr l, TopoDS_Shap return true; } bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& shape) { +#ifdef FACESET_AS_COMPOUND + TopoDS_Compound compound; + BRep_Builder builder; + builder.MakeCompound(compound); +#else BRepOffsetAPI_Sewing builder; builder.SetTolerance(0.01); +#endif Ifc2x3::IfcFace::list faces = l->CfsFaces(); bool facesAdded = false; for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) { TopoDS_Face face; if ( IfcGeom::convert_face(*it,face) ) { +#ifdef FACESET_AS_COMPOUND + builder.Add(compound,face); +#else builder.Add(face); +#endif facesAdded = true; } else { Ifc::LogMessage("Warning","Invalid face:",(*it)->entity); } } if ( ! facesAdded ) return false; +#ifdef FACESET_AS_COMPOUND + shape = compound; +#else builder.Perform(); shape = builder.SewedShape(); try { @@ -200,6 +213,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh solid.LimitTolerance(0.01); shape = solid.SolidFromShell(TopoDS::Shell(shape)); } catch(...) {} +#endif return true; } bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, ShapeList& shapes) { diff --git a/test/bpy.py b/test/bpy.py new file mode 100644 index 0000000000..a60e2d941d --- /dev/null +++ b/test/bpy.py @@ -0,0 +1,119 @@ +############################################################################### +# # +# This file is part of IfcOpenShell. # +# # +# IfcOpenShell is free software: you can redistribute it and/or modify # +# it under the terms of the Lesser GNU General Public License as published by # +# the Free Software Foundation, either version 3.0 of the License, or # +# (at your option) any later version. # +# # +# IfcOpenShell is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# Lesser GNU General Public License for more details. # +# # +# You should have received a copy of the Lesser GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +############################################################################### +# # +# Do not run this script directly, it is called by run.py # +# # +############################################################################### + +import os +import bpy +import sys +import time +try: from io_import_scene_ifc import import_ifc +except: + print("[Error] Unable to import IfcOpenShell") + sys.exit(1) +from mathutils import Vector as V +from math import radians + +scn = bpy.context.scene + +for ob in bpy.data.objects: + scn.objects.unlink(ob) + +if sys.argv[-2] != 'render': sys.exit(0) + +fn = sys.argv[-1] +t1 = time.time() +succes = import_ifc(fn,True,False) +if not succes: + print("[Error] Import of %s failed"%fn) + sys.exit(1) + +dt = time.time()-t1 +print ("[Notice] Conversion took %.2f seconds"%dt) + +cam = bpy.data.cameras.new('cam') +cam.angle = radians(45) +cam_ob = bpy.data.objects.new('cam',cam) +scn.objects.link(cam_ob) +cam_ob.rotation_euler = (radians(67),0,radians(45)) + +scn.camera = cam_ob +scn.render.resolution_percentage = 100 +scn.render.resolution_x = 2048 +scn.render.resolution_y = 2048 +scn.world.horizon_color = (1,1,1) +scn.world.ambient_color = (0.05,0.05,0.05) +scn.render.color_mode = 'RGBA' + +for m in bpy.data.materials: m.specular_intensity = 0 +def material(name,settings): + m = bpy.data.materials.get(name) + if not m: return + for k,v in settings.items(): + setattr(m,k,v) + +material("IfcWall",{"diffuse_color":[1,1,1],"diffuse_intensity":1}) +material("IfcWallStandardCase",{"diffuse_color":[1,1,1],"diffuse_intensity":1}) +material("IfcSite",{"diffuse_color":[0.4,0.5,0.25]}) +material("IfcSlab",{"diffuse_color":[0.2,0.2,0.2]}) +material("IfcDoor",{"diffuse_color":[0.25,0.1,0.05]}) +material("IfcWindow",{"diffuse_color":[0.5,0.7,0.5],"use_transparency":True,"alpha":0.3}) +material("IfcRoof",{"diffuse_color":[0.35,0.2,0.2]}) +material("IfcFurnishingElement",{"diffuse_color":[0.8,0.7,0.5]}) +material("IfcBuildingElementPro",{"diffuse_intensity":0.6}) + +def create_lamp(eul): + l = bpy.data.lamps.new('l','SUN') + l.energy = 1.3 + l_ob = bpy.data.objects.new('l',l) + scn.objects.link(l_ob) + l_ob.rotation_euler = [radians(e) for e in eul] + +create_lamp((20,0,60)) +create_lamp((0,-120,-50)) + +A = V([1e9]*3) +B = V([-1e9]*3) + +for ob in scn.objects: + if ob.type != 'MESH': continue + if ob.hide: continue + bb = [ob.matrix_world*V(x) for x in ob.bound_box] + for b in bb: + for i in range(3): + if b[i] < A[i]: A[i] = b[i] + if b[i] > B[i]: B[i] = b[i] + +C = V((1.2,-1.2,0.6)) +D = B-A +E = max(D)*C + (A+B)/2 + +cam_ob.location = E +cam.clip_end = max(D) * 10 + +scn.render.filepath = os.path.join("output",os.path.basename(fn)+".png") + +bpy.ops.render.render(write_still=True) +bpy.ops.wm.save_mainfile(filepath=os.path.join("output",os.path.basename(fn)+".blend"),compress=True) + +sys.exit(0) diff --git a/test/run.py b/test/run.py new file mode 100644 index 0000000000..214973ac5b --- /dev/null +++ b/test/run.py @@ -0,0 +1,198 @@ +############################################################################### +# # +# This file is part of IfcOpenShell. # +# # +# IfcOpenShell is free software: you can redistribute it and/or modify # +# it under the terms of the Lesser GNU General Public License as published by # +# the Free Software Foundation, either version 3.0 of the License, or # +# (at your option) any later version. # +# # +# IfcOpenShell is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# Lesser GNU General Public License for more details. # +# # +# You should have received a copy of the Lesser GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +############################################################################### +# # +# The IfcOpenShell test suite downloads IFC files that are publicely # +# available on the internet and uses Blender and IfcOpenShell to generate a # +# render of the parsed file. For the script to run, Blender needs to be # +# installed and added to PATH. # +# # +############################################################################### + +import os +import sys +import shutil +import inspect +import subprocess +from zipfile import ZipFile +from urllib.request import urlretrieve + +# Test whether Blender and IfcOpenShell are installed +if subprocess.call(['blender','-b','-P','bpy.py','TEST']) != 0: + print("[Error] Failed to launch Blender") + sys.exit(1) +else: + print("[Notice] Found Blender and IfcOpenShell on system") + +# Global variables for keeping track of test cases +test_cases = [] +failed = [] + +# Create the ouput directory +cwd = os.path.abspath(os.path.dirname(inspect.getfile(inspect.currentframe()))) +os.chdir(cwd) +if not os.path.exists("output"): os.mkdir("output") +if not os.path.exists("input"): os.mkdir("input") + +def extension(fn): + return os.path.splitext(fn)[-1].lower() + +# Class to download extract and convert IFC files +class TestFile: + def __init__(self,fn,store_as=None): + global test_cases + self.fn = fn + self.store_as = store_as + self.failed = [] + test_cases.append(self) + def __call__(self): + if self.fn.startswith("http://") or self.fn.startswith("ftp://"): + fn = self.store_as if self.store_as else self.fn.split("/")[-1] + if os.path.exists(os.path.join("input",fn)): + print ("[Notice] Already downloaded:",fn) + else: + print ("[Notice] Downloading:",fn) + urlretrieve(self.fn,os.path.join("input",fn)) + self.fn = fn + if extension(self.fn) == '.zip': + print ("[Notice] Extracting:",self.fn) + zf = ZipFile(os.path.join("input",self.fn)) + self.fn = [n for n in zf.namelist() if extension(n) == '.ifc' and not n.startswith('__') and not n.startswith('.')] + for fn in self.fn: + if not os.path.exists(os.path.join("input",fn)): zf.extract(fn,"input") + zf.close() + else: self.fn = [self.fn] + for fn in self.fn: + print ("[Notice] Rendering:",fn) + succes = subprocess.call(['blender','-b','-P','bpy.py','render',os.path.join("input",fn)]) == 0 + if not succes: self.failed.append(fn) + return len(self.failed) == 0 + def __str__(self): return "\n".join(self.failed) if len(self.failed) else "" + +# Karlsruher Institut fuer Technologie +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/ADT-FZK-Haus-2005-2006.zip") +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/Nem-FZK-Haus-2x3.zip") +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/AC14-FZK-Haus.zip") +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/FZK-Haus-EliteCAD.zip") + +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/FJK-Project-Final.zip") + +TestFile("http://www.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/Bien-Zenker_Jasmin-Sun-AC14-V2-IFC.zip") + +TestFile("http://www.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/ADT-Smiley-West-Project-14-10-2005.zip") +TestFile("http://www.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/Allplan-Smiley-West.zip") +TestFile("http://www.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/AC-11-Smiley-West-04-07-2007-IFC.zip") + +TestFile("http://www.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/Allplan-2008-Institute-Var-2-IFC.zip") +TestFile("http://www.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/AC11-Institute-Var-2-IFC.zip") + +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/PART02_Wilfer_200302_20070209_IFC.zip") +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/PART06_Kermi_200405_20070401_IFC.zip") + +TestFile("http://iai-typo3.iai.fzk.de/www-extern-kit/fileadmin/download/download-vrsys/Ettenheim-GIS-05-11-2006_optimized.zip") + +# Selvaag Gruppen +TestFile("ftp://ftp.dds.no/pub/ifc/Munkerud/Munkerud_hus6_BE.zip") + +# Statsbygg +TestFile("ftp://ftp.dds.no/pub/ifc/HiTOS/2x3_HiTOS_EL_new.zip") +TestFile("ftp://ftp.dds.no/pub/ifc/HiTOS/2x3_HiTOS_HVAC_new.zip") +TestFile("ftp://ftp.dds.no/pub/ifc/HiTOS/HITOS_Architectural_2006-10-25.zip") + +# Nemetschek Vectorworks +TestFile("http://download2cf.nemetschek.net/www_misc/bim/DCR-LOD_100.zip") +TestFile("http://download2cf.nemetschek.net/www_misc/bim/DCR-LOD_200.zip") +# Rather large: +# TestFile("http://download2cf.nemetschek.net/www_misc/bim/DCR-LOD_300.zip") + +# Data Design Systems +TestFile("ftp://ftp.dds.no/pub/ifc/BardNa/Dds_BardNa.zip") + +# Common Building Information Model Files +TestFile("http://projects.buildingsmartalliance.org/files/?artifact_id=4278","2011-09-14-Duplex-IFC.zip") +TestFile("http://projects.buildingsmartalliance.org/files/?artifact_id=4284","2011-09-14-Office-IFC.zip") +# Rather large +# TestFile("http://projects.buildingsmartalliance.org/files/?artifact_id=4289","2011-09-14-Clinic-IFC.zip") + +# http://openifcmodel.cs.auckland.ac.nz IAI +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912101-01wall_layers_number_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912101-02wall_opening_straight_ac_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912101-03wall_recess_ben_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912101-04wall_L-shape_all_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912102-01beam_profile_basic_rev_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912102-01beam_profile_para_ac_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912102-02brep_beams_opening_ben_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912102-02extruded_beam_open_tek_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912103-01col_profile_clip_ben_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912103-01columns_basic_all_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912103-02col_brep_opening_ben_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912103-02OpeningsInExtrudedColumns_rev_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912104-01slab_profile_basic_ac_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912104-03extruded_slab_openings_all_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912104-04slab_recess_tek_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912105-01doors_explicit_geom_all_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912105-02DoorOperationsPlacementInsideWall_rev_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912106-01window_brep_ac_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912106-02windows_placement_inside_wall_all_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912107-01stair_geom_ac_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912107-01stair_geometry_ben_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912108-01ramp_geometry_ben_2.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912108-01RampAsContainer_rev_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912109-01railing_brep_ac_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/0912109-01railing_extrusion_tek_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/09121010-01RoofWithGeometry_rev_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/09121010-02roof_with_openings_ben_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/09121011curtain_wall_basic_rev_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/09121012mem_profile_basic_tek_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/09121013plate_steel_exam_tek_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/09121014pile_basic_tek_1.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/09121015footing_ac_1.ifc") + +# http://openifcmodel.cs.auckland.ac.nz NIST +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210AISC_Sculpture_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210AISC_Sculpture_param.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210analysis_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210analysis_param.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210Bentley1_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210Bentley1_param.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210CADstudio_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210cutouts_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210DesignData1_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210DesignData3_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210PlayersTheater_param.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210profiles_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210profilescp1_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210sections_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210threebeams_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210TrainingStructure_brep.ifc") +TestFile("http://openifcmodel.cs.auckland.ac.nz/_models/171210eccentricity_physical.ifc") + +for test in test_cases: + succes = test() + if not succes: + failed.append(test) + +if len(failed): + print("[Notice] Conversion failed for the following cases:") + for test in failed: + print (test) +else: + print("[Notice] All cases succeeded") + \ No newline at end of file