BIM: cleanup imports in importers

This commit is contained in:
marcuspollio
2025-03-23 23:30:31 +01:00
parent 8ab6bd7d4b
commit 7bbfa68698
14 changed files with 157 additions and 127 deletions

View File

@@ -18,41 +18,44 @@
# * USA *
# * *
# ***************************************************************************
"""Provide the exporter for IFC files used above all in Arch and BIM.
Internally it uses IfcOpenShell, which must be installed before using.
"""
__title__ = "FreeCAD IFC export"
__author__ = ("Yorik van Havre", "Jonathan Wiedemann", "Bernd Hahnebach")
__url__ = "https://www.freecad.org"
## @package exportIFC
# \ingroup ARCH
# \brief IFC file format exporter
#
# This module provides tools to export IFC files.
"""Provide the exporter for IFC files used above all in Arch and BIM.
Internally it uses IfcOpenShell, which must be installed before using.
"""
import math
import os
import time
import tempfile
import math
from builtins import open as pyopen
import FreeCAD
import Part
import Draft
import FreeCADGui
import Arch
import Draft
import DraftVecUtils
import Part
import ArchIFCSchema
from importers import exportIFCHelper
from importers import exportIFCStructuralTools
from DraftGeomUtils import vec
from importers.importIFCHelper import dd2dms
from draftutils import params
from draftutils.messages import _msg, _err
import FreeCADGui
from importers import exportIFCHelper
from importers import exportIFCStructuralTools
from importers.importIFCHelper import dd2dms
__title__ = "FreeCAD IFC export"
__author__ = ("Yorik van Havre", "Jonathan Wiedemann", "Bernd Hahnebach")
__url__ = "https://www.freecad.org"
PARAMS = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/BIM")

View File

@@ -22,12 +22,15 @@
import json
import math
import FreeCAD
# import Draft
import ifcopenshell
from ifcopenshell import guid
import FreeCAD
# import Draft
from draftutils import params
def getObjectsOfIfcType(objects, ifcType):
results = []
for object in objects:

View File

@@ -19,20 +19,24 @@
#* *
#***************************************************************************
import os,FreeCAD,Mesh
__title__ = "FreeCAD 3DS importer"
__author__ = "Yorik van Havre"
__url__ = "https://www.freecad.org"
DEBUG = True
## @package import3DS
# \ingroup ARCH
# \brief 3DS file format importer
#
# This module provides tools to import 3DS files.
import os
import FreeCAD
import Mesh
DEBUG = True
def check3DS():
"checks if collada if available"
global dom3ds

View File

@@ -19,18 +19,29 @@
#* *
#***************************************************************************
__title__ = "FreeCAD Collada importer"
__author__ = "Yorik van Havre"
__url__ = "https://www.freecad.org"
## @package importDAE
# \ingroup ARCH
# \brief DAE (Collada) file format importer and exporter
#
# This module provides tools to import and export Collada (.dae) files.
import os
from typing import Optional
import numpy as np
from draftutils import params
import FreeCAD
import Arch
import Draft
import FreeCAD
import Mesh
import MeshPart
from draftutils import params
if FreeCAD.GuiUp:
from draftutils.translate import translate
else:
@@ -39,16 +50,6 @@ else:
return text
# \endcond
## @package importDAE
# \ingroup ARCH
# \brief DAE (Collada) file format importer and exporter
#
# This module provides tools to import and export Collada (.dae) files.
__title__ = "FreeCAD Collada importer"
__author__ = "Yorik van Havre"
__url__ = "https://www.freecad.org"
DEBUG = True

View File

@@ -23,6 +23,14 @@ __title__ = "FreeCAD GbXml exporter"
__author__ = "Yorik van Havre"
__url__ = "https://www.freecad.org"
## @package importGBXML
# \ingroup ARCH
# \brief GBXML file format exporter
#
# This module provides tools to export GBXML files.
from builtins import open as pyopen
import FreeCAD
import Draft
@@ -34,11 +42,6 @@ else:
return txt
# \endcond
## @package importGBXML
# \ingroup ARCH
# \brief GBXML file format exporter
#
# This module provides tools to export GBXML files.
def export(objectslist,filename):

View File

@@ -18,40 +18,42 @@
# * USA *
# * *
# ***************************************************************************
"""Provide the importer for IFC files used above all in Arch and BIM.
Internally it uses IfcOpenShell, which must be installed before using.
"""
__title__ = "FreeCAD IFC importer - Enhanced IfcOpenShell-only version"
__author__ = ("Yorik van Havre", "Jonathan Wiedemann", "Bernd Hahnebach")
__url__ = "https://www.freecad.org"
## @package importIFC
# \ingroup ARCH
# \brief IFC file format importer
#
# This module provides tools to import IFC files.
"""Provide the importer for IFC files used above all in Arch and BIM.
Internally it uses IfcOpenShell, which must be installed before using.
"""
import os
import math
import time
import FreeCAD
import Part
import Draft
import Arch
import DraftVecUtils
import ArchIFCSchema
from importers import importIFCHelper
from importers import importIFCmulticore
import Draft
import DraftVecUtils
import Part
from draftutils import params
from draftutils.messages import _msg, _err
from importers import importIFCHelper
from importers import importIFCmulticore
if FreeCAD.GuiUp:
import FreeCADGui as Gui
__title__ = "FreeCAD IFC importer - Enhanced IfcOpenShell-only version"
__author__ = ("Yorik van Havre", "Jonathan Wiedemann", "Bernd Hahnebach")
__url__ = "https://www.freecad.org"
DEBUG = False # Set to True to see debug messages. Otherwise, totally silent
ZOOMOUT = True # Set to False to not zoom extents after import

View File

@@ -18,8 +18,8 @@
# * USA *
# * *
# ***************************************************************************
"""Helper functions that are used by IFC importer and exporter."""
import sys
import math
import FreeCAD

View File

@@ -25,16 +25,27 @@
# #
############################################################################
import FreeCAD, Arch, Draft, os, sys, time, Part, DraftVecUtils, uuid, math, re
from builtins import open as pyopen
from draftutils import params
from draftutils.translate import translate
__title__="FreeCAD IFC importer"
__author__ = "Yorik van Havre"
__url__ = "https://www.freecad.org"
import math
import os
import re
import time
import uuid
from builtins import open as pyopen
import FreeCAD
import Arch
import Draft
import DraftVecUtils
import Part
from draftutils import params
from draftutils.translate import translate
# config
subtractiveTypes = ["IfcOpeningElement"] # elements that must be subtracted from their parents
SCHEMA = "http://www.steptools.com/support/stdev_docs/ifcbim/ifc4.exp" # only for internal parser
@@ -937,7 +948,8 @@ def export(exportList,filename):
have IFC export capabilities. IFC export currently requires an experimental
version of IfcOpenShell available from https://github.com/aothms/IfcOpenShell""")
return
import Arch,Draft
import Draft
import Arch
# creating base IFC project
getConfig()
@@ -1139,7 +1151,8 @@ def export(exportList,filename):
ifc.write()
if exporttxt:
import time, os
import os
import time
txtstring = "List of objects exported by FreeCAD in file\n"
txtstring += filename + "\n"
txtstring += "On " + time.ctime() + "\n"
@@ -1181,7 +1194,8 @@ def getTuples(data,scale=1,placement=None,normal=None,close=True):
elif isinstance(data,Part.Shape):
t = []
if len(data.Wires) == 1:
import Part,DraftGeomUtils
import Part
import DraftGeomUtils
data = Part.Wire(Part.__sortEdges__(data.Wires[0].Edges))
verts = data.Vertexes
try:
@@ -1261,7 +1275,6 @@ def getIfcExtrusionData(obj,scale=1,nosubs=False):
edges = Part.__sortEdges__(p.Edges)
for e in edges:
if isinstance(e.Curve,Part.Circle):
import math
follow = True
if last:
if not DraftVecUtils.equals(last,e.Vertexes[0].Point):
@@ -1779,7 +1792,7 @@ class IfcDocument:
def explorer(filename,schema="IFC2X3_TC1.exp"):
"returns a PySide dialog showing the contents of an IFC file"
from PySide import QtCore,QtGui
from PySide import QtGui
ifc = IfcDocument(filename,schema)
schema = IfcSchema(schema)
tree = QtGui.QTreeWidget()

View File

@@ -18,18 +18,21 @@
# * USA *
# * *
# ***************************************************************************
"""FreeCAD IFC importer - Multicore version"""
import os
import sys
import time
import os
import FreeCAD
import Draft
import Arch
from importers import importIFCHelper
from FreeCAD import Base
import ArchIFC
import Draft
from FreeCAD import Base
from importers import importIFCHelper
# global dicts to store ifc object/freecad object relationships

View File

@@ -19,9 +19,18 @@
#* *
#***************************************************************************
import os
## @package importOBJ
# \ingroup ARCH
# \brief OBJ file format exporter
#
# This module provides tools to import & export OBJ files.
# It is an alternative to the standard Mesh OBJ exporter
# and supports exporting faces with more than 3 vertices
# and supports object colors / materials
import codecs
import ntpath
import os
from builtins import open as pyopen
import FreeCAD
@@ -31,6 +40,7 @@ import DraftGeomUtils
import Mesh
import MeshPart
import Part
from draftutils import params
if FreeCAD.GuiUp:
@@ -41,14 +51,6 @@ else:
return text
# \endcond
## @package importOBJ
# \ingroup ARCH
# \brief OBJ file format exporter
#
# This module provides tools to import & export OBJ files.
# It is an alternative to the standard Mesh OBJ exporter
# and supports exporting faces with more than 3 vertices
# and supports object colors / materials
def findVert(aVertex,aList):
"finds aVertex in aList, returns index"

View File

@@ -23,20 +23,19 @@ __title__ = "FreeCAD SweetHome3D Importer"
__author__ = "Yorik van Havre"
__url__ = "https://www.freecad.org"
import os
import xml.sax
import zipfile
import FreeCAD
from FreeCAD import Base
## @package importSH3D
# \ingroup ARCH
# \brief SH3D (SweetHome3D) file format importer
#
# This module provides tools to import SH3D files created from Sweet Home 3D.
import os
import zipfile
import FreeCAD
from FreeCAD import Base
DEBUG = True

View File

@@ -18,9 +18,10 @@
# * USA *
# * *
# ***************************************************************************
"""Helper functions that are used by SH3D importer."""
import itertools
import numpy as np
import math
import os
import re
@@ -29,6 +30,9 @@ import uuid
import xml.etree.ElementTree as ET
import zipfile
import numpy as np
import FreeCAD as App
import Arch
import BOPTools.SplitFeatures
import BOPTools.BOPFeatures
@@ -43,8 +47,6 @@ import TechDraw
from draftutils.messages import _err, _log, _msg, _wrn
from draftutils.params import get_param_arch
import FreeCAD as App
if App.GuiUp:
import FreeCADGui as Gui
from draftutils.translate import translate
@@ -1367,8 +1369,8 @@ class RoomHandler(BaseHandler):
Returns:
bool: True if at least one pair of edge intersect.
list(tuple): a list of tuple of v1, e1, v2, e2 where v1 is the
intersection on the first edge e1, and v2 is the intersection
list(tuple): a list of tuple of v1, e1, v2, e2 where v1 is the
intersection on the first edge e1, and v2 is the intersection
on the second edge e2.
"""
for i in range(len(edges)):
@@ -1380,7 +1382,7 @@ class RoomHandler(BaseHandler):
continue
for (v1, v2) in vectors:
# Check that the intersections are not extremities
# If both v1 and v2 are extremities then the edges
# If both v1 and v2 are extremities then the edges
# are connected which is not really a self-intersecting
# situation.
if v1 not in [v.Point for v in e1.Vertexes] or v2 not in [v.Point for v in e2.Vertexes]:
@@ -1949,8 +1951,8 @@ class WallHandler(BaseHandler):
if is_wall_straight:
# In order to make sure that the edges are not self-intersecting
# create a convex hull and use these points instead. Maybe
# overkill for a 4 point wall, however not sure how to invert
# create a convex hull and use these points instead. Maybe
# overkill for a 4 point wall, however not sure how to invert
# edges.
points = list(map(lambda v: v.Point, face.Vertexes))
new_points = convex_hull(points)
@@ -2247,7 +2249,7 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
# Note that we only move on the XY plane since we assume that
# only the right and left face will be used for supporting the
# doorOrWndow. It might not be correct for roof windows and floor
# doorOrWndow. It might not be correct for roof windows and floor
# windows...
# The absolute coordinate of the corner of the doorOrWindow
dow_abs_corner = dow_abs_center.add(App.Vector(-width/2, -depth/2, 0))
@@ -2264,7 +2266,7 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
is_opened = False
wall_width = depth
# Get all the walls hosting that doorOrWndow.
#
#
# The main wall is used to determine the projection of the
# doorOrWindow bounding_box, and thus the placement of the
# resulting Arch element. The main wall is the one containing
@@ -2289,7 +2291,7 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
# Get the left and right face for the main_wall
(_, wall_lface, _, wall_rface) = self.get_faces(main_wall)
# The general process is as follow:
# The general process is as follow:
# 1- Find the bounding box face whose normal is properly oriented
# with respect to the doorOrWindow (+90º)
# 2- Find the wall face with the same orientation.
@@ -2329,7 +2331,7 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
self._debug_shape(wall_face, f"{label_prefix}-bb-projected-onto#{main_wall.Label}", MAGENTA)
self._debug_shape(projected_face, f"{label_prefix}-bb-projection#{main_wall.Label}", RED)
# Determine the base vertex that I later use for the doorOrWindow
# Determine the base vertex that I later use for the doorOrWindow
# placement
base_vertex = self._get_base_vertex(main_wall, is_on_right, projected_face)
@@ -2378,12 +2380,12 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
"""Returns the wall(s) and slab(s) intersecting with the doorOrWindow
bounding_box.
The main wall is the one that contains the doorOrWndow bounding_box
CenterOfGravity. Note that this will not work for open doorOrWindow
(i.e.whose bounding_box is a lot greater than the containing wall).
The main wall is the one that contains the doorOrWndow bounding_box
CenterOfGravity. Note that this will not work for open doorOrWindow
(i.e.whose bounding_box is a lot greater than the containing wall).
The _create_door, has a mitigation process for that case.
The main_wall is used to get the face on which to project the
The main_wall is used to get the face on which to project the
doorOrWindows bounding_box, and from there the placement of the
element on the wall's face.
@@ -2391,7 +2393,7 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
- find out whether the doorOrWindow span several floors, if so
add all the walls (and slab) for that floor to the list of elements
to check.
- once the list of elements to check is complete we check if the
- once the list of elements to check is complete we check if the
doorOrWindow bounding_box has a volume in common with the wall.
Args:
@@ -2401,8 +2403,8 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
Returns:
tuple(Arch::Wall, list(Arch::Wall)): a tuple of the main wall (if
any could be found and a list of any other Arch element that
might be host of that
any could be found and a list of any other Arch element that
might be host of that
"""
relevant_walls = [*self.importer.get_walls(floor)]
# First find out which floor the window might be have an impact on.
@@ -2453,7 +2455,7 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
"""
debug_geometry = self.importer.preferences["DEBUG_GEOMETRY"]
# Note that the 'angle' refers to the angle of the face, not its normal.
# we therefore add a '+90º' in SH3D coordinate (i.e. -90º in FC
# we therefore add a '+90º' in SH3D coordinate (i.e. -90º in FC
# coordinate).
# XXX: Can it be speed up by assuming that left and right are always
# Face2 and Face4???
@@ -2474,7 +2476,7 @@ class DoorOrWindowHandler(BaseFurnitureHandler):
"""Return the base vertex used to place a doorOrWindow.
Returns the vertex of the projected_face that serves as the
base for the Placement when creating the doorOrWindow. It is
base for the Placement when creating the doorOrWindow. It is
the lowest vertex and closest to the wall reference point.
The wall reference point depends on whether we are on the
right or left side of the wall.
@@ -2618,7 +2620,7 @@ class FurnitureHandler(BaseFurnitureHandler):
mesh_transform.scale(-1, 1, 1) # Mirror along X
if debug_geometry: self._debug_mesh(mesh, f"{name}-mirrored", mesh_transform)
# We add an initial 90º in order for a yaw-pitch-roll-rotation free
# We add an initial 90º in order for a yaw-pitch-roll-rotation free
# model to appear properly in FC
mesh_transform.rotateX(math.pi/2)
if debug_geometry: self._debug_mesh(mesh, f"{name}-x90", mesh_transform)
@@ -2636,7 +2638,7 @@ class FurnitureHandler(BaseFurnitureHandler):
z_scale = height / normilized_bb.ZLength
mesh_transform.scale(x_scale, y_scale, z_scale)
if debug_geometry:
if debug_geometry:
model_size = App.Vector(model_bb.XLength, model_bb.YLength, model_bb.ZLength)
normalized_size = App.Vector(normilized_bb.XLength, normilized_bb.YLength, normilized_bb.ZLength)
final_size = App.Vector(width, depth, height)
@@ -2645,7 +2647,7 @@ class FurnitureHandler(BaseFurnitureHandler):
self._debug_mesh(mesh, f"{name}-scaled", mesh_transform, MAGENTA)
# At that point the mesh has the proper scale. We determine the placement.
# In order to do that, we need to apply the different rotation (ypr) and
# In order to do that, we need to apply the different rotation (ypr) and
# also the translation from the origin to the final point.
if pitch != 0:
r_pitch = App.Rotation(X_NORM, Radian=-pitch)
@@ -3011,4 +3013,3 @@ def convex_hull(points, tol=1e-6):
# point_coords = np.array([[p.x, p.y] for p in points])
# new_points = [points[i] for i in scipy.spatial.ConvexHull(point_coords).vertices]
# return new_points[0]

View File

@@ -26,6 +26,7 @@ from builtins import open as pyopen
import FreeCAD
translate = FreeCAD.Qt.translate
def open(filename):
"""opens a SHP/SHX/DBF file in a new FreeCAD document"""
@@ -144,11 +145,6 @@ def checkShapeFileLibrary():
f = pyopen(fp,"wb")
f.write(b)
f.close()
try:
import shapefile
except Exception:
FreeCAD.Console.PrintError(translate("Arch","Could not download shapefile module. Aborting.")+"\n")
return False
else:
FreeCAD.Console.PrintError(translate("Arch","Shapefile module not downloaded. Aborting.")+"\n")
return False

View File

@@ -35,18 +35,27 @@
# Development reload oneliner:
# def re(): from importlib import reload;import importWebGL;reload(importWebGL);o=FreeCAD.getDocument("YourDocName");importWebGL.export([o.getObject("YourBodyName")],u"C:/path/to/your/file.htm");
## @package importWebGL
# \ingroup ARCH
# \brief FreeCAD WebGL Exporter
#
# This module provides tools to export HTML files containing the
# exported objects in WebGL format and a simple three.js-based viewer.
"""FreeCAD WebGL Exporter"""
from typing import NotRequired, TypedDict
import FreeCAD
import Mesh
import Draft
import Part
import OfflineRenderingUtils
import json
import textwrap
from builtins import open as pyopen
from typing import NotRequired, TypedDict
import numpy as np
import FreeCAD
import Draft
import Mesh
import OfflineRenderingUtils
import Part
if FreeCAD.GuiUp:
import FreeCADGui
@@ -58,15 +67,6 @@ else:
return txt
import numpy as np
## @package importWebGL
# \ingroup ARCH
# \brief FreeCAD WebGL Exporter
#
# This module provides tools to export HTML files containing the
# exported objects in WebGL format and a simple three.js-based viewer.
disableCompression = False # Compress object data before sending to JS
base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!#$%&()*+-:;/=>?@[]^_,.{|}~`" # safe str chars for js in all cases
baseFloat = ",.-0123456789"