mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 22:33:33 +00:00
Merge branch 'IfcOpenShell:v0.8.0' into fix-5563
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
SVG [mustache](https://mustache.github.io/) templates that will be used for sheets and fill be filled with infromation from the sheet's IfcDocumentInformation attributes (e.g. Identification, Name, Revision, etc).
|
||||||
@@ -1734,7 +1734,7 @@ class OpenLayout(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
class SelectAllSheets(bpy.types.Operator):
|
class SelectAllSheets(bpy.types.Operator):
|
||||||
bl_idname = "bim.select_all_sheets"
|
bl_idname = "bim.select_all_sheets"
|
||||||
bl_label = "Select All Sheetss"
|
bl_label = "Select All Sheets"
|
||||||
view: bpy.props.StringProperty()
|
view: bpy.props.StringProperty()
|
||||||
bl_description = "Select all sheets in the sheet list.\n\n" + "SHIFT+CLICK to deselect all sheets"
|
bl_description = "Select all sheets in the sheet list.\n\n" + "SHIFT+CLICK to deselect all sheets"
|
||||||
select_all: bpy.props.BoolProperty(name="Open All", default=True, options={"SKIP_SAVE"})
|
select_all: bpy.props.BoolProperty(name="Open All", default=True, options={"SKIP_SAVE"})
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ class SheetBuilder:
|
|||||||
shutil.copy(ootb_titleblock_path, titleblock_path)
|
shutil.copy(ootb_titleblock_path, titleblock_path)
|
||||||
|
|
||||||
view_root = ET.parse(titleblock_path).getroot()
|
view_root = ET.parse(titleblock_path).getroot()
|
||||||
view_width = self.convert_to_mm(view_root.attrib.get("width"))
|
view_width = self.convert_to_mm(view_root.attrib["width"])
|
||||||
view_height = self.convert_to_mm(view_root.attrib.get("height"))
|
view_height = self.convert_to_mm(view_root.attrib["height"])
|
||||||
view = ET.SubElement(root, "g")
|
view = ET.SubElement(root, "g")
|
||||||
view.attrib["data-type"] = "titleblock"
|
view.attrib["data-type"] = "titleblock"
|
||||||
titleblock = ET.SubElement(view, "image")
|
titleblock = ET.SubElement(view, "image")
|
||||||
@@ -87,6 +87,7 @@ class SheetBuilder:
|
|||||||
) -> None:
|
) -> None:
|
||||||
filename = drawing.Name
|
filename = drawing.Name
|
||||||
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
||||||
|
assert layout_path
|
||||||
layout_dir = os.path.dirname(layout_path)
|
layout_dir = os.path.dirname(layout_path)
|
||||||
|
|
||||||
drawing_path = tool.Drawing.get_document_uri(tool.Drawing.get_drawing_reference(drawing))
|
drawing_path = tool.Drawing.get_document_uri(tool.Drawing.get_drawing_reference(drawing))
|
||||||
@@ -110,8 +111,8 @@ class SheetBuilder:
|
|||||||
view.attrib["data-type"] = "drawing"
|
view.attrib["data-type"] = "drawing"
|
||||||
view.attrib["data-id"] = str(reference.id())
|
view.attrib["data-id"] = str(reference.id())
|
||||||
view.attrib["data-drawing"] = drawing.GlobalId
|
view.attrib["data-drawing"] = drawing.GlobalId
|
||||||
view_width = self.convert_to_mm(view_root.attrib.get("width"))
|
view_width = self.convert_to_mm(view_root.attrib["width"])
|
||||||
view_height = self.convert_to_mm(view_root.attrib.get("height"))
|
view_height = self.convert_to_mm(view_root.attrib["height"])
|
||||||
|
|
||||||
x, y = self.next_drawing_location(layout_root, view_width)
|
x, y = self.next_drawing_location(layout_root, view_width)
|
||||||
|
|
||||||
@@ -134,16 +135,16 @@ class SheetBuilder:
|
|||||||
|
|
||||||
# how wide is the title block frame
|
# how wide is the title block frame
|
||||||
try:
|
try:
|
||||||
titleblock_width = self.convert_to_mm(titleblocks[0][0].attrib.get("width"))
|
titleblock_width = self.convert_to_mm(titleblocks[0][0].attrib["width"])
|
||||||
except (IndexError, AttributeError):
|
except (IndexError, AttributeError):
|
||||||
titleblock_width = 840.0
|
titleblock_width = 840.0
|
||||||
|
|
||||||
# where does the last drawing finish
|
# where does the last drawing finish
|
||||||
try:
|
try:
|
||||||
last = drawings[-1][0]
|
last = drawings[-1][0]
|
||||||
last_width = self.convert_to_mm(last.attrib.get("width"))
|
last_width = self.convert_to_mm(last.attrib["width"])
|
||||||
last_x = self.convert_to_mm(last.attrib.get("x"))
|
last_x = self.convert_to_mm(last.attrib["x"])
|
||||||
last_y = self.convert_to_mm(last.attrib.get("y"))
|
last_y = self.convert_to_mm(last.attrib["y"])
|
||||||
except (IndexError, AttributeError):
|
except (IndexError, AttributeError):
|
||||||
return [DEFAULT_POSITION.x, DEFAULT_POSITION.y]
|
return [DEFAULT_POSITION.x, DEFAULT_POSITION.y]
|
||||||
|
|
||||||
@@ -155,8 +156,8 @@ class SheetBuilder:
|
|||||||
for drawing in drawings:
|
for drawing in drawings:
|
||||||
for image in drawing:
|
for image in drawing:
|
||||||
try:
|
try:
|
||||||
image_y = self.convert_to_mm(image.attrib.get("y"))
|
image_y = self.convert_to_mm(image.attrib["y"])
|
||||||
image_height = self.convert_to_mm(image.attrib.get("height"))
|
image_height = self.convert_to_mm(image.attrib["height"])
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return [DEFAULT_POSITION.x, DEFAULT_POSITION.y]
|
return [DEFAULT_POSITION.x, DEFAULT_POSITION.y]
|
||||||
if image_y + image_height + DRAWING_PADDING > last_y:
|
if image_y + image_height + DRAWING_PADDING > last_y:
|
||||||
@@ -167,6 +168,7 @@ class SheetBuilder:
|
|||||||
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
||||||
|
|
||||||
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
||||||
|
assert layout_path
|
||||||
layout_tree = ET.parse(layout_path)
|
layout_tree = ET.parse(layout_path)
|
||||||
layout_root = layout_tree.getroot()
|
layout_root = layout_tree.getroot()
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
@@ -210,12 +212,13 @@ class SheetBuilder:
|
|||||||
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
||||||
|
|
||||||
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
||||||
|
assert layout_path
|
||||||
if not os.path.exists(layout_path):
|
if not os.path.exists(layout_path):
|
||||||
return
|
return
|
||||||
layout_tree = ET.parse(layout_path)
|
layout_tree = ET.parse(layout_path)
|
||||||
layout_root = layout_tree.getroot()
|
layout_root = layout_tree.getroot()
|
||||||
|
|
||||||
for g in layout_root.findall("{http://www.w3.org/2000/svg}g"):
|
for g in layout_root.findall(f"{SVG}g"):
|
||||||
if g.attrib.get("data-id") == str(reference.id()):
|
if g.attrib.get("data-id") == str(reference.id()):
|
||||||
layout_root.remove(g)
|
layout_root.remove(g)
|
||||||
break
|
break
|
||||||
@@ -233,6 +236,7 @@ class SheetBuilder:
|
|||||||
tool.Drawing.create_svg_document(document)
|
tool.Drawing.create_svg_document(document)
|
||||||
document_name = os.path.splitext(os.path.basename(view_path))[0]
|
document_name = os.path.splitext(os.path.basename(view_path))[0]
|
||||||
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
||||||
|
assert layout_path
|
||||||
layout_dir = os.path.dirname(layout_path)
|
layout_dir = os.path.dirname(layout_path)
|
||||||
|
|
||||||
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
ET.register_namespace("", "http://www.w3.org/2000/svg")
|
||||||
@@ -278,13 +282,14 @@ class SheetBuilder:
|
|||||||
title.attrib["xlink:href"] = os.path.relpath(title_path, layout_dir)
|
title.attrib["xlink:href"] = os.path.relpath(title_path, layout_dir)
|
||||||
title.attrib["x"] = str(x)
|
title.attrib["x"] = str(x)
|
||||||
title.attrib["y"] = str(y)
|
title.attrib["y"] = str(y)
|
||||||
title.attrib["width"] = str(self.convert_to_mm(title_root.attrib.get("width")))
|
title.attrib["width"] = str(self.convert_to_mm(title_root.attrib["width"]))
|
||||||
title.attrib["height"] = str(self.convert_to_mm(title_root.attrib.get("height")))
|
title.attrib["height"] = str(self.convert_to_mm(title_root.attrib["height"]))
|
||||||
|
|
||||||
def build(self, sheet: ifcopenshell.entity_instance) -> dict:
|
def build(self, sheet: ifcopenshell.entity_instance) -> dict:
|
||||||
self.references = {"SHEET": None, "RASTER": []}
|
self.references = {"SHEET": None, "RASTER": []}
|
||||||
|
|
||||||
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
layout_path = tool.Drawing.get_document_uri(sheet, "LAYOUT")
|
||||||
|
assert layout_path
|
||||||
self.layout_dir = os.path.dirname(layout_path)
|
self.layout_dir = os.path.dirname(layout_path)
|
||||||
|
|
||||||
sheet_path = tool.Ifc.resolve_uri(tool.Drawing.get_default_sheet_path(sheet[0], sheet.Name))
|
sheet_path = tool.Ifc.resolve_uri(tool.Drawing.get_default_sheet_path(sheet[0], sheet.Name))
|
||||||
@@ -313,14 +318,14 @@ class SheetBuilder:
|
|||||||
return self.references
|
return self.references
|
||||||
|
|
||||||
def build_titleblock(self, root: ET.Element, sheet: ifcopenshell.entity_instance) -> None:
|
def build_titleblock(self, root: ET.Element, sheet: ifcopenshell.entity_instance) -> None:
|
||||||
titleblock = root.findall('{http://www.w3.org/2000/svg}g[@data-type="titleblock"]')[0]
|
titleblock = root.findall(f'{SVG}g[@data-type="titleblock"]')[0]
|
||||||
image = titleblock.findall("{http://www.w3.org/2000/svg}image")[0]
|
image = titleblock.findall(f"{SVG}image")[0]
|
||||||
g = self.parse_embedded_svg(image, sheet.get_info())
|
g = self.parse_embedded_svg(image, sheet.get_info())
|
||||||
grid_north = ifcopenshell.util.geolocation.get_grid_north(tool.Ifc.get()) * -1
|
grid_north = ifcopenshell.util.geolocation.get_grid_north(tool.Ifc.get()) * -1
|
||||||
true_north = ifcopenshell.util.geolocation.get_true_north(tool.Ifc.get()) * -1
|
true_north = ifcopenshell.util.geolocation.get_true_north(tool.Ifc.get()) * -1
|
||||||
for north in g.iterfind('.//{http://www.w3.org/2000/svg}g[@data-type="grid-north"]'):
|
for north in g.iterfind(f'.//{SVG}g[@data-type="grid-north"]'):
|
||||||
north.attrib["transform"] = f"rotate({grid_north})"
|
north.attrib["transform"] = f"rotate({grid_north})"
|
||||||
for north in g.iterfind('.//{http://www.w3.org/2000/svg}g[@data-type="true-north"]'):
|
for north in g.iterfind(f'.//{SVG}g[@data-type="true-north"]'):
|
||||||
north.attrib["transform"] = f"rotate({true_north})"
|
north.attrib["transform"] = f"rotate({true_north})"
|
||||||
titleblock.append(g)
|
titleblock.append(g)
|
||||||
titleblock.remove(image)
|
titleblock.remove(image)
|
||||||
@@ -333,7 +338,9 @@ class SheetBuilder:
|
|||||||
|
|
||||||
# add .prefix class to all css selectors
|
# add .prefix class to all css selectors
|
||||||
style = svg.find(f"{SVG}defs/{SVG}style")
|
style = svg.find(f"{SVG}defs/{SVG}style")
|
||||||
|
assert style
|
||||||
style_data = style.text
|
style_data = style.text
|
||||||
|
assert style_data is not None
|
||||||
text = ""
|
text = ""
|
||||||
brackets_level = 0
|
brackets_level = 0
|
||||||
for l in style_data:
|
for l in style_data:
|
||||||
@@ -374,6 +381,8 @@ class SheetBuilder:
|
|||||||
if "filter" in attrib:
|
if "filter" in attrib:
|
||||||
# example use "#fill-background" filter
|
# example use "#fill-background" filter
|
||||||
attrib["filter"] = replace_urls(attrib["filter"])
|
attrib["filter"] = replace_urls(attrib["filter"])
|
||||||
|
if "style" in attrib:
|
||||||
|
attrib["style"] = replace_urls(attrib["style"])
|
||||||
if svg_element.tag == f"{SVG}use":
|
if svg_element.tag == f"{SVG}use":
|
||||||
href_attrib = f"{XLINK}href"
|
href_attrib = f"{XLINK}href"
|
||||||
if href_attrib in attrib:
|
if href_attrib in attrib:
|
||||||
@@ -384,16 +393,16 @@ class SheetBuilder:
|
|||||||
return svg
|
return svg
|
||||||
|
|
||||||
def build_drawings(self, root: ET.Element, sheet: ifcopenshell.entity_instance):
|
def build_drawings(self, root: ET.Element, sheet: ifcopenshell.entity_instance):
|
||||||
for view in root.findall('{http://www.w3.org/2000/svg}g[@data-type="drawing"]'):
|
for view in root.findall(f'{SVG}g[@data-type="drawing"]'):
|
||||||
drawing_id = int(view.attrib["data-id"])
|
drawing_id = int(view.attrib["data-id"])
|
||||||
try:
|
try:
|
||||||
reference = tool.Ifc.get().by_id(int(view.attrib["data-id"]))
|
reference = tool.Ifc.get().by_id(int(view.attrib["data-id"]))
|
||||||
drawing = tool.Ifc.get().by_id(view.attrib["data-drawing"])
|
drawing = tool.Ifc.get().by_guid(view.attrib["data-drawing"])
|
||||||
except:
|
except RuntimeError:
|
||||||
# Perhaps the SVG has outdated content or is edited externally which we cannot control.
|
# Perhaps the SVG has outdated content or is edited externally which we cannot control.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
images = view.findall("{http://www.w3.org/2000/svg}image")
|
images = view.findall(f"{SVG}image")
|
||||||
|
|
||||||
foreground = None
|
foreground = None
|
||||||
view_title = None
|
view_title = None
|
||||||
@@ -410,6 +419,7 @@ class SheetBuilder:
|
|||||||
view.append(svg)
|
view.append(svg)
|
||||||
|
|
||||||
if view_title is not None:
|
if view_title is not None:
|
||||||
|
assert foreground
|
||||||
foreground_path = self.get_href(foreground)
|
foreground_path = self.get_href(foreground)
|
||||||
data = reference.get_info()
|
data = reference.get_info()
|
||||||
data.update({"Sheet" + k: v for k, v in sheet.get_info().items()})
|
data.update({"Sheet" + k: v for k, v in sheet.get_info().items()})
|
||||||
@@ -434,8 +444,8 @@ class SheetBuilder:
|
|||||||
view.remove(image)
|
view.remove(image)
|
||||||
|
|
||||||
def build_documents(self, root: ET.Element, sheet: ifcopenshell.entity_instance) -> None:
|
def build_documents(self, root: ET.Element, sheet: ifcopenshell.entity_instance) -> None:
|
||||||
schedules = root.findall('{http://www.w3.org/2000/svg}g[@data-type="schedule"]')
|
schedules = root.findall(f'{SVG}g[@data-type="schedule"]')
|
||||||
references = root.findall('{http://www.w3.org/2000/svg}g[@data-type="reference"]')
|
references = root.findall(f'{SVG}g[@data-type="reference"]')
|
||||||
documents = schedules + references
|
documents = schedules + references
|
||||||
for view in documents:
|
for view in documents:
|
||||||
try:
|
try:
|
||||||
@@ -445,7 +455,7 @@ class SheetBuilder:
|
|||||||
# Perhaps the SVG has outdated content or is edited externally which we cannot control.
|
# Perhaps the SVG has outdated content or is edited externally which we cannot control.
|
||||||
continue
|
continue
|
||||||
|
|
||||||
images = view.findall("{http://www.w3.org/2000/svg}image")
|
images = view.findall(f"{SVG}image")
|
||||||
|
|
||||||
table = None
|
table = None
|
||||||
view_title = None
|
view_title = None
|
||||||
@@ -471,13 +481,12 @@ class SheetBuilder:
|
|||||||
view.remove(image)
|
view.remove(image)
|
||||||
|
|
||||||
def get_href(self, element: ET.Element) -> str:
|
def get_href(self, element: ET.Element) -> str:
|
||||||
return urllib.parse.unquote(element.attrib.get("{http://www.w3.org/1999/xlink}href")).replace("\\", "/")
|
return urllib.parse.unquote(element.attrib[f"{XLINK}href"]).replace("\\", "/")
|
||||||
|
|
||||||
def parse_embedded_svg(self, image: ET.Element, data: dict) -> ET.Element:
|
def parse_embedded_svg(self, image: ET.Element, data: dict) -> ET.Element:
|
||||||
group = ET.Element("g")
|
group = ET.Element("g")
|
||||||
group.attrib["transform"] = "translate({},{})".format(
|
x, y = self.convert_to_mm(image.attrib["x"]), self.convert_to_mm(image.attrib["y"])
|
||||||
self.convert_to_mm(image.attrib.get("x")), self.convert_to_mm(image.attrib.get("y"))
|
group.attrib["transform"] = f"translate({x},{y})"
|
||||||
)
|
|
||||||
|
|
||||||
# Convert viewBox into a clip path
|
# Convert viewBox into a clip path
|
||||||
clip_id = str(uuid.uuid4())
|
clip_id = str(uuid.uuid4())
|
||||||
@@ -487,8 +496,8 @@ class SheetBuilder:
|
|||||||
rect = ET.Element("rect")
|
rect = ET.Element("rect")
|
||||||
rect.attrib["x"] = "0"
|
rect.attrib["x"] = "0"
|
||||||
rect.attrib["y"] = "0"
|
rect.attrib["y"] = "0"
|
||||||
rect.attrib["width"] = str(self.convert_to_mm(image.attrib.get("width")))
|
rect.attrib["width"] = str(self.convert_to_mm(image.attrib["width"]))
|
||||||
rect.attrib["height"] = str(self.convert_to_mm(image.attrib.get("height")))
|
rect.attrib["height"] = str(self.convert_to_mm(image.attrib["height"]))
|
||||||
clip_path.append(rect)
|
clip_path.append(rect)
|
||||||
self.defs.append(clip_path)
|
self.defs.append(clip_path)
|
||||||
|
|
||||||
@@ -499,16 +508,16 @@ class SheetBuilder:
|
|||||||
embedded.attrib["viewBox"] = ""
|
embedded.attrib["viewBox"] = ""
|
||||||
# TODO: This should not be in this function
|
# TODO: This should not be in this function
|
||||||
self.scale = embedded.attrib.get("data-scale")
|
self.scale = embedded.attrib.get("data-scale")
|
||||||
images = embedded.findall("{http://www.w3.org/2000/svg}image")
|
images = embedded.findall(f"{SVG}image")
|
||||||
for image in images:
|
for image in images:
|
||||||
old_href = Path(image.attrib.get("{http://www.w3.org/1999/xlink}href"))
|
old_href = Path(image.attrib[f"{XLINK}href"])
|
||||||
if not os.path.isabs(old_href):
|
if not os.path.isabs(old_href):
|
||||||
template_dir = Path(os.path.join(self.layout_dir, svg_path)).resolve().parent
|
template_dir = Path(os.path.join(self.layout_dir, svg_path)).resolve().parent
|
||||||
old_href = Path(os.path.join(template_dir, old_href))
|
old_href = Path(os.path.join(template_dir, old_href))
|
||||||
old_href = old_href.absolute().resolve().as_posix()
|
old_href = old_href.absolute().resolve().as_posix()
|
||||||
new_href = Path(os.path.join(self.sheets_dir, Path(old_href).name)).absolute().resolve().as_posix()
|
new_href = Path(os.path.join(self.sheets_dir, Path(old_href).name)).absolute().resolve().as_posix()
|
||||||
shutil.copy(old_href, new_href)
|
shutil.copy(old_href, new_href)
|
||||||
image.attrib["{http://www.w3.org/1999/xlink}href"] = Path(old_href).name
|
image.attrib[f"{XLINK}href"] = Path(old_href).name
|
||||||
for child in embedded:
|
for child in embedded:
|
||||||
if "namedview" in child.tag:
|
if "namedview" in child.tag:
|
||||||
continue
|
continue
|
||||||
@@ -539,9 +548,9 @@ class SheetBuilder:
|
|||||||
sheet_tree = ET.parse(sheet_path)
|
sheet_tree = ET.parse(sheet_path)
|
||||||
root = sheet_tree.getroot()
|
root = sheet_tree.getroot()
|
||||||
|
|
||||||
titleblock = sheet_tree.findall('{http://www.w3.org/2000/svg}g[@data-type="titleblock"]')[0]
|
titleblock = sheet_tree.findall(f'{SVG}g[@data-type="titleblock"]')[0]
|
||||||
image = titleblock.findall("{http://www.w3.org/2000/svg}image[@{http://www.w3.org/1999/xlink}href]")[0]
|
image = titleblock.findall(f"{SVG}image[@{XLINK}href]")[0]
|
||||||
image.attrib["{http://www.w3.org/1999/xlink}href"] = os.path.relpath(titleblock_path, sheet_dir)
|
image.attrib[f"{XLINK}href"] = os.path.relpath(titleblock_path, sheet_dir)
|
||||||
image.attrib["width"] = str(view_width)
|
image.attrib["width"] = str(view_width)
|
||||||
image.attrib["height"] = str(view_height)
|
image.attrib["height"] = str(view_height)
|
||||||
|
|
||||||
|
|||||||
@@ -1132,21 +1132,24 @@ class DumbWallJoiner:
|
|||||||
relating_element = None
|
relating_element = None
|
||||||
connections = element1.ConnectedTo
|
connections = element1.ConnectedTo
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
if conn.RelatingConnectionType == "ATEND":
|
if conn.is_a("IfcRelConnectsPathElements") and conn.RelatingConnectionType == "ATEND":
|
||||||
relating_element = conn.RelatedElement
|
relating_element = conn.RelatedElement
|
||||||
|
relating_connection = conn.RelatedConnectionType
|
||||||
description = conn.Description
|
description = conn.Description
|
||||||
|
bonsai.core.geometry.remove_connection(tool.Geometry, connection=conn)
|
||||||
connections = element1.ConnectedFrom
|
connections = element1.ConnectedFrom
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
if conn.RelatedConnectionType == "ATEND":
|
if conn.is_a("IfcRelConnectsPathElements") and conn.RelatedConnectionType == "ATEND":
|
||||||
relating_element = conn.RelatingElement
|
relating_element = conn.RelatingElement
|
||||||
|
relating_connection = conn.RelatingConnectionType
|
||||||
description = conn.Description
|
description = conn.Description
|
||||||
|
bonsai.core.geometry.remove_connection(tool.Geometry, connection=conn)
|
||||||
if relating_element:
|
if relating_element:
|
||||||
ifcopenshell.api.geometry.connect_path(
|
ifcopenshell.api.geometry.connect_path(
|
||||||
tool.Ifc.get(),
|
tool.Ifc.get(),
|
||||||
relating_element=relating_element,
|
relating_element=relating_element,
|
||||||
related_element=element2,
|
related_element=element2,
|
||||||
relating_connection="ATSTART",
|
relating_connection=relating_connection,
|
||||||
related_connection="ATEND",
|
related_connection="ATEND",
|
||||||
description=description,
|
description=description,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class BIMProfileProperties(PropertyGroup):
|
|||||||
name="Filter Material Profiles",
|
name="Filter Material Profiles",
|
||||||
default=False,
|
default=False,
|
||||||
description="Check to only show IfcProfileDefs attached to IfcMaterialProfiles",
|
description="Check to only show IfcProfileDefs attached to IfcMaterialProfiles",
|
||||||
update=lambda self, context: bpy.ops.bim.load_profiles(),
|
update=lambda self, context: (None, bpy.ops.bim.load_profiles())[0],
|
||||||
)
|
)
|
||||||
object_to_profile: PointerProperty(
|
object_to_profile: PointerProperty(
|
||||||
name="Object to profile",
|
name="Object to profile",
|
||||||
|
|||||||
@@ -63,24 +63,34 @@ from bonsai.bim.module.project.decorator import ProjectDecorator, ClippingPlaneD
|
|||||||
from bonsai.bim.module.project.prop import BreadcrumbType
|
from bonsai.bim.module.project.prop import BreadcrumbType
|
||||||
from bonsai.bim.module.model.decorator import PolylineDecorator, FaceAreaDecorator
|
from bonsai.bim.module.model.decorator import PolylineDecorator, FaceAreaDecorator
|
||||||
from bonsai.bim.module.model.polyline import PolylineOperator
|
from bonsai.bim.module.model.polyline import PolylineOperator
|
||||||
from typing import Union, TYPE_CHECKING, get_args
|
from typing import Union, TYPE_CHECKING, get_args, Literal
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
import bpy.stub_internal.rna_enums as rna_enums
|
||||||
from bonsai.bim.module.project.prop import Link
|
from bonsai.bim.module.project.prop import Link
|
||||||
|
|
||||||
|
|
||||||
|
PresetType = Literal["metric_m", "metric_mm", "imperial_ft", "demo", "wizard"]
|
||||||
|
|
||||||
|
|
||||||
class NewProject(bpy.types.Operator):
|
class NewProject(bpy.types.Operator):
|
||||||
bl_idname = "bim.new_project"
|
bl_idname = "bim.new_project"
|
||||||
bl_label = "New Project"
|
bl_label = "New Project"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_description = "Start a new IFC project in a fresh session"
|
bl_description = "Start a new IFC project in a fresh session"
|
||||||
preset: bpy.props.StringProperty()
|
preset: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||||
|
items=[(i, i, "") for i in get_args(PresetType)]
|
||||||
|
)
|
||||||
|
|
||||||
def execute(self, context):
|
if TYPE_CHECKING:
|
||||||
|
preset: PresetType
|
||||||
|
|
||||||
|
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
||||||
bpy.ops.wm.read_homefile()
|
bpy.ops.wm.read_homefile()
|
||||||
pprops = tool.Project.get_project_props()
|
pprops = tool.Project.get_project_props()
|
||||||
bim_props = tool.Blender.get_bim_props()
|
bim_props = tool.Blender.get_bim_props()
|
||||||
|
|
||||||
|
assert bpy.context.scene
|
||||||
if self.preset == "metric_m":
|
if self.preset == "metric_m":
|
||||||
pprops.export_schema = "IFC4"
|
pprops.export_schema = "IFC4"
|
||||||
bpy.context.scene.unit_settings.system = "METRIC"
|
bpy.context.scene.unit_settings.system = "METRIC"
|
||||||
|
|||||||
@@ -21,15 +21,21 @@ import ifcopenshell.api
|
|||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
import bonsai.core.unit as core
|
import bonsai.core.unit as core
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from bpy.stub_internal import rna_enums
|
||||||
|
|
||||||
|
|
||||||
class AssignSceneUnits(bpy.types.Operator, tool.Ifc.Operator):
|
class AssignSceneUnits(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.assign_scene_units"
|
bl_idname = "bim.assign_scene_units"
|
||||||
bl_label = "Assign Scene Units"
|
bl_label = "Assign Scene Units"
|
||||||
|
bl_description = "Add new units based on the current Blender scene units and assign them as project default."
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
core.assign_scene_units(tool.Ifc, tool.Unit)
|
core.assign_scene_units(tool.Ifc, tool.Unit)
|
||||||
|
core.load_units(tool.Unit)
|
||||||
|
|
||||||
|
|
||||||
class AssignUnit(bpy.types.Operator, tool.Ifc.Operator):
|
class AssignUnit(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -54,24 +60,26 @@ class UnassignUnit(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
core.unassign_unit(tool.Ifc, tool.Unit, unit=tool.Ifc.get().by_id(self.unit))
|
core.unassign_unit(tool.Ifc, tool.Unit, unit=tool.Ifc.get().by_id(self.unit))
|
||||||
|
|
||||||
|
|
||||||
class LoadUnits(bpy.types.Operator, tool.Ifc.Operator):
|
class LoadUnits(bpy.types.Operator):
|
||||||
bl_idname = "bim.load_units"
|
bl_idname = "bim.load_units"
|
||||||
bl_label = "Load Units"
|
bl_label = "Load Units"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_description = "Open the loaded units"
|
bl_description = "Open the loaded units"
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
||||||
core.load_units(tool.Unit)
|
core.load_units(tool.Unit)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class DisableUnitEditingUI(bpy.types.Operator, tool.Ifc.Operator):
|
class DisableUnitEditingUI(bpy.types.Operator):
|
||||||
bl_idname = "bim.disable_unit_editing_ui"
|
bl_idname = "bim.disable_unit_editing_ui"
|
||||||
bl_label = "Disable Unit Editing UI"
|
bl_label = "Disable Unit Editing UI"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_description = "Close the editing units mode"
|
bl_description = "Close the editing units mode"
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
||||||
core.disable_unit_editing_ui(tool.Unit)
|
core.disable_unit_editing_ui(tool.Unit)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class RemoveUnit(bpy.types.Operator, tool.Ifc.Operator):
|
class RemoveUnit(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -124,23 +132,25 @@ class AddContextDependentUnit(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
core.add_context_dependent_unit(tool.Ifc, tool.Unit, unit_type=self.unit_type, name=self.name)
|
core.add_context_dependent_unit(tool.Ifc, tool.Unit, unit_type=self.unit_type, name=self.name)
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingUnit(bpy.types.Operator, tool.Ifc.Operator):
|
class EnableEditingUnit(bpy.types.Operator):
|
||||||
bl_idname = "bim.enable_editing_unit"
|
bl_idname = "bim.enable_editing_unit"
|
||||||
bl_label = "Enable Editing Unit"
|
bl_label = "Enable Editing Unit"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
unit: bpy.props.IntProperty()
|
unit: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
||||||
core.enable_editing_unit(tool.Unit, unit=tool.Ifc.get().by_id(self.unit))
|
core.enable_editing_unit(tool.Unit, unit=tool.Ifc.get().by_id(self.unit))
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingUnit(bpy.types.Operator, tool.Ifc.Operator):
|
class DisableEditingUnit(bpy.types.Operator):
|
||||||
bl_idname = "bim.disable_editing_unit"
|
bl_idname = "bim.disable_editing_unit"
|
||||||
bl_label = "Disable Editing Unit"
|
bl_label = "Disable Editing Unit"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
||||||
core.disable_editing_unit(tool.Unit)
|
core.disable_editing_unit(tool.Unit)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class EditUnit(bpy.types.Operator, tool.Ifc.Operator):
|
class EditUnit(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
|
|||||||
@@ -48,10 +48,12 @@ class BIM_PT_units(Panel):
|
|||||||
UnitsData.load()
|
UnitsData.load()
|
||||||
|
|
||||||
self.props = tool.Unit.get_unit_props()
|
self.props = tool.Unit.get_unit_props()
|
||||||
|
assert self.layout
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.label(text="{} Units Found".format(UnitsData.data["total_units"]), icon="SNAP_GRID")
|
row.label(text="{} Units Found".format(UnitsData.data["total_units"]), icon="SNAP_GRID")
|
||||||
if self.props.is_editing:
|
if self.props.is_editing:
|
||||||
|
row.operator("bim.assign_scene_units", text="", icon="TOOL_SETTINGS")
|
||||||
row.operator("bim.disable_unit_editing_ui", text="", icon="CANCEL")
|
row.operator("bim.disable_unit_editing_ui", text="", icon="CANCEL")
|
||||||
else:
|
else:
|
||||||
row.operator("bim.load_units", text="", icon="GREASEPENCIL")
|
row.operator("bim.load_units", text="", icon="GREASEPENCIL")
|
||||||
|
|||||||
@@ -26,7 +26,12 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
def copy_attribute_to_selection(
|
def copy_attribute_to_selection(
|
||||||
ifc: tool.Ifc, blender: tool.Blender, root: tool.Root, spatial: tool.Spatial, name: str, value: Union[str, None]
|
ifc: type[tool.Ifc],
|
||||||
|
blender: type[tool.Blender],
|
||||||
|
root: type[tool.Root],
|
||||||
|
spatial: type[tool.Spatial],
|
||||||
|
name: str,
|
||||||
|
value: Union[str, None],
|
||||||
) -> int:
|
) -> int:
|
||||||
total_changed = 0
|
total_changed = 0
|
||||||
has_edited_spatial_name = False
|
has_edited_spatial_name = False
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def load_brick_project(brick: tool.Brick, filepath: str, brick_root: str) -> None:
|
def load_brick_project(brick: type[tool.Brick], filepath: str, brick_root: str) -> None:
|
||||||
brick.load_brick_file(filepath)
|
brick.load_brick_file(filepath)
|
||||||
brick.import_brick_classes(brick_root)
|
brick.import_brick_classes(brick_root)
|
||||||
brick.import_brick_classes(brick_root, split_screen=True)
|
brick.import_brick_classes(brick_root, split_screen=True)
|
||||||
@@ -33,7 +33,7 @@ def load_brick_project(brick: tool.Brick, filepath: str, brick_root: str) -> Non
|
|||||||
brick.set_active_brick_class(brick_root, split_screen=True)
|
brick.set_active_brick_class(brick_root, split_screen=True)
|
||||||
|
|
||||||
|
|
||||||
def new_brick_file(brick: tool.Brick, brick_root: str) -> None:
|
def new_brick_file(brick: type[tool.Brick], brick_root: str) -> None:
|
||||||
brick.new_brick_file()
|
brick.new_brick_file()
|
||||||
brick.import_brick_classes(brick_root)
|
brick.import_brick_classes(brick_root)
|
||||||
brick.import_brick_classes(brick_root, split_screen=True)
|
brick.import_brick_classes(brick_root, split_screen=True)
|
||||||
@@ -41,7 +41,7 @@ def new_brick_file(brick: tool.Brick, brick_root: str) -> None:
|
|||||||
brick.set_active_brick_class(brick_root, split_screen=True)
|
brick.set_active_brick_class(brick_root, split_screen=True)
|
||||||
|
|
||||||
|
|
||||||
def view_brick_class(brick: tool.Brick, brick_class: str, split_screen: bool = False) -> None:
|
def view_brick_class(brick: type[tool.Brick], brick_class: str, split_screen: bool = False) -> None:
|
||||||
brick.add_brick_breadcrumb(split_screen=split_screen)
|
brick.add_brick_breadcrumb(split_screen=split_screen)
|
||||||
brick.clear_brick_browser(split_screen=split_screen)
|
brick.clear_brick_browser(split_screen=split_screen)
|
||||||
brick.import_brick_classes(brick_class, split_screen=split_screen)
|
brick.import_brick_classes(brick_class, split_screen=split_screen)
|
||||||
@@ -49,13 +49,13 @@ def view_brick_class(brick: tool.Brick, brick_class: str, split_screen: bool = F
|
|||||||
brick.set_active_brick_class(brick_class, split_screen=split_screen)
|
brick.set_active_brick_class(brick_class, split_screen=split_screen)
|
||||||
|
|
||||||
|
|
||||||
def view_brick_item(brick: tool.Brick, item: str, split_screen: bool = False) -> None:
|
def view_brick_item(brick: type[tool.Brick], item: str, split_screen: bool = False) -> None:
|
||||||
brick_class = brick.get_item_class(item)
|
brick_class = brick.get_item_class(item)
|
||||||
brick.run_view_brick_class(brick_class=brick_class, split_screen=split_screen)
|
brick.run_view_brick_class(brick_class=brick_class, split_screen=split_screen)
|
||||||
brick.select_browser_item(item, split_screen=split_screen)
|
brick.select_browser_item(item, split_screen=split_screen)
|
||||||
|
|
||||||
|
|
||||||
def rewind_brick_class(brick: tool.Brick, split_screen: bool = False) -> None:
|
def rewind_brick_class(brick: type[tool.Brick], split_screen: bool = False) -> None:
|
||||||
previous_class = brick.pop_brick_breadcrumb(split_screen=split_screen)
|
previous_class = brick.pop_brick_breadcrumb(split_screen=split_screen)
|
||||||
brick.clear_brick_browser(split_screen=split_screen)
|
brick.clear_brick_browser(split_screen=split_screen)
|
||||||
brick.import_brick_classes(previous_class, split_screen=split_screen)
|
brick.import_brick_classes(previous_class, split_screen=split_screen)
|
||||||
@@ -63,7 +63,7 @@ def rewind_brick_class(brick: tool.Brick, split_screen: bool = False) -> None:
|
|||||||
brick.set_active_brick_class(previous_class, split_screen=split_screen)
|
brick.set_active_brick_class(previous_class, split_screen=split_screen)
|
||||||
|
|
||||||
|
|
||||||
def close_brick_project(brick: tool.Brick) -> None:
|
def close_brick_project(brick: type[tool.Brick]) -> None:
|
||||||
brick.clear_project()
|
brick.clear_project()
|
||||||
brick.clear_brick_browser()
|
brick.clear_brick_browser()
|
||||||
brick.clear_brick_browser(split_screen=True)
|
brick.clear_brick_browser(split_screen=True)
|
||||||
@@ -71,15 +71,15 @@ def close_brick_project(brick: tool.Brick) -> None:
|
|||||||
brick.clear_breadcrumbs(split_screen=True)
|
brick.clear_breadcrumbs(split_screen=True)
|
||||||
|
|
||||||
|
|
||||||
def convert_brick_project(ifc: tool.Ifc, brick: tool.Brick) -> None:
|
def convert_brick_project(ifc: type[tool.Ifc], brick: type[tool.Brick]) -> None:
|
||||||
library = ifc.run("library.add_library", name=brick.get_brick_path_name())
|
library = ifc.run("library.add_library", name=brick.get_brick_path_name())
|
||||||
if ifc.get_schema() != "IFC2X3":
|
if ifc.get_schema() != "IFC2X3":
|
||||||
ifc.run("library.edit_library", library=library, attributes={"Location": brick.get_brick_path()})
|
ifc.run("library.edit_library", library=library, attributes={"Location": brick.get_brick_path()})
|
||||||
|
|
||||||
|
|
||||||
def assign_brick_reference(
|
def assign_brick_reference(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
brick: tool.Brick,
|
brick: type[tool.Brick],
|
||||||
element: ifcopenshell.entity_instance,
|
element: ifcopenshell.entity_instance,
|
||||||
library: ifcopenshell.entity_instance,
|
library: ifcopenshell.entity_instance,
|
||||||
brick_uri: str,
|
brick_uri: str,
|
||||||
@@ -96,8 +96,8 @@ def assign_brick_reference(
|
|||||||
|
|
||||||
|
|
||||||
def add_brick(
|
def add_brick(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
brick: tool.Brick,
|
brick: type[tool.Brick],
|
||||||
element: Union[ifcopenshell.entity_instance, None],
|
element: Union[ifcopenshell.entity_instance, None],
|
||||||
namespace: str,
|
namespace: str,
|
||||||
brick_class: str,
|
brick_class: str,
|
||||||
@@ -113,12 +113,14 @@ def add_brick(
|
|||||||
brick.run_refresh_brick_viewer()
|
brick.run_refresh_brick_viewer()
|
||||||
|
|
||||||
|
|
||||||
def add_brick_relation(brick: tool.Brick, brick_uri: str, predicate: str, object: str) -> None:
|
def add_brick_relation(brick: type[tool.Brick], brick_uri: str, predicate: str, object: str) -> None:
|
||||||
brick.add_relation(brick_uri, predicate, object)
|
brick.add_relation(brick_uri, predicate, object)
|
||||||
brick.run_refresh_brick_viewer()
|
brick.run_refresh_brick_viewer()
|
||||||
|
|
||||||
|
|
||||||
def convert_ifc_to_brick(brick: tool.Brick, namespace: str, library: Union[ifcopenshell.entity_instance, None]) -> None:
|
def convert_ifc_to_brick(
|
||||||
|
brick: type[tool.Brick], namespace: str, library: Union[ifcopenshell.entity_instance, None]
|
||||||
|
) -> None:
|
||||||
# convert spaces to brick
|
# convert spaces to brick
|
||||||
spaces = brick.get_convertable_brick_spaces()
|
spaces = brick.get_convertable_brick_spaces()
|
||||||
space_uris = {}
|
space_uris = {}
|
||||||
@@ -163,14 +165,16 @@ def convert_ifc_to_brick(brick: tool.Brick, namespace: str, library: Union[ifcop
|
|||||||
brick.run_refresh_brick_viewer()
|
brick.run_refresh_brick_viewer()
|
||||||
|
|
||||||
|
|
||||||
def refresh_brick_viewer(brick: tool.Brick) -> None:
|
def refresh_brick_viewer(brick: type[tool.Brick]) -> None:
|
||||||
brick.run_view_brick_class(brick_class=brick.get_active_brick_class())
|
brick.run_view_brick_class(brick_class=brick.get_active_brick_class())
|
||||||
brick.pop_brick_breadcrumb()
|
brick.pop_brick_breadcrumb()
|
||||||
brick.run_view_brick_class(brick_class=brick.get_active_brick_class(split_screen=True), split_screen=True)
|
brick.run_view_brick_class(brick_class=brick.get_active_brick_class(split_screen=True), split_screen=True)
|
||||||
brick.pop_brick_breadcrumb(split_screen=True)
|
brick.pop_brick_breadcrumb(split_screen=True)
|
||||||
|
|
||||||
|
|
||||||
def remove_brick(ifc: tool.Ifc, brick: tool.Brick, library: ifcopenshell.entity_instance, brick_uri: str) -> None:
|
def remove_brick(
|
||||||
|
ifc: type[tool.Ifc], brick: type[tool.Brick], library: ifcopenshell.entity_instance, brick_uri: str
|
||||||
|
) -> None:
|
||||||
if library:
|
if library:
|
||||||
reference = brick.get_library_brick_reference(library, brick_uri)
|
reference = brick.get_library_brick_reference(library, brick_uri)
|
||||||
if reference:
|
if reference:
|
||||||
@@ -179,18 +183,18 @@ def remove_brick(ifc: tool.Ifc, brick: tool.Brick, library: ifcopenshell.entity_
|
|||||||
brick.run_refresh_brick_viewer()
|
brick.run_refresh_brick_viewer()
|
||||||
|
|
||||||
|
|
||||||
def serialize_brick(brick: tool.Brick) -> None:
|
def serialize_brick(brick: type[tool.Brick]) -> None:
|
||||||
brick.serialize_brick()
|
brick.serialize_brick()
|
||||||
|
|
||||||
|
|
||||||
def add_brick_namespace(brick: tool.Brick, alias: str, uri: str) -> None:
|
def add_brick_namespace(brick: type[tool.Brick], alias: str, uri: str) -> None:
|
||||||
brick.add_namespace(alias, uri)
|
brick.add_namespace(alias, uri)
|
||||||
|
|
||||||
|
|
||||||
def set_brick_list_root(brick: tool.Brick, brick_root: str, split_screen: bool = False) -> None:
|
def set_brick_list_root(brick: type[tool.Brick], brick_root: str, split_screen: bool = False) -> None:
|
||||||
brick.run_view_brick_class(brick_class=brick_root, split_screen=split_screen)
|
brick.run_view_brick_class(brick_class=brick_root, split_screen=split_screen)
|
||||||
brick.clear_breadcrumbs(split_screen=split_screen)
|
brick.clear_breadcrumbs(split_screen=split_screen)
|
||||||
|
|
||||||
|
|
||||||
def remove_brick_relation(brick: tool.Brick, brick_uri: str, predicate: str, object: str) -> None:
|
def remove_brick_relation(brick: type[tool.Brick], brick_uri: str, predicate: str, object: str) -> None:
|
||||||
brick.remove_relation(brick_uri, predicate, object)
|
brick.remove_relation(brick_uri, predicate, object)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
def add_context(
|
def add_context(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
context_type: Optional[str] = None,
|
context_type: Optional[str] = None,
|
||||||
context_identifier: Optional[str] = None,
|
context_identifier: Optional[str] = None,
|
||||||
target_view: Optional[str] = None,
|
target_view: Optional[str] = None,
|
||||||
@@ -41,19 +41,19 @@ def add_context(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def remove_context(ifc: tool.Ifc, context: ifcopenshell.entity_instance) -> None:
|
def remove_context(ifc: type[tool.Ifc], context: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("context.remove_context", context=context)
|
ifc.run("context.remove_context", context=context)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_context(context_tool: tool.Context, context: ifcopenshell.entity_instance) -> None:
|
def enable_editing_context(context_tool: type[tool.Context], context: ifcopenshell.entity_instance) -> None:
|
||||||
context_tool.set_context(context)
|
context_tool.set_context(context)
|
||||||
context_tool.import_attributes()
|
context_tool.import_attributes()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_context(context: tool.Context) -> None:
|
def disable_editing_context(context: type[tool.Context]) -> None:
|
||||||
context.clear_context()
|
context.clear_context()
|
||||||
|
|
||||||
|
|
||||||
def edit_context(ifc: tool.Ifc, context: tool.Context) -> None:
|
def edit_context(ifc: type[tool.Ifc], context: type[tool.Context]) -> None:
|
||||||
ifc.run("context.edit_context", context=context.get_context(), attributes=context.export_attributes())
|
ifc.run("context.edit_context", context=context.get_context(), attributes=context.export_attributes())
|
||||||
disable_editing_context(context)
|
disable_editing_context(context)
|
||||||
|
|||||||
@@ -458,7 +458,5 @@ def add_currency(ifc: type[tool.Ifc], cost: type[tool.Cost]) -> ifcopenshell.ent
|
|||||||
return unit
|
return unit
|
||||||
|
|
||||||
|
|
||||||
def generate_cost_schedule_browser(
|
def generate_cost_schedule_browser(cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance
|
|
||||||
) -> bpy.types.Panel:
|
|
||||||
return cost.generate_cost_schedule_browser(cost_schedule)
|
return cost.generate_cost_schedule_browser(cost_schedule)
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def add_instance_flooring_covering_from_cursor(ifc: tool.Ifc, root: tool.Root, spatial: tool.Spatial) -> None:
|
def add_instance_flooring_covering_from_cursor(
|
||||||
|
ifc: type[tool.Ifc], root: type[tool.Root], spatial: type[tool.Spatial]
|
||||||
|
) -> None:
|
||||||
if not root.get_default_container():
|
if not root.get_default_container():
|
||||||
raise NoDefaultContainer()
|
raise NoDefaultContainer()
|
||||||
|
|
||||||
@@ -68,7 +70,7 @@ def add_instance_flooring_covering_from_cursor(ifc: tool.Ifc, root: tool.Root, s
|
|||||||
|
|
||||||
|
|
||||||
def add_instance_ceiling_covering_from_cursor(
|
def add_instance_ceiling_covering_from_cursor(
|
||||||
ifc: tool.Ifc, root: tool.Root, covering: tool.Covering, spatial: tool.Spatial
|
ifc: type[tool.Ifc], root: type[tool.Root], covering: type[tool.Covering], spatial: type[tool.Spatial]
|
||||||
) -> None:
|
) -> None:
|
||||||
if not root.get_default_container():
|
if not root.get_default_container():
|
||||||
raise NoDefaultContainer()
|
raise NoDefaultContainer()
|
||||||
@@ -111,7 +113,7 @@ def add_instance_ceiling_covering_from_cursor(
|
|||||||
spatial.regen_obj_representation(obj, body)
|
spatial.regen_obj_representation(obj, body)
|
||||||
|
|
||||||
|
|
||||||
def regen_selected_covering_object(root: tool.Root, spatial: tool.Spatial) -> None:
|
def regen_selected_covering_object(root: type[tool.Root], spatial: type[tool.Spatial]) -> None:
|
||||||
if not root.get_default_container():
|
if not root.get_default_container():
|
||||||
raise NoDefaultContainer()
|
raise NoDefaultContainer()
|
||||||
|
|
||||||
@@ -142,7 +144,7 @@ def regen_selected_covering_object(root: tool.Root, spatial: tool.Spatial) -> No
|
|||||||
|
|
||||||
|
|
||||||
# TODO CHECK IF IT IS POSSIBLE TO CREATE ONLY ONE CORE FUNCTION FOR _FROM_WALLS
|
# TODO CHECK IF IT IS POSSIBLE TO CREATE ONLY ONE CORE FUNCTION FOR _FROM_WALLS
|
||||||
def add_instance_flooring_coverings_from_walls(root: tool.Root, spatial: tool.Spatial) -> None:
|
def add_instance_flooring_coverings_from_walls(root: type[tool.Root], spatial: type[tool.Spatial]) -> None:
|
||||||
if not root.get_default_container():
|
if not root.get_default_container():
|
||||||
raise NoDefaultContainer()
|
raise NoDefaultContainer()
|
||||||
|
|
||||||
@@ -168,7 +170,9 @@ def add_instance_flooring_coverings_from_walls(root: tool.Root, spatial: tool.Sp
|
|||||||
spatial.regen_obj_representation(obj, body)
|
spatial.regen_obj_representation(obj, body)
|
||||||
|
|
||||||
|
|
||||||
def add_instance_ceiling_coverings_from_walls(root: tool.Root, spatial: tool.Spatial, covering: tool.Covering) -> None:
|
def add_instance_ceiling_coverings_from_walls(
|
||||||
|
root: type[tool.Root], spatial: type[tool.Spatial], covering: type[tool.Covering]
|
||||||
|
) -> None:
|
||||||
if not root.get_default_container():
|
if not root.get_default_container():
|
||||||
raise NoDefaultContainer()
|
raise NoDefaultContainer()
|
||||||
|
|
||||||
|
|||||||
@@ -25,25 +25,25 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def add_georeferencing(georeference: tool.Georeference) -> None:
|
def add_georeferencing(georeference: type[tool.Georeference]) -> None:
|
||||||
georeference.add_georeferencing()
|
georeference.add_georeferencing()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_georeferencing(georeference: tool.Georeference) -> None:
|
def enable_editing_georeferencing(georeference: type[tool.Georeference]) -> None:
|
||||||
georeference.import_projected_crs()
|
georeference.import_projected_crs()
|
||||||
georeference.import_coordinate_operation()
|
georeference.import_coordinate_operation()
|
||||||
georeference.enable_editing()
|
georeference.enable_editing()
|
||||||
|
|
||||||
|
|
||||||
def remove_georeferencing(ifc: tool.Ifc) -> None:
|
def remove_georeferencing(ifc: type[tool.Ifc]) -> None:
|
||||||
ifc.run("georeference.remove_georeferencing")
|
ifc.run("georeference.remove_georeferencing")
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_georeferencing(georeference: tool.Georeference) -> None:
|
def disable_editing_georeferencing(georeference: type[tool.Georeference]) -> None:
|
||||||
georeference.disable_editing()
|
georeference.disable_editing()
|
||||||
|
|
||||||
|
|
||||||
def edit_georeferencing(ifc: tool.Ifc, georeference: tool.Georeference) -> None:
|
def edit_georeferencing(ifc: type[tool.Ifc], georeference: type[tool.Georeference]) -> None:
|
||||||
ifc.run(
|
ifc.run(
|
||||||
"georeference.edit_georeferencing",
|
"georeference.edit_georeferencing",
|
||||||
projected_crs=georeference.export_projected_crs(),
|
projected_crs=georeference.export_projected_crs(),
|
||||||
@@ -53,7 +53,7 @@ def edit_georeferencing(ifc: tool.Ifc, georeference: tool.Georeference) -> None:
|
|||||||
georeference.set_model_origin()
|
georeference.set_model_origin()
|
||||||
|
|
||||||
|
|
||||||
def get_cursor_location(georeference: tool.Georeference) -> None:
|
def get_cursor_location(georeference: type[tool.Georeference]) -> None:
|
||||||
location = georeference.get_cursor_location()
|
location = georeference.get_cursor_location()
|
||||||
if georeference.has_blender_offset():
|
if georeference.has_blender_offset():
|
||||||
georeference.set_coordinates("blender", location)
|
georeference.set_coordinates("blender", location)
|
||||||
@@ -61,39 +61,39 @@ def get_cursor_location(georeference: tool.Georeference) -> None:
|
|||||||
georeference.set_coordinates("local", location)
|
georeference.set_coordinates("local", location)
|
||||||
|
|
||||||
|
|
||||||
def import_plot(georeference: tool.Georeference, filepath: str) -> None:
|
def import_plot(georeference: type[tool.Georeference], filepath: str) -> None:
|
||||||
georeference.import_plot(filepath)
|
georeference.import_plot(filepath)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_wcs(georeference: tool.Georeference) -> None:
|
def enable_editing_wcs(georeference: type[tool.Georeference]) -> None:
|
||||||
georeference.import_wcs()
|
georeference.import_wcs()
|
||||||
georeference.enable_editing_wcs()
|
georeference.enable_editing_wcs()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_wcs(georeference: tool.Georeference) -> None:
|
def disable_editing_wcs(georeference: type[tool.Georeference]) -> None:
|
||||||
georeference.disable_editing_wcs()
|
georeference.disable_editing_wcs()
|
||||||
|
|
||||||
|
|
||||||
def edit_wcs(georeference: tool.Georeference) -> None:
|
def edit_wcs(georeference: type[tool.Georeference]) -> None:
|
||||||
wcs = georeference.export_wcs()
|
wcs = georeference.export_wcs()
|
||||||
georeference.set_wcs(wcs)
|
georeference.set_wcs(wcs)
|
||||||
georeference.disable_editing_wcs()
|
georeference.disable_editing_wcs()
|
||||||
georeference.set_model_origin()
|
georeference.set_model_origin()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_true_north(georeference: tool.Georeference) -> None:
|
def enable_editing_true_north(georeference: type[tool.Georeference]) -> None:
|
||||||
georeference.import_true_north()
|
georeference.import_true_north()
|
||||||
georeference.enable_editing_true_north()
|
georeference.enable_editing_true_north()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_true_north(georeference: tool.Georeference) -> None:
|
def disable_editing_true_north(georeference: type[tool.Georeference]) -> None:
|
||||||
georeference.disable_editing_true_north()
|
georeference.disable_editing_true_north()
|
||||||
|
|
||||||
|
|
||||||
def edit_true_north(ifc: tool.Ifc, georeference: tool.Georeference) -> None:
|
def edit_true_north(ifc: type[tool.Ifc], georeference: type[tool.Georeference]) -> None:
|
||||||
ifc.run("georeference.edit_true_north", true_north=georeference.get_true_north_attributes())
|
ifc.run("georeference.edit_true_north", true_north=georeference.get_true_north_attributes())
|
||||||
georeference.disable_editing_true_north()
|
georeference.disable_editing_true_north()
|
||||||
|
|
||||||
|
|
||||||
def remove_true_north(ifc: tool.Ifc) -> None:
|
def remove_true_north(ifc: type[tool.Ifc]) -> None:
|
||||||
ifc.run("georeference.edit_true_north", true_north=None)
|
ifc.run("georeference.edit_true_north", true_north=None)
|
||||||
|
|||||||
@@ -25,35 +25,35 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def add_library(ifc: tool.Ifc) -> ifcopenshell.entity_instance:
|
def add_library(ifc: type[tool.Ifc]) -> ifcopenshell.entity_instance:
|
||||||
return ifc.run("library.add_library", name="Unnamed")
|
return ifc.run("library.add_library", name="Unnamed")
|
||||||
|
|
||||||
|
|
||||||
def remove_library(ifc: tool.Ifc, library: ifcopenshell.entity_instance) -> None:
|
def remove_library(ifc: type[tool.Ifc], library: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("library.remove_library", library=library)
|
ifc.run("library.remove_library", library=library)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_library_references(library_tool: tool.Library, library: ifcopenshell.entity_instance) -> None:
|
def enable_editing_library_references(library_tool: type[tool.Library], library: ifcopenshell.entity_instance) -> None:
|
||||||
library_tool.set_editing_mode("REFERENCES")
|
library_tool.set_editing_mode("REFERENCES")
|
||||||
library_tool.set_active_library(library)
|
library_tool.set_active_library(library)
|
||||||
library_tool.import_references(library)
|
library_tool.import_references(library)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_library_references(library: tool.Library) -> None:
|
def disable_editing_library_references(library: type[tool.Library]) -> None:
|
||||||
library.clear_editing_mode()
|
library.clear_editing_mode()
|
||||||
library.set_active_library(None)
|
library.set_active_library(None)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_library(library: tool.Library) -> None:
|
def enable_editing_library(library: type[tool.Library]) -> None:
|
||||||
library.set_editing_mode("LIBRARY")
|
library.set_editing_mode("LIBRARY")
|
||||||
library.import_library_attributes(library.get_active_library())
|
library.import_library_attributes(library.get_active_library())
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_library(library: tool.Library) -> None:
|
def disable_editing_library(library: type[tool.Library]) -> None:
|
||||||
library.set_editing_mode("REFERENCES")
|
library.set_editing_mode("REFERENCES")
|
||||||
|
|
||||||
|
|
||||||
def edit_library(ifc: tool.Ifc, library: tool.Library) -> None:
|
def edit_library(ifc: type[tool.Ifc], library: type[tool.Library]) -> None:
|
||||||
library.set_editing_mode("REFERENCES")
|
library.set_editing_mode("REFERENCES")
|
||||||
active_library = library.get_active_library()
|
active_library = library.get_active_library()
|
||||||
attributes = library.export_library_attributes()
|
attributes = library.export_library_attributes()
|
||||||
@@ -61,29 +61,31 @@ def edit_library(ifc: tool.Ifc, library: tool.Library) -> None:
|
|||||||
library.import_references(active_library)
|
library.import_references(active_library)
|
||||||
|
|
||||||
|
|
||||||
def add_library_reference(ifc: tool.Ifc, library: tool.Library) -> ifcopenshell.entity_instance:
|
def add_library_reference(ifc: type[tool.Ifc], library: type[tool.Library]) -> ifcopenshell.entity_instance:
|
||||||
active_library = library.get_active_library()
|
active_library = library.get_active_library()
|
||||||
reference = ifc.run("library.add_reference", library=active_library)
|
reference = ifc.run("library.add_reference", library=active_library)
|
||||||
library.import_references(active_library)
|
library.import_references(active_library)
|
||||||
return reference
|
return reference
|
||||||
|
|
||||||
|
|
||||||
def remove_library_reference(ifc: tool.Ifc, library: tool.Library, reference: ifcopenshell.entity_instance) -> None:
|
def remove_library_reference(
|
||||||
|
ifc: type[tool.Ifc], library: type[tool.Library], reference: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
ifc.run("library.remove_reference", reference=reference)
|
ifc.run("library.remove_reference", reference=reference)
|
||||||
library.import_references(library.get_active_library())
|
library.import_references(library.get_active_library())
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_library_reference(library: tool.Library, reference: ifcopenshell.entity_instance) -> None:
|
def enable_editing_library_reference(library: type[tool.Library], reference: ifcopenshell.entity_instance) -> None:
|
||||||
library.set_editing_mode("REFERENCE")
|
library.set_editing_mode("REFERENCE")
|
||||||
library.set_active_reference(reference)
|
library.set_active_reference(reference)
|
||||||
library.import_reference_attributes(reference)
|
library.import_reference_attributes(reference)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_library_reference(library: tool.Library) -> None:
|
def disable_editing_library_reference(library: type[tool.Library]) -> None:
|
||||||
library.set_editing_mode("REFERENCES")
|
library.set_editing_mode("REFERENCES")
|
||||||
|
|
||||||
|
|
||||||
def edit_library_reference(ifc: tool.Ifc, library: tool.Library) -> None:
|
def edit_library_reference(ifc: type[tool.Ifc], library: type[tool.Library]) -> None:
|
||||||
library.set_editing_mode("REFERENCES")
|
library.set_editing_mode("REFERENCES")
|
||||||
active_reference = library.get_active_reference()
|
active_reference = library.get_active_reference()
|
||||||
attributes = library.export_reference_attributes()
|
attributes = library.export_reference_attributes()
|
||||||
@@ -91,9 +93,13 @@ def edit_library_reference(ifc: tool.Ifc, library: tool.Library) -> None:
|
|||||||
library.import_references(library.get_active_library())
|
library.import_references(library.get_active_library())
|
||||||
|
|
||||||
|
|
||||||
def assign_library_reference(ifc: tool.Ifc, obj: bpy.types.Object, reference: ifcopenshell.entity_instance) -> None:
|
def assign_library_reference(
|
||||||
|
ifc: type[tool.Ifc], obj: bpy.types.Object, reference: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
ifc.run("library.assign_reference", products=[ifc.get_entity(obj)], reference=reference)
|
ifc.run("library.assign_reference", products=[ifc.get_entity(obj)], reference=reference)
|
||||||
|
|
||||||
|
|
||||||
def unassign_library_reference(ifc: tool.Ifc, obj: bpy.types.Object, reference: ifcopenshell.entity_instance) -> None:
|
def unassign_library_reference(
|
||||||
|
ifc: type[tool.Ifc], obj: bpy.types.Object, reference: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
ifc.run("library.unassign_reference", products=[ifc.get_entity(obj)], reference=reference)
|
ifc.run("library.unassign_reference", products=[ifc.get_entity(obj)], reference=reference)
|
||||||
|
|||||||
@@ -25,18 +25,18 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_nest(nest: tool.Nest, obj: bpy.types.Object) -> None:
|
def enable_editing_nest(nest: type[tool.Nest], obj: bpy.types.Object) -> None:
|
||||||
nest.enable_editing(obj)
|
nest.enable_editing(obj)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_nest(nest: tool.Nest, obj: bpy.types.Object) -> None:
|
def disable_editing_nest(nest: type[tool.Nest], obj: bpy.types.Object) -> None:
|
||||||
nest.disable_editing(obj)
|
nest.disable_editing(obj)
|
||||||
|
|
||||||
|
|
||||||
def assign_object(
|
def assign_object(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
nest: tool.Nest,
|
nest: type[tool.Nest],
|
||||||
collector: tool.Collector,
|
collector: type[tool.Collector],
|
||||||
relating_obj: bpy.types.Object,
|
relating_obj: bpy.types.Object,
|
||||||
related_obj: bpy.types.Object,
|
related_obj: bpy.types.Object,
|
||||||
) -> Union[ifcopenshell.entity_instance, None]:
|
) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
@@ -54,9 +54,9 @@ def assign_object(
|
|||||||
|
|
||||||
|
|
||||||
def unassign_object(
|
def unassign_object(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
nest: tool.Nest,
|
nest: type[tool.Nest],
|
||||||
collector: tool.Collector,
|
collector: type[tool.Collector],
|
||||||
relating_obj: bpy.types.Object,
|
relating_obj: bpy.types.Object,
|
||||||
related_obj: bpy.types.Object,
|
related_obj: bpy.types.Object,
|
||||||
) -> Union[ifcopenshell.entity_instance, None]:
|
) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
@@ -77,10 +77,10 @@ def unassign_object(
|
|||||||
|
|
||||||
|
|
||||||
def add_part_to_object(
|
def add_part_to_object(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
nest: tool.Nest,
|
nest: type[tool.Nest],
|
||||||
collector: tool.Collector,
|
collector: type[tool.Collector],
|
||||||
blender: tool.Blender,
|
blender: type[tool.Blender],
|
||||||
obj: bpy.types.Object,
|
obj: bpy.types.Object,
|
||||||
part_class: str,
|
part_class: str,
|
||||||
part_name: str,
|
part_name: str,
|
||||||
@@ -90,7 +90,7 @@ def add_part_to_object(
|
|||||||
|
|
||||||
|
|
||||||
def enable_nest_mode(
|
def enable_nest_mode(
|
||||||
nest: tool.Nest,
|
nest: type[tool.Nest],
|
||||||
obj: bpy.types.Object,
|
obj: bpy.types.Object,
|
||||||
) -> None:
|
) -> None:
|
||||||
if nest.get_nest_mode():
|
if nest.get_nest_mode():
|
||||||
@@ -99,5 +99,5 @@ def enable_nest_mode(
|
|||||||
nest.enable_nest_mode(obj)
|
nest.enable_nest_mode(obj)
|
||||||
|
|
||||||
|
|
||||||
def disable_nest_mode(nest: tool.Nest) -> None:
|
def disable_nest_mode(nest: type[tool.Nest]) -> None:
|
||||||
nest.disable_nest_mode()
|
nest.disable_nest_mode()
|
||||||
|
|||||||
@@ -26,5 +26,5 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def run_migrate_patch(patch: tool.Patch, infile: str, outfile: str, schema: str) -> None:
|
def run_migrate_patch(patch: type[tool.Patch], infile: str, outfile: str, schema: str) -> None:
|
||||||
patch.run_migrate_patch(infile, outfile, schema)
|
patch.run_migrate_patch(infile, outfile, schema)
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
def create_project(
|
def create_project(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
georeference: tool.Georeference,
|
georeference: type[tool.Georeference],
|
||||||
project: tool.Project,
|
project: type[tool.Project],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
schema: str,
|
schema: str,
|
||||||
template: Optional[str] = None,
|
template: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
def copy_property_to_selection(
|
def copy_property_to_selection(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
pset: tool.Pset,
|
pset: type[tool.Pset],
|
||||||
obj: bpy.types.Object,
|
obj: bpy.types.Object,
|
||||||
pset_name: str,
|
pset_name: str,
|
||||||
prop_name: str,
|
prop_name: str,
|
||||||
@@ -48,7 +48,11 @@ def copy_property_to_selection(
|
|||||||
|
|
||||||
|
|
||||||
def add_pset(
|
def add_pset(
|
||||||
ifc: tool.Ifc, pset: tool.Pset, blender: tool.Blender, obj_name: str, obj_type: tool.Ifc.OBJECT_TYPE
|
ifc: type[tool.Ifc],
|
||||||
|
pset: type[tool.Pset],
|
||||||
|
blender: type[tool.Blender],
|
||||||
|
obj_name: str,
|
||||||
|
obj_type: type[tool.Ifc].OBJECT_TYPE,
|
||||||
) -> None:
|
) -> None:
|
||||||
pset_name = pset.get_pset_name(obj_name, obj_type, pset_type="PSET")
|
pset_name = pset.get_pset_name(obj_name, obj_type, pset_type="PSET")
|
||||||
if obj_type == "Object":
|
if obj_type == "Object":
|
||||||
@@ -64,12 +68,12 @@ def add_pset(
|
|||||||
|
|
||||||
|
|
||||||
def enable_pset_editing(
|
def enable_pset_editing(
|
||||||
pset_tool: tool.Pset,
|
pset_tool: type[tool.Pset],
|
||||||
pset: Union[ifcopenshell.entity_instance, None],
|
pset: Union[ifcopenshell.entity_instance, None],
|
||||||
pset_name: str,
|
pset_name: str,
|
||||||
pset_type: tool.Pset.PSET_TYPE,
|
pset_type: type[tool.Pset].PSET_TYPE,
|
||||||
obj_name: str,
|
obj_name: str,
|
||||||
obj_type: tool.Ifc.OBJECT_TYPE,
|
obj_type: type[tool.Ifc].OBJECT_TYPE,
|
||||||
) -> None:
|
) -> None:
|
||||||
props = pset_tool.get_pset_props(obj_name, obj_type)
|
props = pset_tool.get_pset_props(obj_name, obj_type)
|
||||||
pset_tool.clear_blender_pset_properties(props)
|
pset_tool.clear_blender_pset_properties(props)
|
||||||
@@ -90,7 +94,7 @@ def enable_pset_editing(
|
|||||||
|
|
||||||
|
|
||||||
def add_proposed_prop(
|
def add_proposed_prop(
|
||||||
pset: tool.Pset, obj_name: str, obj_type: tool.Ifc.OBJECT_TYPE, name: str, value: Any
|
pset: type[tool.Pset], obj_name: str, obj_type: type[tool.Ifc].OBJECT_TYPE, name: str, value: Any
|
||||||
) -> Union[None, str]:
|
) -> Union[None, str]:
|
||||||
props = pset.get_pset_props(obj_name, obj_type)
|
props = pset.get_pset_props(obj_name, obj_type)
|
||||||
res = pset.add_proposed_property(name, pset.cast_string_to_primitive(value), props)
|
res = pset.add_proposed_property(name, pset.cast_string_to_primitive(value), props)
|
||||||
@@ -99,7 +103,7 @@ def add_proposed_prop(
|
|||||||
|
|
||||||
|
|
||||||
def unshare_pset(
|
def unshare_pset(
|
||||||
ifc: tool.Ifc, pset_tool: tool.Pset, obj_type: tool.Ifc.OBJECT_TYPE, obj_name: str, pset_id: int
|
ifc: type[tool.Ifc], pset_tool: type[tool.Pset], obj_type: type[tool.Ifc].OBJECT_TYPE, obj_name: str, pset_id: int
|
||||||
) -> None:
|
) -> None:
|
||||||
elements: list[ifcopenshell.entity_instance]
|
elements: list[ifcopenshell.entity_instance]
|
||||||
pset = ifc.get_entity_by_id(pset_id)
|
pset = ifc.get_entity_by_id(pset_id)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def calculate_circle_radius(qto: tool.Qto, obj: bpy.types.Object) -> float:
|
def calculate_circle_radius(qto: type[tool.Qto], obj: bpy.types.Object) -> float:
|
||||||
result = qto.get_radius_of_selected_vertices(obj)
|
result = qto.get_radius_of_selected_vertices(obj)
|
||||||
qto.set_qto_result(result)
|
qto.set_qto_result(result)
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -1,2 +1,28 @@
|
|||||||
def show_scene_elements(spatial):
|
# Bonsai - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of Bonsai.
|
||||||
|
#
|
||||||
|
# Bonsai is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Bonsai 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
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import bpy
|
||||||
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
|
def show_scene_elements(spatial: type[tool.Spatial]) -> None:
|
||||||
spatial.show_scene_objects()
|
spatial.show_scene_objects()
|
||||||
|
|||||||
+143
-102
@@ -25,106 +25,110 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def add_work_plan(ifc: tool.Ifc) -> ifcopenshell.entity_instance:
|
def add_work_plan(ifc: type[tool.Ifc]) -> ifcopenshell.entity_instance:
|
||||||
return ifc.run("sequence.add_work_plan")
|
return ifc.run("sequence.add_work_plan")
|
||||||
|
|
||||||
|
|
||||||
def remove_work_plan(ifc: tool.Ifc, work_plan: ifcopenshell.entity_instance) -> None:
|
def remove_work_plan(ifc: type[tool.Ifc], work_plan: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.remove_work_plan", work_plan=work_plan)
|
ifc.run("sequence.remove_work_plan", work_plan=work_plan)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_work_plan(sequence: tool.Sequence, work_plan: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_plan(sequence: type[tool.Sequence], work_plan: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.load_work_plan_attributes(work_plan)
|
sequence.load_work_plan_attributes(work_plan)
|
||||||
sequence.enable_editing_work_plan(work_plan)
|
sequence.enable_editing_work_plan(work_plan)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_work_plan(sequence: tool.Sequence) -> None:
|
def disable_editing_work_plan(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.disable_editing_work_plan()
|
sequence.disable_editing_work_plan()
|
||||||
|
|
||||||
|
|
||||||
def edit_work_plan(ifc: tool.Ifc, sequence: tool.Sequence, work_plan: ifcopenshell.entity_instance) -> None:
|
def edit_work_plan(ifc: type[tool.Ifc], sequence: type[tool.Sequence], work_plan: ifcopenshell.entity_instance) -> None:
|
||||||
attributes = sequence.get_work_plan_attributes()
|
attributes = sequence.get_work_plan_attributes()
|
||||||
ifc.run("sequence.edit_work_plan", work_plan=work_plan, attributes=attributes)
|
ifc.run("sequence.edit_work_plan", work_plan=work_plan, attributes=attributes)
|
||||||
sequence.disable_editing_work_plan()
|
sequence.disable_editing_work_plan()
|
||||||
|
|
||||||
|
|
||||||
def edit_work_schedule(ifc: tool.Ifc, sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def edit_work_schedule(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
attributes = sequence.get_work_schedule_attributes()
|
attributes = sequence.get_work_schedule_attributes()
|
||||||
ifc.run("sequence.edit_work_schedule", work_schedule=work_schedule, attributes=attributes)
|
ifc.run("sequence.edit_work_schedule", work_schedule=work_schedule, attributes=attributes)
|
||||||
sequence.disable_editing_work_schedule()
|
sequence.disable_editing_work_schedule()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_work_plan_schedules(
|
def enable_editing_work_plan_schedules(
|
||||||
sequence: tool.Sequence, work_plan: Optional[ifcopenshell.entity_instance] = None
|
sequence: type[tool.Sequence], work_plan: Optional[ifcopenshell.entity_instance] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
sequence.enable_editing_work_plan_schedules(work_plan)
|
sequence.enable_editing_work_plan_schedules(work_plan)
|
||||||
|
|
||||||
|
|
||||||
def add_work_schedule(ifc: tool.Ifc, sequence: tool.Sequence, name: str) -> ifcopenshell.entity_instance:
|
def add_work_schedule(ifc: type[tool.Ifc], sequence: type[tool.Sequence], name: str) -> ifcopenshell.entity_instance:
|
||||||
predefined_type, object_type = sequence.get_user_predefined_type()
|
predefined_type, object_type = sequence.get_user_predefined_type()
|
||||||
return ifc.run("sequence.add_work_schedule", name=name, predefined_type=predefined_type, object_type=object_type)
|
return ifc.run("sequence.add_work_schedule", name=name, predefined_type=predefined_type, object_type=object_type)
|
||||||
|
|
||||||
|
|
||||||
def remove_work_schedule(ifc: tool.Ifc, work_schedule: ifcopenshell.entity_instance) -> None:
|
def remove_work_schedule(ifc: type[tool.Ifc], work_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.remove_work_schedule", work_schedule=work_schedule)
|
ifc.run("sequence.remove_work_schedule", work_schedule=work_schedule)
|
||||||
|
|
||||||
|
|
||||||
def assign_work_schedule(
|
def assign_work_schedule(
|
||||||
ifc: tool.Ifc, work_plan: ifcopenshell.entity_instance, work_schedule: ifcopenshell.entity_instance
|
ifc: type[tool.Ifc], work_plan: ifcopenshell.entity_instance, work_schedule: ifcopenshell.entity_instance
|
||||||
) -> Union[ifcopenshell.entity_instance, None]:
|
) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
if work_schedule:
|
if work_schedule:
|
||||||
return ifc.run("aggregate.assign_object", relating_object=work_plan, products=[work_schedule])
|
return ifc.run("aggregate.assign_object", relating_object=work_plan, products=[work_schedule])
|
||||||
|
|
||||||
|
|
||||||
def unassign_work_schedule(ifc: tool.Ifc, work_schedule: ifcopenshell.entity_instance) -> None:
|
def unassign_work_schedule(ifc: type[tool.Ifc], work_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("aggregate.unassign_object", products=[work_schedule])
|
ifc.run("aggregate.unassign_object", products=[work_schedule])
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_work_schedule(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_schedule(sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.load_work_schedule_attributes(work_schedule)
|
sequence.load_work_schedule_attributes(work_schedule)
|
||||||
sequence.enable_editing_work_schedule(work_schedule)
|
sequence.enable_editing_work_schedule(work_schedule)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_work_schedule_tasks(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_schedule_tasks(
|
||||||
|
sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
sequence.enable_editing_work_schedule_tasks(work_schedule)
|
sequence.enable_editing_work_schedule_tasks(work_schedule)
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def load_task_tree(sequence: tool.Sequence, work_schedule) -> None:
|
def load_task_tree(sequence: type[tool.Sequence], work_schedule) -> None:
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def expand_task(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def expand_task(sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.expand_task(task)
|
sequence.expand_task(task)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def expand_all_tasks(sequence: tool.Sequence) -> None:
|
def expand_all_tasks(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.expand_all_tasks()
|
sequence.expand_all_tasks()
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def contract_task(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def contract_task(sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.contract_task(task)
|
sequence.contract_task(task)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def contract_all_tasks(sequence: tool.Sequence) -> None:
|
def contract_all_tasks(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.contract_all_tasks()
|
sequence.contract_all_tasks()
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def remove_task(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def remove_task(ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.remove_task", task=task)
|
ifc.run("sequence.remove_task", task=task)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
@@ -132,22 +136,24 @@ def remove_task(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entit
|
|||||||
sequence.disable_selecting_deleted_task()
|
sequence.disable_selecting_deleted_task()
|
||||||
|
|
||||||
|
|
||||||
def load_task_properties(sequence: tool.Sequence) -> None:
|
def load_task_properties(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_work_schedule(sequence: tool.Sequence) -> None:
|
def disable_editing_work_schedule(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.disable_editing_work_schedule()
|
sequence.disable_editing_work_schedule()
|
||||||
|
|
||||||
|
|
||||||
def add_summary_task(ifc: tool.Ifc, sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def add_summary_task(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
ifc.run("sequence.add_task", work_schedule=work_schedule)
|
ifc.run("sequence.add_task", work_schedule=work_schedule)
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def add_task(
|
def add_task(
|
||||||
ifc: tool.Ifc, sequence: tool.Sequence, parent_task: Optional[ifcopenshell.entity_instance] = None
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], parent_task: Optional[ifcopenshell.entity_instance] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
ifc.run("sequence.add_task", parent_task=parent_task)
|
ifc.run("sequence.add_task", parent_task=parent_task)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
@@ -155,19 +161,19 @@ def add_task(
|
|||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_task_attributes(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def enable_editing_task_attributes(sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.load_task_attributes(task)
|
sequence.load_task_attributes(task)
|
||||||
sequence.enable_editing_task_attributes(task)
|
sequence.enable_editing_task_attributes(task)
|
||||||
|
|
||||||
|
|
||||||
def edit_task(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def edit_task(ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
attributes = sequence.get_task_attributes()
|
attributes = sequence.get_task_attributes()
|
||||||
ifc.run("sequence.edit_task", task=task, attributes=attributes)
|
ifc.run("sequence.edit_task", task=task, attributes=attributes)
|
||||||
sequence.load_task_properties(task=task)
|
sequence.load_task_properties(task=task)
|
||||||
sequence.disable_editing_task()
|
sequence.disable_editing_task()
|
||||||
|
|
||||||
|
|
||||||
def copy_task_attribute(ifc: tool.Ifc, sequence: tool.Sequence, attribute_name: str) -> None:
|
def copy_task_attribute(ifc: type[tool.Ifc], sequence: type[tool.Sequence], attribute_name: str) -> None:
|
||||||
for task in sequence.get_checked_tasks():
|
for task in sequence.get_checked_tasks():
|
||||||
ifc.run(
|
ifc.run(
|
||||||
"sequence.edit_task",
|
"sequence.edit_task",
|
||||||
@@ -177,18 +183,20 @@ def copy_task_attribute(ifc: tool.Ifc, sequence: tool.Sequence, attribute_name:
|
|||||||
sequence.load_task_properties(task)
|
sequence.load_task_properties(task)
|
||||||
|
|
||||||
|
|
||||||
def duplicate_task(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def duplicate_task(ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.duplicate_task", task=task)
|
ifc.run("sequence.duplicate_task", task=task)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
sequence.load_task_tree(work_schedule)
|
sequence.load_task_tree(work_schedule)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_task(sequence: tool.Sequence) -> None:
|
def disable_editing_task(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.disable_editing_task()
|
sequence.disable_editing_task()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_task_time(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def enable_editing_task_time(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
task_time = sequence.get_task_time(task)
|
task_time = sequence.get_task_time(task)
|
||||||
if task_time is None:
|
if task_time is None:
|
||||||
task_time = ifc.run("sequence.add_task_time", task=task)
|
task_time = ifc.run("sequence.add_task_time", task=task)
|
||||||
@@ -196,7 +204,9 @@ def enable_editing_task_time(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcop
|
|||||||
sequence.enable_editing_task_time(task)
|
sequence.enable_editing_task_time(task)
|
||||||
|
|
||||||
|
|
||||||
def edit_task_time(ifc: tool.Ifc, sequence: tool.Sequence, resource, task_time: ifcopenshell.entity_instance) -> None:
|
def edit_task_time(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], resource, task_time: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
attributes = sequence.get_task_time_attributes()
|
attributes = sequence.get_task_time_attributes()
|
||||||
# TODO: nasty loop goes on when calendar props are messed up
|
# TODO: nasty loop goes on when calendar props are messed up
|
||||||
ifc.run("sequence.edit_task_time", task_time=task_time, attributes=attributes)
|
ifc.run("sequence.edit_task_time", task_time=task_time, attributes=attributes)
|
||||||
@@ -206,34 +216,36 @@ def edit_task_time(ifc: tool.Ifc, sequence: tool.Sequence, resource, task_time:
|
|||||||
resource.load_resource_properties()
|
resource.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
def assign_predecessor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def assign_predecessor(ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
predecessor_task = sequence.get_highlighted_task()
|
predecessor_task = sequence.get_highlighted_task()
|
||||||
ifc.run("sequence.assign_sequence", relating_process=task, related_process=predecessor_task)
|
ifc.run("sequence.assign_sequence", relating_process=task, related_process=predecessor_task)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def unassign_predecessor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def unassign_predecessor(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
predecessor_task = sequence.get_highlighted_task()
|
predecessor_task = sequence.get_highlighted_task()
|
||||||
ifc.run("sequence.unassign_sequence", relating_process=task, related_process=predecessor_task)
|
ifc.run("sequence.unassign_sequence", relating_process=task, related_process=predecessor_task)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def assign_successor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def assign_successor(ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
successor_task = sequence.get_highlighted_task()
|
successor_task = sequence.get_highlighted_task()
|
||||||
ifc.run("sequence.assign_sequence", relating_process=successor_task, related_process=task)
|
ifc.run("sequence.assign_sequence", relating_process=successor_task, related_process=task)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def unassign_successor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def unassign_successor(ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
successor_task = sequence.get_highlighted_task()
|
successor_task = sequence.get_highlighted_task()
|
||||||
ifc.run("sequence.unassign_sequence", relating_process=successor_task, related_process=task)
|
ifc.run("sequence.unassign_sequence", relating_process=successor_task, related_process=task)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def assign_products(
|
def assign_products(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
sequence: tool.Sequence,
|
sequence: type[tool.Sequence],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
task: ifcopenshell.entity_instance,
|
task: ifcopenshell.entity_instance,
|
||||||
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -244,9 +256,9 @@ def assign_products(
|
|||||||
|
|
||||||
|
|
||||||
def unassign_products(
|
def unassign_products(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
sequence: tool.Sequence,
|
sequence: type[tool.Sequence],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
task: ifcopenshell.entity_instance,
|
task: ifcopenshell.entity_instance,
|
||||||
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -257,9 +269,9 @@ def unassign_products(
|
|||||||
|
|
||||||
|
|
||||||
def assign_input_products(
|
def assign_input_products(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
sequence: tool.Sequence,
|
sequence: type[tool.Sequence],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
task: ifcopenshell.entity_instance,
|
task: ifcopenshell.entity_instance,
|
||||||
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -270,9 +282,9 @@ def assign_input_products(
|
|||||||
|
|
||||||
|
|
||||||
def unassign_input_products(
|
def unassign_input_products(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
sequence: tool.Sequence,
|
sequence: type[tool.Sequence],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
task: ifcopenshell.entity_instance,
|
task: ifcopenshell.entity_instance,
|
||||||
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
products: Optional[list[ifcopenshell.entity_instance]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -282,7 +294,9 @@ def unassign_input_products(
|
|||||||
sequence.load_task_inputs(inputs)
|
sequence.load_task_inputs(inputs)
|
||||||
|
|
||||||
|
|
||||||
def assign_resource(ifc: tool.Ifc, sequence: tool.Sequence, resource_tool, task: ifcopenshell.entity_instance) -> None:
|
def assign_resource(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], resource_tool, task: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
resource = resource_tool.get_highlighted_resource()
|
resource = resource_tool.get_highlighted_resource()
|
||||||
sub_resource = ifc.run(
|
sub_resource = ifc.run(
|
||||||
"resource.add_resource",
|
"resource.add_resource",
|
||||||
@@ -296,8 +310,8 @@ def assign_resource(ifc: tool.Ifc, sequence: tool.Sequence, resource_tool, task:
|
|||||||
|
|
||||||
|
|
||||||
def unassign_resource(
|
def unassign_resource(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
sequence: tool.Sequence,
|
sequence: type[tool.Sequence],
|
||||||
resource_tool,
|
resource_tool,
|
||||||
task: ifcopenshell.entity_instance,
|
task: ifcopenshell.entity_instance,
|
||||||
resource: ifcopenshell.entity_instance,
|
resource: ifcopenshell.entity_instance,
|
||||||
@@ -308,54 +322,58 @@ def unassign_resource(
|
|||||||
resource_tool.load_resources()
|
resource_tool.load_resources()
|
||||||
|
|
||||||
|
|
||||||
def remove_work_calendar(ifc: tool.Ifc, work_calendar: ifcopenshell.entity_instance) -> None:
|
def remove_work_calendar(ifc: type[tool.Ifc], work_calendar: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.remove_work_calendar", work_calendar=work_calendar)
|
ifc.run("sequence.remove_work_calendar", work_calendar=work_calendar)
|
||||||
|
|
||||||
|
|
||||||
def add_work_calendar(ifc: tool.Ifc) -> ifcopenshell.entity_instance:
|
def add_work_calendar(ifc: type[tool.Ifc]) -> ifcopenshell.entity_instance:
|
||||||
return ifc.run("sequence.add_work_calendar")
|
return ifc.run("sequence.add_work_calendar")
|
||||||
|
|
||||||
|
|
||||||
def edit_work_calendar(ifc: tool.Ifc, sequence: tool.Sequence, work_calendar: ifcopenshell.entity_instance) -> None:
|
def edit_work_calendar(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], work_calendar: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
attributes = sequence.get_work_calendar_attributes()
|
attributes = sequence.get_work_calendar_attributes()
|
||||||
ifc.run("sequence.edit_work_calendar", work_calendar=work_calendar, attributes=attributes)
|
ifc.run("sequence.edit_work_calendar", work_calendar=work_calendar, attributes=attributes)
|
||||||
sequence.disable_editing_work_calendar()
|
sequence.disable_editing_work_calendar()
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_work_calendar(sequence: tool.Sequence, work_calendar: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_calendar(sequence: type[tool.Sequence], work_calendar: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.load_work_calendar_attributes(work_calendar)
|
sequence.load_work_calendar_attributes(work_calendar)
|
||||||
sequence.enable_editing_work_calendar(work_calendar)
|
sequence.enable_editing_work_calendar(work_calendar)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_work_calendar(sequence: tool.Sequence) -> None:
|
def disable_editing_work_calendar(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.disable_editing_work_calendar()
|
sequence.disable_editing_work_calendar()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_work_calendar_times(sequence: tool.Sequence, work_calendar: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_calendar_times(
|
||||||
|
sequence: type[tool.Sequence], work_calendar: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
sequence.enable_editing_work_calendar_times(work_calendar)
|
sequence.enable_editing_work_calendar_times(work_calendar)
|
||||||
|
|
||||||
|
|
||||||
def add_work_time(
|
def add_work_time(
|
||||||
ifc: tool.Ifc, work_calendar: ifcopenshell.entity_instance, time_type: ifcopenshell.entity_instance
|
ifc: type[tool.Ifc], work_calendar: ifcopenshell.entity_instance, time_type: ifcopenshell.entity_instance
|
||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
return ifc.run("sequence.add_work_time", work_calendar=work_calendar, time_type=time_type)
|
return ifc.run("sequence.add_work_time", work_calendar=work_calendar, time_type=time_type)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_work_time(sequence: tool.Sequence, work_time: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_time(sequence: type[tool.Sequence], work_time: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.load_work_time_attributes(work_time)
|
sequence.load_work_time_attributes(work_time)
|
||||||
sequence.enable_editing_work_time(work_time)
|
sequence.enable_editing_work_time(work_time)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_work_time(sequence: tool.Sequence) -> None:
|
def disable_editing_work_time(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.disable_editing_work_time()
|
sequence.disable_editing_work_time()
|
||||||
|
|
||||||
|
|
||||||
def remove_work_time(ifc: tool.Ifc, work_time=None) -> None:
|
def remove_work_time(ifc: type[tool.Ifc], work_time=None) -> None:
|
||||||
ifc.run("sequence.remove_work_time", work_time=work_time)
|
ifc.run("sequence.remove_work_time", work_time=work_time)
|
||||||
|
|
||||||
|
|
||||||
def edit_work_time(ifc: tool.Ifc, sequence: tool.Sequence) -> None:
|
def edit_work_time(ifc: type[tool.Ifc], sequence: type[tool.Sequence]) -> None:
|
||||||
work_time = sequence.get_active_work_time()
|
work_time = sequence.get_active_work_time()
|
||||||
ifc.run("sequence.edit_work_time", work_time=work_time, attributes=sequence.get_work_time_attributes())
|
ifc.run("sequence.edit_work_time", work_time=work_time, attributes=sequence.get_work_time_attributes())
|
||||||
recurrence_pattern = work_time.RecurrencePattern
|
recurrence_pattern = work_time.RecurrencePattern
|
||||||
@@ -369,32 +387,34 @@ def edit_work_time(ifc: tool.Ifc, sequence: tool.Sequence) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def assign_recurrence_pattern(
|
def assign_recurrence_pattern(
|
||||||
ifc: tool.Ifc, work_time: ifcopenshell.entity_instance, recurrence_type: ifcopenshell.entity_instance
|
ifc: type[tool.Ifc], work_time: ifcopenshell.entity_instance, recurrence_type: ifcopenshell.entity_instance
|
||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
return ifc.run("sequence.assign_recurrence_pattern", parent=work_time, recurrence_type=recurrence_type)
|
return ifc.run("sequence.assign_recurrence_pattern", parent=work_time, recurrence_type=recurrence_type)
|
||||||
|
|
||||||
|
|
||||||
def unassign_recurrence_pattern(ifc: tool.Ifc, recurrence_pattern: ifcopenshell.entity_instance) -> None:
|
def unassign_recurrence_pattern(ifc: type[tool.Ifc], recurrence_pattern: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.unassign_recurrence_pattern", recurrence_pattern=recurrence_pattern)
|
ifc.run("sequence.unassign_recurrence_pattern", recurrence_pattern=recurrence_pattern)
|
||||||
|
|
||||||
|
|
||||||
def add_time_period(ifc: tool.Ifc, sequence: tool.Sequence, recurrence_pattern: ifcopenshell.entity_instance) -> None:
|
def add_time_period(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], recurrence_pattern: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
start_time, end_time = sequence.get_recurrence_pattern_times()
|
start_time, end_time = sequence.get_recurrence_pattern_times()
|
||||||
ifc.run("sequence.add_time_period", recurrence_pattern=recurrence_pattern, start_time=start_time, end_time=end_time)
|
ifc.run("sequence.add_time_period", recurrence_pattern=recurrence_pattern, start_time=start_time, end_time=end_time)
|
||||||
sequence.reset_time_period()
|
sequence.reset_time_period()
|
||||||
|
|
||||||
|
|
||||||
def remove_time_period(ifc: tool.Ifc, time_period: ifcopenshell.entity_instance) -> None:
|
def remove_time_period(ifc: type[tool.Ifc], time_period: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.remove_time_period", time_period=time_period)
|
ifc.run("sequence.remove_time_period", time_period=time_period)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_task_calendar(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def enable_editing_task_calendar(sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.enable_editing_task_calendar(task)
|
sequence.enable_editing_task_calendar(task)
|
||||||
|
|
||||||
|
|
||||||
def edit_task_calendar(
|
def edit_task_calendar(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
sequence: tool.Sequence,
|
sequence: type[tool.Sequence],
|
||||||
task: ifcopenshell.entity_instance,
|
task: ifcopenshell.entity_instance,
|
||||||
work_calendar: ifcopenshell.entity_instance,
|
work_calendar: ifcopenshell.entity_instance,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -404,8 +424,8 @@ def edit_task_calendar(
|
|||||||
|
|
||||||
|
|
||||||
def remove_task_calendar(
|
def remove_task_calendar(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
sequence: tool.Sequence,
|
sequence: type[tool.Sequence],
|
||||||
task: ifcopenshell.entity_instance,
|
task: ifcopenshell.entity_instance,
|
||||||
work_calendar: ifcopenshell.entity_instance,
|
work_calendar: ifcopenshell.entity_instance,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -414,38 +434,42 @@ def remove_task_calendar(
|
|||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_task_sequence(sequence: tool.Sequence) -> None:
|
def enable_editing_task_sequence(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.enable_editing_task_sequence()
|
sequence.enable_editing_task_sequence()
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_task_time(sequence: tool.Sequence) -> None:
|
def disable_editing_task_time(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.disable_editing_task_time()
|
sequence.disable_editing_task_time()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_sequence_attributes(sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance) -> None:
|
def enable_editing_sequence_attributes(
|
||||||
|
sequence: type[tool.Sequence], rel_sequence: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
sequence.enable_editing_rel_sequence_attributes(rel_sequence)
|
sequence.enable_editing_rel_sequence_attributes(rel_sequence)
|
||||||
sequence.load_rel_sequence_attributes(rel_sequence)
|
sequence.load_rel_sequence_attributes(rel_sequence)
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_sequence_lag_time(
|
def enable_editing_sequence_lag_time(
|
||||||
sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance, lag_time: ifcopenshell.entity_instance
|
sequence: type[tool.Sequence], rel_sequence: ifcopenshell.entity_instance, lag_time: ifcopenshell.entity_instance
|
||||||
) -> None:
|
) -> None:
|
||||||
sequence.load_lag_time_attributes(lag_time)
|
sequence.load_lag_time_attributes(lag_time)
|
||||||
sequence.enable_editing_sequence_lag_time(rel_sequence)
|
sequence.enable_editing_sequence_lag_time(rel_sequence)
|
||||||
|
|
||||||
|
|
||||||
def unassign_lag_time(ifc: tool.Ifc, sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance) -> None:
|
def unassign_lag_time(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], rel_sequence: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
ifc.run("sequence.unassign_lag_time", rel_sequence=rel_sequence)
|
ifc.run("sequence.unassign_lag_time", rel_sequence=rel_sequence)
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def assign_lag_time(ifc: tool.Ifc, rel_sequence: ifcopenshell.entity_instance) -> None:
|
def assign_lag_time(ifc: type[tool.Ifc], rel_sequence: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.assign_lag_time", rel_sequence=rel_sequence, lag_value="P1D")
|
ifc.run("sequence.assign_lag_time", rel_sequence=rel_sequence, lag_value="P1D")
|
||||||
|
|
||||||
|
|
||||||
def edit_sequence_attributes(
|
def edit_sequence_attributes(
|
||||||
ifc: tool.Ifc, sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], rel_sequence: ifcopenshell.entity_instance
|
||||||
) -> None:
|
) -> None:
|
||||||
attributes = sequence.get_rel_sequence_attributes()
|
attributes = sequence.get_rel_sequence_attributes()
|
||||||
ifc.run("sequence.edit_sequence", rel_sequence=rel_sequence, attributes=attributes)
|
ifc.run("sequence.edit_sequence", rel_sequence=rel_sequence, attributes=attributes)
|
||||||
@@ -453,33 +477,41 @@ def edit_sequence_attributes(
|
|||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def edit_sequence_lag_time(ifc: tool.Ifc, sequence: tool.Sequence, lag_time: ifcopenshell.entity_instance) -> None:
|
def edit_sequence_lag_time(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], lag_time: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
attributes = sequence.get_lag_time_attributes()
|
attributes = sequence.get_lag_time_attributes()
|
||||||
ifc.run("sequence.edit_lag_time", lag_time=lag_time, attributes=attributes)
|
ifc.run("sequence.edit_lag_time", lag_time=lag_time, attributes=attributes)
|
||||||
sequence.disable_editing_rel_sequence()
|
sequence.disable_editing_rel_sequence()
|
||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_rel_sequence(sequence: tool.Sequence) -> None:
|
def disable_editing_rel_sequence(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.disable_editing_rel_sequence()
|
sequence.disable_editing_rel_sequence()
|
||||||
|
|
||||||
|
|
||||||
def select_task_outputs(sequence: tool.Sequence, spatial: tool.Spatial, task: ifcopenshell.entity_instance) -> None:
|
def select_task_outputs(
|
||||||
|
sequence: type[tool.Sequence], spatial: type[tool.Spatial], task: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
spatial.select_products(products=sequence.get_task_outputs(task))
|
spatial.select_products(products=sequence.get_task_outputs(task))
|
||||||
|
|
||||||
|
|
||||||
def select_task_inputs(sequence: tool.Sequence, spatial: tool.Spatial, task: ifcopenshell.entity_instance) -> None:
|
def select_task_inputs(
|
||||||
|
sequence: type[tool.Sequence], spatial: type[tool.Spatial], task: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
spatial.select_products(products=sequence.get_task_inputs(task))
|
spatial.select_products(products=sequence.get_task_inputs(task))
|
||||||
|
|
||||||
|
|
||||||
def select_work_schedule_products(
|
def select_work_schedule_products(
|
||||||
sequence: tool.Sequence, spatial: tool.Spatial, work_schedule: ifcopenshell.entity_instance
|
sequence: type[tool.Sequence], spatial: type[tool.Spatial], work_schedule: ifcopenshell.entity_instance
|
||||||
) -> None:
|
) -> None:
|
||||||
products = sequence.get_work_schedule_products(work_schedule)
|
products = sequence.get_work_schedule_products(work_schedule)
|
||||||
spatial.select_products(products)
|
spatial.select_products(products)
|
||||||
|
|
||||||
|
|
||||||
def select_unassigned_work_schedule_products(ifc: tool.Ifc, sequence: tool.Sequence, spatial: tool.Spatial) -> None:
|
def select_unassigned_work_schedule_products(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], spatial: type[tool.Spatial]
|
||||||
|
) -> None:
|
||||||
spatial.deselect_objects()
|
spatial.deselect_objects()
|
||||||
products = ifc.get().by_type("IfcElement")
|
products = ifc.get().by_type("IfcElement")
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
@@ -488,11 +520,11 @@ def select_unassigned_work_schedule_products(ifc: tool.Ifc, sequence: tool.Seque
|
|||||||
spatial.select_products(selection)
|
spatial.select_products(selection)
|
||||||
|
|
||||||
|
|
||||||
def recalculate_schedule(ifc: tool.Ifc, work_schedule: ifcopenshell.entity_instance) -> None:
|
def recalculate_schedule(ifc: type[tool.Ifc], work_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("sequence.recalculate_schedule", work_schedule=work_schedule)
|
ifc.run("sequence.recalculate_schedule", work_schedule=work_schedule)
|
||||||
|
|
||||||
|
|
||||||
def add_task_column(sequence: tool.Sequence, column_type: str, name: str, data_type: str) -> None:
|
def add_task_column(sequence: type[tool.Sequence], column_type: str, name: str, data_type: str) -> None:
|
||||||
sequence.add_task_column(column_type, name, data_type)
|
sequence.add_task_column(column_type, name, data_type)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
if work_schedule:
|
if work_schedule:
|
||||||
@@ -500,11 +532,11 @@ def add_task_column(sequence: tool.Sequence, column_type: str, name: str, data_t
|
|||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def remove_task_column(sequence: tool.Sequence, name: str) -> None:
|
def remove_task_column(sequence: type[tool.Sequence], name: str) -> None:
|
||||||
sequence.remove_task_column(name)
|
sequence.remove_task_column(name)
|
||||||
|
|
||||||
|
|
||||||
def set_task_sort_column(sequence: tool.Sequence, column: str) -> None:
|
def set_task_sort_column(sequence: type[tool.Sequence], column: str) -> None:
|
||||||
sequence.set_task_sort_column(column)
|
sequence.set_task_sort_column(column)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
if work_schedule:
|
if work_schedule:
|
||||||
@@ -512,7 +544,9 @@ def set_task_sort_column(sequence: tool.Sequence, column: str) -> None:
|
|||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def calculate_task_duration(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
|
def calculate_task_duration(
|
||||||
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
ifc.run("sequence.calculate_task_duration", task=task)
|
ifc.run("sequence.calculate_task_duration", task=task)
|
||||||
work_schedule = sequence.get_active_work_schedule()
|
work_schedule = sequence.get_active_work_schedule()
|
||||||
if work_schedule:
|
if work_schedule:
|
||||||
@@ -520,11 +554,13 @@ def calculate_task_duration(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcope
|
|||||||
sequence.load_task_properties()
|
sequence.load_task_properties()
|
||||||
|
|
||||||
|
|
||||||
def load_animation_color_scheme(sequence: tool.Sequence, scheme: Union[ifcopenshell.entity_instance, None]) -> None:
|
def load_animation_color_scheme(
|
||||||
|
sequence: type[tool.Sequence], scheme: Union[ifcopenshell.entity_instance, None]
|
||||||
|
) -> None:
|
||||||
sequence.load_animation_color_scheme(scheme)
|
sequence.load_animation_color_scheme(scheme)
|
||||||
|
|
||||||
|
|
||||||
def go_to_task(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> Union[None, str]:
|
def go_to_task(sequence: type[tool.Sequence], task: ifcopenshell.entity_instance) -> Union[None, str]:
|
||||||
work_schedule = sequence.get_work_schedule(task)
|
work_schedule = sequence.get_work_schedule(task)
|
||||||
is_work_schedule_active = sequence.is_work_schedule_active(work_schedule)
|
is_work_schedule_active = sequence.is_work_schedule_active(work_schedule)
|
||||||
if is_work_schedule_active:
|
if is_work_schedule_active:
|
||||||
@@ -533,26 +569,28 @@ def go_to_task(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> U
|
|||||||
return "Work schedule is not active"
|
return "Work schedule is not active"
|
||||||
|
|
||||||
|
|
||||||
def guess_date_range(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def guess_date_range(sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
start, finish = sequence.guess_date_range(work_schedule)
|
start, finish = sequence.guess_date_range(work_schedule)
|
||||||
sequence.update_visualisation_date(start, finish)
|
sequence.update_visualisation_date(start, finish)
|
||||||
|
|
||||||
|
|
||||||
def setup_default_task_columns(sequence: tool.Sequence) -> None:
|
def setup_default_task_columns(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.setup_default_task_columns()
|
sequence.setup_default_task_columns()
|
||||||
|
|
||||||
|
|
||||||
def add_task_bars(sequence: tool.Sequence) -> None:
|
def add_task_bars(sequence: type[tool.Sequence]) -> None:
|
||||||
tasks = sequence.get_animation_bar_tasks()
|
tasks = sequence.get_animation_bar_tasks()
|
||||||
if tasks:
|
if tasks:
|
||||||
sequence.create_bars(tasks)
|
sequence.create_bars(tasks)
|
||||||
|
|
||||||
|
|
||||||
def load_default_animation_color_scheme(sequence: tool.Sequence) -> None:
|
def load_default_animation_color_scheme(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.load_default_animation_color_scheme()
|
sequence.load_default_animation_color_scheme()
|
||||||
|
|
||||||
|
|
||||||
def visualise_work_schedule_date_range(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def visualise_work_schedule_date_range(
|
||||||
|
sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
sequence.clear_objects_animation(include_blender_objects=False)
|
sequence.clear_objects_animation(include_blender_objects=False)
|
||||||
settings = sequence.get_animation_settings()
|
settings = sequence.get_animation_settings()
|
||||||
if settings:
|
if settings:
|
||||||
@@ -566,7 +604,7 @@ def visualise_work_schedule_date_range(sequence: tool.Sequence, work_schedule: i
|
|||||||
sequence.set_object_shading()
|
sequence.set_object_shading()
|
||||||
|
|
||||||
|
|
||||||
def visualise_work_schedule_date(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def visualise_work_schedule_date(sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
sequence.clear_objects_animation(include_blender_objects=False)
|
sequence.clear_objects_animation(include_blender_objects=False)
|
||||||
start_date = sequence.get_start_date()
|
start_date = sequence.get_start_date()
|
||||||
product_states = sequence.process_construction_state(work_schedule, start_date)
|
product_states = sequence.process_construction_state(work_schedule, start_date)
|
||||||
@@ -574,13 +612,13 @@ def visualise_work_schedule_date(sequence: tool.Sequence, work_schedule: ifcopen
|
|||||||
sequence.set_object_shading()
|
sequence.set_object_shading()
|
||||||
|
|
||||||
|
|
||||||
def generate_gantt_chart(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
|
def generate_gantt_chart(sequence: type[tool.Sequence], work_schedule: ifcopenshell.entity_instance) -> None:
|
||||||
json = sequence.create_tasks_json(work_schedule)
|
json = sequence.create_tasks_json(work_schedule)
|
||||||
sequence.generate_gantt_browser_chart(json, work_schedule)
|
sequence.generate_gantt_browser_chart(json, work_schedule)
|
||||||
|
|
||||||
|
|
||||||
def load_product_related_tasks(
|
def load_product_related_tasks(
|
||||||
sequence: tool.Sequence, product: ifcopenshell.entity_instance
|
sequence: type[tool.Sequence], product: ifcopenshell.entity_instance
|
||||||
) -> Union[list[ifcopenshell.entity_instance], str]:
|
) -> Union[list[ifcopenshell.entity_instance], str]:
|
||||||
filter_by_schedule = sequence.is_filter_by_active_schedule()
|
filter_by_schedule = sequence.is_filter_by_active_schedule()
|
||||||
if filter_by_schedule:
|
if filter_by_schedule:
|
||||||
@@ -596,7 +634,7 @@ def load_product_related_tasks(
|
|||||||
|
|
||||||
|
|
||||||
def reorder_task_nesting(
|
def reorder_task_nesting(
|
||||||
ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance, new_index: int
|
ifc: type[tool.Ifc], sequence: type[tool.Sequence], task: ifcopenshell.entity_instance, new_index: int
|
||||||
) -> Union[None, str]:
|
) -> Union[None, str]:
|
||||||
is_sorting_enabled = sequence.is_sorting_enabled()
|
is_sorting_enabled = sequence.is_sorting_enabled()
|
||||||
is_sort_reversed = sequence.is_sort_reversed()
|
is_sort_reversed = sequence.is_sort_reversed()
|
||||||
@@ -610,18 +648,21 @@ def reorder_task_nesting(
|
|||||||
|
|
||||||
|
|
||||||
def create_baseline(
|
def create_baseline(
|
||||||
ifc: tool.Ifc, sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance, name: Optional[str] = None
|
ifc: type[tool.Ifc],
|
||||||
|
sequence: type[tool.Sequence],
|
||||||
|
work_schedule: ifcopenshell.entity_instance,
|
||||||
|
name: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
ifc.run("sequence.create_baseline", work_schedule=work_schedule, name=name)
|
ifc.run("sequence.create_baseline", work_schedule=work_schedule, name=name)
|
||||||
|
|
||||||
|
|
||||||
def clear_previous_animation(sequence: tool.Sequence) -> None:
|
def clear_previous_animation(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.clear_objects_animation(include_blender_objects=False)
|
sequence.clear_objects_animation(include_blender_objects=False)
|
||||||
|
|
||||||
|
|
||||||
def add_animation_camera(sequence: tool.Sequence) -> None:
|
def add_animation_camera(sequence: type[tool.Sequence]) -> None:
|
||||||
sequence.add_animation_camera()
|
sequence.add_animation_camera()
|
||||||
|
|
||||||
|
|
||||||
def save_animation_color_scheme(sequence: tool.Sequence, name: str) -> None:
|
def save_animation_color_scheme(sequence: type[tool.Sequence], name: str) -> None:
|
||||||
sequence.save_animation_color_scheme(name)
|
sequence.save_animation_color_scheme(name)
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
def reference_structure(
|
def reference_structure(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
structure: Optional[ifcopenshell.entity_instance] = None,
|
structure: Optional[ifcopenshell.entity_instance] = None,
|
||||||
element: Optional[ifcopenshell.entity_instance] = None,
|
element: Optional[ifcopenshell.entity_instance] = None,
|
||||||
) -> Union[ifcopenshell.entity_instance, None]:
|
) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
@@ -36,8 +36,8 @@ def reference_structure(
|
|||||||
|
|
||||||
|
|
||||||
def dereference_structure(
|
def dereference_structure(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
structure: Optional[ifcopenshell.entity_instance] = None,
|
structure: Optional[ifcopenshell.entity_instance] = None,
|
||||||
element: Optional[ifcopenshell.entity_instance] = None,
|
element: Optional[ifcopenshell.entity_instance] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -46,9 +46,9 @@ def dereference_structure(
|
|||||||
|
|
||||||
|
|
||||||
def assign_container(
|
def assign_container(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
collector: tool.Collector,
|
collector: type[tool.Collector],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
container: ifcopenshell.entity_instance,
|
container: ifcopenshell.entity_instance,
|
||||||
element_obj: Optional[bpy.types.Object] = None,
|
element_obj: Optional[bpy.types.Object] = None,
|
||||||
) -> Union[ifcopenshell.entity_instance, None]:
|
) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
@@ -61,24 +61,24 @@ def assign_container(
|
|||||||
return rel
|
return rel
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_container(spatial: tool.Spatial, obj: bpy.types.Object) -> None:
|
def enable_editing_container(spatial: type[tool.Spatial], obj: bpy.types.Object) -> None:
|
||||||
spatial.set_target_container_as_default()
|
spatial.set_target_container_as_default()
|
||||||
spatial.enable_editing(obj)
|
spatial.enable_editing(obj)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_container(spatial: tool.Spatial, obj: bpy.types.Object) -> None:
|
def disable_editing_container(spatial: type[tool.Spatial], obj: bpy.types.Object) -> None:
|
||||||
spatial.disable_editing(obj)
|
spatial.disable_editing(obj)
|
||||||
|
|
||||||
|
|
||||||
def remove_container(ifc: tool.Ifc, collector: tool.Collector, obj: bpy.types.Object) -> None:
|
def remove_container(ifc: type[tool.Ifc], collector: type[tool.Collector], obj: bpy.types.Object) -> None:
|
||||||
ifc.run("spatial.unassign_container", products=[ifc.get_entity(obj)])
|
ifc.run("spatial.unassign_container", products=[ifc.get_entity(obj)])
|
||||||
collector.assign(obj)
|
collector.assign(obj)
|
||||||
|
|
||||||
|
|
||||||
def copy_to_container(
|
def copy_to_container(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
collector: tool.Collector,
|
collector: type[tool.Collector],
|
||||||
spatial: tool.Spatial,
|
spatial: type[tool.Spatial],
|
||||||
obj: bpy.types.Object,
|
obj: bpy.types.Object,
|
||||||
containers: list[ifcopenshell.entity_instance],
|
containers: list[ifcopenshell.entity_instance],
|
||||||
) -> list[ifcopenshell.entity_instance]:
|
) -> list[ifcopenshell.entity_instance]:
|
||||||
@@ -102,57 +102,71 @@ def copy_to_container(
|
|||||||
|
|
||||||
|
|
||||||
def select_container(
|
def select_container(
|
||||||
ifc: tool.Ifc, spatial: tool.Spatial, container: ifcopenshell.entity_instance, selection_mode: str = "ADD"
|
ifc: type[tool.Ifc],
|
||||||
|
spatial: type[tool.Spatial],
|
||||||
|
container: ifcopenshell.entity_instance,
|
||||||
|
selection_mode: str = "ADD",
|
||||||
) -> None:
|
) -> None:
|
||||||
spatial.set_active_object(ifc.get_object(container), selection_mode=selection_mode)
|
spatial.set_active_object(ifc.get_object(container), selection_mode=selection_mode)
|
||||||
|
|
||||||
|
|
||||||
def select_similar_container(ifc: tool.Ifc, spatial: tool.Spatial, obj: bpy.types.Object) -> None:
|
def select_similar_container(ifc: type[tool.Ifc], spatial: type[tool.Spatial], obj: bpy.types.Object) -> None:
|
||||||
element = ifc.get_entity(obj)
|
element = ifc.get_entity(obj)
|
||||||
if element:
|
if element:
|
||||||
spatial.select_products(spatial.get_decomposed_elements(spatial.get_container(element)))
|
spatial.select_products(spatial.get_decomposed_elements(spatial.get_container(element)))
|
||||||
|
|
||||||
|
|
||||||
def select_product(spatial: tool.Spatial, product: ifcopenshell.entity_instance) -> None:
|
def select_product(spatial: type[tool.Spatial], product: ifcopenshell.entity_instance) -> None:
|
||||||
spatial.select_products([product])
|
spatial.select_products([product])
|
||||||
|
|
||||||
|
|
||||||
def import_spatial_decomposition(spatial: tool.Spatial) -> None:
|
def import_spatial_decomposition(spatial: type[tool.Spatial]) -> None:
|
||||||
spatial.import_spatial_decomposition()
|
spatial.import_spatial_decomposition()
|
||||||
|
|
||||||
|
|
||||||
def set_orientation_slot(spatial: tool.Spatial, container: ifcopenshell.entity_instance) -> None:
|
def set_orientation_slot(spatial: type[tool.Spatial], container: ifcopenshell.entity_instance) -> None:
|
||||||
spatial.create_orientation_slot(container)
|
spatial.create_orientation_slot(container)
|
||||||
|
|
||||||
|
|
||||||
def contract_container(spatial: tool.Spatial, container: ifcopenshell.entity_instance, is_recursive: bool) -> None:
|
def contract_container(
|
||||||
|
spatial: type[tool.Spatial], container: ifcopenshell.entity_instance, is_recursive: bool
|
||||||
|
) -> None:
|
||||||
spatial.contract_container(container, is_recursive=is_recursive)
|
spatial.contract_container(container, is_recursive=is_recursive)
|
||||||
spatial.import_spatial_decomposition()
|
spatial.import_spatial_decomposition()
|
||||||
|
|
||||||
|
|
||||||
def expand_container(spatial: tool.Spatial, container: ifcopenshell.entity_instance, is_recursive: bool) -> None:
|
def expand_container(spatial: type[tool.Spatial], container: ifcopenshell.entity_instance, is_recursive: bool) -> None:
|
||||||
spatial.expand_container(container, is_recursive=is_recursive)
|
spatial.expand_container(container, is_recursive=is_recursive)
|
||||||
spatial.import_spatial_decomposition()
|
spatial.import_spatial_decomposition()
|
||||||
|
|
||||||
|
|
||||||
def delete_container(
|
def delete_container(
|
||||||
ifc: tool.Ifc, spatial: tool.Spatial, geometry: tool.Geometry, container: ifcopenshell.entity_instance
|
ifc: type[tool.Ifc],
|
||||||
|
spatial: type[tool.Spatial],
|
||||||
|
geometry: type[tool.Geometry],
|
||||||
|
container: ifcopenshell.entity_instance,
|
||||||
) -> None:
|
) -> None:
|
||||||
geometry.delete_ifc_object(ifc.get_object(container))
|
geometry.delete_ifc_object(ifc.get_object(container))
|
||||||
spatial.import_spatial_decomposition()
|
spatial.import_spatial_decomposition()
|
||||||
|
|
||||||
|
|
||||||
def toggle_container_element(spatial: tool.Spatial, element_index: int, is_recursive: bool) -> None:
|
def toggle_container_element(spatial: type[tool.Spatial], element_index: int, is_recursive: bool) -> None:
|
||||||
spatial.toggle_container_element(element_index, is_recursive=is_recursive)
|
spatial.toggle_container_element(element_index, is_recursive=is_recursive)
|
||||||
spatial.load_contained_elements()
|
spatial.load_contained_elements()
|
||||||
|
|
||||||
|
|
||||||
def select_decomposed_element(ifc: tool.Ifc, spatial: tool.Spatial, element: ifcopenshell.entity_instance) -> None:
|
def select_decomposed_element(
|
||||||
|
ifc: type[tool.Ifc], spatial: type[tool.Spatial], element: ifcopenshell.entity_instance
|
||||||
|
) -> None:
|
||||||
spatial.set_active_object(ifc.get_object(element))
|
spatial.set_active_object(ifc.get_object(element))
|
||||||
|
|
||||||
|
|
||||||
def generate_space(
|
def generate_space(
|
||||||
ifc: tool.Ifc, model: tool.Model, root: tool.Root, spatial: tool.Spatial, type: tool.Type
|
ifc: type[tool.Ifc],
|
||||||
|
model: type[tool.Model],
|
||||||
|
root: type[tool.Root],
|
||||||
|
spatial: type[tool.Spatial],
|
||||||
|
type: type[tool.Type],
|
||||||
) -> Union[None, str]:
|
) -> Union[None, str]:
|
||||||
"""
|
"""
|
||||||
:return: None if successful, error message string if not.
|
:return: None if successful, error message string if not.
|
||||||
@@ -217,7 +231,9 @@ def generate_space(
|
|||||||
spatial.import_spatial_decomposition()
|
spatial.import_spatial_decomposition()
|
||||||
|
|
||||||
|
|
||||||
def generate_spaces_from_walls(ifc: tool.Ifc, spatial: tool.Spatial, collector: tool.Collector) -> None:
|
def generate_spaces_from_walls(
|
||||||
|
ifc: type[tool.Ifc], spatial: type[tool.Spatial], collector: type[tool.Collector]
|
||||||
|
) -> None:
|
||||||
z = spatial.get_active_obj_z()
|
z = spatial.get_active_obj_z()
|
||||||
h = spatial.get_active_obj_height()
|
h = spatial.get_active_obj_height()
|
||||||
|
|
||||||
@@ -237,7 +253,7 @@ def generate_spaces_from_walls(ifc: tool.Ifc, spatial: tool.Spatial, collector:
|
|||||||
spatial.assign_ifcspace_class_to_obj(obj)
|
spatial.assign_ifcspace_class_to_obj(obj)
|
||||||
|
|
||||||
|
|
||||||
def toggle_space_visibility(ifc: tool.Ifc, spatial: tool.Spatial) -> None:
|
def toggle_space_visibility(ifc: type[tool.Ifc], spatial: type[tool.Spatial]) -> None:
|
||||||
model = ifc.get()
|
model = ifc.get()
|
||||||
spaces = model.by_type("IfcSpace")
|
spaces = model.by_type("IfcSpace")
|
||||||
if not spaces:
|
if not spaces:
|
||||||
@@ -245,7 +261,7 @@ def toggle_space_visibility(ifc: tool.Ifc, spatial: tool.Spatial) -> None:
|
|||||||
spatial.toggle_spaces_visibility_wired_and_textured(spaces)
|
spatial.toggle_spaces_visibility_wired_and_textured(spaces)
|
||||||
|
|
||||||
|
|
||||||
def toggle_hide_spaces(ifc: tool.Ifc, spatial: tool.Spatial) -> None:
|
def toggle_hide_spaces(ifc: type[tool.Ifc], spatial: type[tool.Spatial]) -> None:
|
||||||
model = ifc.get()
|
model = ifc.get()
|
||||||
spaces = model.by_type("IfcSpace")
|
spaces = model.by_type("IfcSpace")
|
||||||
if not spaces:
|
if not spaces:
|
||||||
@@ -253,7 +269,7 @@ def toggle_hide_spaces(ifc: tool.Ifc, spatial: tool.Spatial) -> None:
|
|||||||
spatial.toggle_hide_spaces(spaces)
|
spatial.toggle_hide_spaces(spaces)
|
||||||
|
|
||||||
|
|
||||||
def set_default_container(spatial: tool.Spatial, container: ifcopenshell.entity_instance) -> None:
|
def set_default_container(spatial: type[tool.Spatial], container: ifcopenshell.entity_instance) -> None:
|
||||||
spatial.set_default_container(container)
|
spatial.set_default_container(container)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def add_structural_analysis_model(ifc: tool.Ifc, structural: tool.Structural) -> ifcopenshell.entity_instance:
|
def add_structural_analysis_model(
|
||||||
|
ifc: type[tool.Ifc], structural: type[tool.Structural]
|
||||||
|
) -> ifcopenshell.entity_instance:
|
||||||
result = ifc.run("structural.add_structural_analysis_model")
|
result = ifc.run("structural.add_structural_analysis_model")
|
||||||
structural.load_structural_analysis_models()
|
structural.load_structural_analysis_models()
|
||||||
structural.ensure_representation_contexts()
|
structural.ensure_representation_contexts()
|
||||||
@@ -33,7 +35,7 @@ def add_structural_analysis_model(ifc: tool.Ifc, structural: tool.Structural) ->
|
|||||||
|
|
||||||
|
|
||||||
def assign_structural_analysis_model(
|
def assign_structural_analysis_model(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
products: list[ifcopenshell.entity_instance],
|
products: list[ifcopenshell.entity_instance],
|
||||||
structural_analysis_model: ifcopenshell.entity_instance,
|
structural_analysis_model: ifcopenshell.entity_instance,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -44,15 +46,15 @@ def assign_structural_analysis_model(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_structural_analysis_model(structural: tool.Structural) -> None:
|
def disable_editing_structural_analysis_model(structural: type[tool.Structural]) -> None:
|
||||||
structural.disable_editing_structural_analysis_model()
|
structural.disable_editing_structural_analysis_model()
|
||||||
|
|
||||||
|
|
||||||
def disable_structural_analysis_model_editing_ui(structural: tool.Structural) -> None:
|
def disable_structural_analysis_model_editing_ui(structural: type[tool.Structural]) -> None:
|
||||||
structural.disable_structural_analysis_model_editing_ui()
|
structural.disable_structural_analysis_model_editing_ui()
|
||||||
|
|
||||||
|
|
||||||
def edit_structural_analysis_model(ifc: tool.Ifc, structural: tool.Structural) -> None:
|
def edit_structural_analysis_model(ifc: type[tool.Ifc], structural: type[tool.Structural]) -> None:
|
||||||
attributes = structural.get_structural_analysis_model_attributes()
|
attributes = structural.get_structural_analysis_model_attributes()
|
||||||
ifc.run(
|
ifc.run(
|
||||||
"structural.edit_structural_analysis_model",
|
"structural.edit_structural_analysis_model",
|
||||||
@@ -63,28 +65,28 @@ def edit_structural_analysis_model(ifc: tool.Ifc, structural: tool.Structural) -
|
|||||||
structural.disable_editing_structural_analysis_model()
|
structural.disable_editing_structural_analysis_model()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_structural_analysis_model(structural: tool.Structural, model: Union[int, None]) -> None:
|
def enable_editing_structural_analysis_model(structural: type[tool.Structural], model: Union[int, None]) -> None:
|
||||||
structural.enable_editing_structural_analysis_model(model)
|
structural.enable_editing_structural_analysis_model(model)
|
||||||
|
|
||||||
|
|
||||||
def enable_structural_analysis_model_editing_ui(structural: tool.Structural) -> None:
|
def enable_structural_analysis_model_editing_ui(structural: type[tool.Structural]) -> None:
|
||||||
structural.enable_structural_analysis_model_editing_ui()
|
structural.enable_structural_analysis_model_editing_ui()
|
||||||
|
|
||||||
|
|
||||||
def load_structural_analysis_model_attributes(structural: tool.Structural, model: Union[int, None]) -> None:
|
def load_structural_analysis_model_attributes(structural: type[tool.Structural], model: Union[int, None]) -> None:
|
||||||
data = structural.get_ifc_structural_analysis_model_attributes(model)
|
data = structural.get_ifc_structural_analysis_model_attributes(model)
|
||||||
if data is None:
|
if data is None:
|
||||||
return
|
return
|
||||||
structural.load_structural_analysis_model_attributes(data)
|
structural.load_structural_analysis_model_attributes(data)
|
||||||
|
|
||||||
|
|
||||||
def load_structural_analysis_models(structural: tool.Structural) -> None:
|
def load_structural_analysis_models(structural: type[tool.Structural]) -> None:
|
||||||
structural.load_structural_analysis_models()
|
structural.load_structural_analysis_models()
|
||||||
structural.enable_structural_analysis_model_editing_ui()
|
structural.enable_structural_analysis_model_editing_ui()
|
||||||
# structural.disable_editing_structural_analysis_model()
|
# structural.disable_editing_structural_analysis_model()
|
||||||
|
|
||||||
|
|
||||||
def remove_structural_analysis_model(ifc: tool.Ifc, structural: tool.Structural, model: int) -> None:
|
def remove_structural_analysis_model(ifc: type[tool.Ifc], structural: type[tool.Structural], model: int) -> None:
|
||||||
ifc.run(
|
ifc.run(
|
||||||
"structural.remove_structural_analysis_model",
|
"structural.remove_structural_analysis_model",
|
||||||
structural_analysis_model=ifc.get().by_id(model),
|
structural_analysis_model=ifc.get().by_id(model),
|
||||||
@@ -93,7 +95,7 @@ def remove_structural_analysis_model(ifc: tool.Ifc, structural: tool.Structural,
|
|||||||
|
|
||||||
|
|
||||||
def unassign_structural_analysis_model(
|
def unassign_structural_analysis_model(
|
||||||
ifc: tool.Ifc,
|
ifc: type[tool.Ifc],
|
||||||
products: list[ifcopenshell.entity_instance],
|
products: list[ifcopenshell.entity_instance],
|
||||||
structural_analysis_model: ifcopenshell.entity_instance,
|
structural_analysis_model: ifcopenshell.entity_instance,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@@ -25,62 +25,62 @@ if TYPE_CHECKING:
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
def load_systems(system: tool.System) -> None:
|
def load_systems(system: type[tool.System]) -> None:
|
||||||
system.import_systems()
|
system.import_systems()
|
||||||
system.enable_system_editing_ui()
|
system.enable_system_editing_ui()
|
||||||
system.disable_editing_system()
|
system.disable_editing_system()
|
||||||
|
|
||||||
|
|
||||||
def disable_system_editing_ui(system: tool.System) -> None:
|
def disable_system_editing_ui(system: type[tool.System]) -> None:
|
||||||
system.disable_editing_system()
|
system.disable_editing_system()
|
||||||
system.disable_system_editing_ui()
|
system.disable_system_editing_ui()
|
||||||
|
|
||||||
|
|
||||||
def add_system(ifc: tool.Ifc, system: tool.System, ifc_class: str) -> None:
|
def add_system(ifc: type[tool.Ifc], system: type[tool.System], ifc_class: str) -> None:
|
||||||
ifc.run("system.add_system", ifc_class=ifc_class)
|
ifc.run("system.add_system", ifc_class=ifc_class)
|
||||||
system.import_systems()
|
system.import_systems()
|
||||||
|
|
||||||
|
|
||||||
def edit_system(ifc: tool.Ifc, system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
|
def edit_system(ifc: type[tool.Ifc], system_tool: type[tool.System], system: ifcopenshell.entity_instance) -> None:
|
||||||
attributes = system_tool.export_system_attributes()
|
attributes = system_tool.export_system_attributes()
|
||||||
ifc.run("system.edit_system", system=system, attributes=attributes)
|
ifc.run("system.edit_system", system=system, attributes=attributes)
|
||||||
system_tool.disable_editing_system()
|
system_tool.disable_editing_system()
|
||||||
system_tool.import_systems()
|
system_tool.import_systems()
|
||||||
|
|
||||||
|
|
||||||
def remove_system(ifc: tool.Ifc, system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
|
def remove_system(ifc: type[tool.Ifc], system_tool: type[tool.System], system: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("system.remove_system", system=system)
|
ifc.run("system.remove_system", system=system)
|
||||||
system_tool.import_systems()
|
system_tool.import_systems()
|
||||||
|
|
||||||
|
|
||||||
def enable_editing_system(system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
|
def enable_editing_system(system_tool: type[tool.System], system: ifcopenshell.entity_instance) -> None:
|
||||||
system_tool.import_system_attributes(system)
|
system_tool.import_system_attributes(system)
|
||||||
system_tool.set_active_edited_system(system)
|
system_tool.set_active_edited_system(system)
|
||||||
|
|
||||||
|
|
||||||
def disable_editing_system(system: tool.System) -> None:
|
def disable_editing_system(system: type[tool.System]) -> None:
|
||||||
system.disable_editing_system()
|
system.disable_editing_system()
|
||||||
|
|
||||||
|
|
||||||
def assign_system(
|
def assign_system(
|
||||||
ifc: tool.Ifc, system: ifcopenshell.entity_instance, products: list[ifcopenshell.entity_instance]
|
ifc: type[tool.Ifc], system: ifcopenshell.entity_instance, products: list[ifcopenshell.entity_instance]
|
||||||
) -> None:
|
) -> None:
|
||||||
ifc.run("system.assign_system", products=products, system=system)
|
ifc.run("system.assign_system", products=products, system=system)
|
||||||
|
|
||||||
|
|
||||||
def unassign_system(
|
def unassign_system(
|
||||||
ifc: tool.Ifc, system: ifcopenshell.entity_instance, products: list[ifcopenshell.entity_instance]
|
ifc: type[tool.Ifc], system: ifcopenshell.entity_instance, products: list[ifcopenshell.entity_instance]
|
||||||
) -> None:
|
) -> None:
|
||||||
ifc.run("system.unassign_system", products=products, system=system)
|
ifc.run("system.unassign_system", products=products, system=system)
|
||||||
|
|
||||||
|
|
||||||
def select_system_products(system_tool: tool.System, system: ifcopenshell.entity_instance) -> None:
|
def select_system_products(system_tool: type[tool.System], system: ifcopenshell.entity_instance) -> None:
|
||||||
system_tool.select_system_products(system)
|
system_tool.select_system_products(system)
|
||||||
system_tool.set_active_system(system)
|
system_tool.set_active_system(system)
|
||||||
|
|
||||||
|
|
||||||
def show_ports(
|
def show_ports(
|
||||||
ifc: tool.Ifc, system: tool.System, spatial: tool.Spatial, element: ifcopenshell.entity_instance
|
ifc: type[tool.Ifc], system: type[tool.System], spatial: type[tool.Spatial], element: ifcopenshell.entity_instance
|
||||||
) -> None:
|
) -> None:
|
||||||
obj = ifc.get_object(element)
|
obj = ifc.get_object(element)
|
||||||
if obj and ifc.is_moved(obj):
|
if obj and ifc.is_moved(obj):
|
||||||
@@ -91,7 +91,7 @@ def show_ports(
|
|||||||
spatial.select_products(ports)
|
spatial.select_products(ports)
|
||||||
|
|
||||||
|
|
||||||
def hide_ports(ifc: tool.Ifc, system: tool.System, element: ifcopenshell.entity_instance) -> None:
|
def hide_ports(ifc: type[tool.Ifc], system: type[tool.System], element: ifcopenshell.entity_instance) -> None:
|
||||||
obj = ifc.get_object(element)
|
obj = ifc.get_object(element)
|
||||||
if obj and ifc.is_moved(obj):
|
if obj and ifc.is_moved(obj):
|
||||||
system.run_geometry_edit_object_placement(obj=obj)
|
system.run_geometry_edit_object_placement(obj=obj)
|
||||||
@@ -105,27 +105,29 @@ def hide_ports(ifc: tool.Ifc, system: tool.System, element: ifcopenshell.entity_
|
|||||||
system.delete_element_objects(ports)
|
system.delete_element_objects(ports)
|
||||||
|
|
||||||
|
|
||||||
def add_port(ifc: tool.Ifc, system: tool.System, element: ifcopenshell.entity_instance) -> None:
|
def add_port(ifc: type[tool.Ifc], system: type[tool.System], element: ifcopenshell.entity_instance) -> None:
|
||||||
system.load_ports(element, system.get_ports(element))
|
system.load_ports(element, system.get_ports(element))
|
||||||
obj = system.create_empty_at_cursor_with_element_orientation(element)
|
obj = system.create_empty_at_cursor_with_element_orientation(element)
|
||||||
port = system.run_root_assign_class(obj=obj, ifc_class="IfcDistributionPort", should_add_representation=False)
|
port = system.run_root_assign_class(obj=obj, ifc_class="IfcDistributionPort", should_add_representation=False)
|
||||||
ifc.run("system.assign_port", element=element, port=port)
|
ifc.run("system.assign_port", element=element, port=port)
|
||||||
|
|
||||||
|
|
||||||
def remove_port(ifc: tool.Ifc, system: tool.System, port: ifcopenshell.entity_instance) -> None:
|
def remove_port(ifc: type[tool.Ifc], system: type[tool.System], port: ifcopenshell.entity_instance) -> None:
|
||||||
system.delete_element_objects([port])
|
system.delete_element_objects([port])
|
||||||
ifc.run("root.remove_product", product=port)
|
ifc.run("root.remove_product", product=port)
|
||||||
|
|
||||||
|
|
||||||
def connect_port(ifc: tool.Ifc, port1: ifcopenshell.entity_instance, port2: ifcopenshell.entity_instance) -> None:
|
def connect_port(ifc: type[tool.Ifc], port1: ifcopenshell.entity_instance, port2: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("system.connect_port", port1=port1, port2=port2)
|
ifc.run("system.connect_port", port1=port1, port2=port2)
|
||||||
|
|
||||||
|
|
||||||
def disconnect_port(ifc: tool.Ifc, port: ifcopenshell.entity_instance) -> None:
|
def disconnect_port(ifc: type[tool.Ifc], port: ifcopenshell.entity_instance) -> None:
|
||||||
ifc.run("system.disconnect_port", port=port)
|
ifc.run("system.disconnect_port", port=port)
|
||||||
|
|
||||||
|
|
||||||
def set_flow_direction(ifc: tool.Ifc, system: tool.System, port: ifcopenshell.entity_instance, direction: str) -> None:
|
def set_flow_direction(
|
||||||
|
ifc: type[tool.Ifc], system: type[tool.System], port: ifcopenshell.entity_instance, direction: str
|
||||||
|
) -> None:
|
||||||
port2 = system.get_connected_port(port)
|
port2 = system.get_connected_port(port)
|
||||||
if not port2:
|
if not port2:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,8 +1,35 @@
|
|||||||
def generate_port_number(web):
|
# Bonsai - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of Bonsai.
|
||||||
|
#
|
||||||
|
# Bonsai is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Bonsai 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
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
from typing import TYPE_CHECKING, Optional, Union
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import bpy
|
||||||
|
import ifcopenshell
|
||||||
|
import bonsai.tool as tool
|
||||||
|
|
||||||
|
|
||||||
|
def generate_port_number(web: type[tool.Web]) -> int:
|
||||||
return web.generate_port_number()
|
return web.generate_port_number()
|
||||||
|
|
||||||
|
|
||||||
def connect_websocket_server(web, port, page):
|
def connect_websocket_server(web: type[tool.Web], port: int, page: str) -> None:
|
||||||
# check if port already has a server listening to it
|
# check if port already has a server listening to it
|
||||||
if web.is_port_available(port):
|
if web.is_port_available(port):
|
||||||
web.start_websocket_server(port)
|
web.start_websocket_server(port)
|
||||||
@@ -15,13 +42,13 @@ def connect_websocket_server(web, port, page):
|
|||||||
web.connect_websocket_server(port)
|
web.connect_websocket_server(port)
|
||||||
|
|
||||||
|
|
||||||
def disconnect_websocket_server(web):
|
def disconnect_websocket_server(web: type[tool.Web]) -> None:
|
||||||
web.disconnect_websocket_server()
|
web.disconnect_websocket_server()
|
||||||
|
|
||||||
|
|
||||||
def kill_websocket_server(web):
|
def kill_websocket_server(web: type[tool.Web]) -> None:
|
||||||
web.kill_websocket_server()
|
web.kill_websocket_server()
|
||||||
|
|
||||||
|
|
||||||
def open_web_browser(web, port, page):
|
def open_web_browser(web: type[tool.Web], port: int, page: str) -> None:
|
||||||
web.open_web_browser(port, page)
|
web.open_web_browser(port, page)
|
||||||
|
|||||||
@@ -159,7 +159,6 @@ class Project(bonsai.core.tool.Project):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def set_default_modeling_dimensions(cls) -> None:
|
def set_default_modeling_dimensions(cls) -> None:
|
||||||
props = tool.Model.get_model_props()
|
props = tool.Model.get_model_props()
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
|
||||||
props.extrusion_depth = 3
|
props.extrusion_depth = 3
|
||||||
props.length = 1
|
props.length = 1
|
||||||
props.rl1 = 0
|
props.rl1 = 0
|
||||||
|
|||||||
@@ -355,6 +355,16 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
# Objects
|
# Objects
|
||||||
objs_to_raycast = tool.Raycast.filter_objects_to_raycast(context, event, objs_2d_bbox)
|
objs_to_raycast = tool.Raycast.filter_objects_to_raycast(context, event, objs_2d_bbox)
|
||||||
|
# Wireframes
|
||||||
|
# For wireframe we have to get all the objects so we can further calculate edge intersection
|
||||||
|
for snap_obj in objs_to_raycast:
|
||||||
|
if snap_obj.type in {"EMPTY", "CURVE"} or (snap_obj.type == "MESH" and len(snap_obj.data.polygons) == 0):
|
||||||
|
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, snap_obj)
|
||||||
|
if snap_points:
|
||||||
|
for point in snap_points:
|
||||||
|
point["group"] = "Wireframe"
|
||||||
|
detected_snaps.append(point)
|
||||||
|
|
||||||
if (space.shading.type == "SOLID" and space.shading.show_xray) or (
|
if (space.shading.type == "SOLID" and space.shading.show_xray) or (
|
||||||
space.shading.type == "WIREFRAME" and space.shading.show_xray_wireframe
|
space.shading.type == "WIREFRAME" and space.shading.show_xray_wireframe
|
||||||
):
|
):
|
||||||
@@ -374,12 +384,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
if snap_obj.type in {"EMPTY", "CURVE"} or (
|
if snap_obj.type in {"EMPTY", "CURVE"} or (
|
||||||
snap_obj.type == "MESH" and len(snap_obj.data.polygons) == 0
|
snap_obj.type == "MESH" and len(snap_obj.data.polygons) == 0
|
||||||
):
|
):
|
||||||
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, snap_obj)
|
continue
|
||||||
if snap_points:
|
|
||||||
for point in snap_points:
|
|
||||||
point["group"] = "Wireframe"
|
|
||||||
detected_snaps.append(point)
|
|
||||||
|
|
||||||
# Meshes
|
# Meshes
|
||||||
else:
|
else:
|
||||||
# Add face snap
|
# Add face snap
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class Unit(bonsai.core.tool.Unit):
|
|||||||
def get_scene_unit_name(cls, unit_type: UNIT_TYPE) -> str:
|
def get_scene_unit_name(cls, unit_type: UNIT_TYPE) -> str:
|
||||||
bim_props = tool.Blender.get_bim_props()
|
bim_props = tool.Blender.get_bim_props()
|
||||||
if unit_type == "LENGTHUNIT":
|
if unit_type == "LENGTHUNIT":
|
||||||
|
assert bpy.context.scene
|
||||||
props = bpy.context.scene.unit_settings
|
props = bpy.context.scene.unit_settings
|
||||||
if props.length_unit == "MILES":
|
if props.length_unit == "MILES":
|
||||||
return "mile"
|
return "mile"
|
||||||
@@ -84,12 +85,13 @@ class Unit(bonsai.core.tool.Unit):
|
|||||||
elif unit_type == "VOLUMEUNIT":
|
elif unit_type == "VOLUMEUNIT":
|
||||||
return bim_props.volume_unit
|
return bim_props.volume_unit
|
||||||
else:
|
else:
|
||||||
assert_never()
|
assert_never(unit_type)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_scene_unit_si_prefix(cls, unit_type: UNIT_TYPE) -> Union[str, None]:
|
def get_scene_unit_si_prefix(cls, unit_type: UNIT_TYPE) -> Union[str, None]:
|
||||||
bim_props = tool.Blender.get_bim_props()
|
bim_props = tool.Blender.get_bim_props()
|
||||||
if unit_type == "LENGTHUNIT":
|
if unit_type == "LENGTHUNIT":
|
||||||
|
assert bpy.context.scene
|
||||||
props = bpy.context.scene.unit_settings
|
props = bpy.context.scene.unit_settings
|
||||||
if props.length_unit == "ADAPTIVE" or props.length_unit == "METERS":
|
if props.length_unit == "ADAPTIVE" or props.length_unit == "METERS":
|
||||||
return
|
return
|
||||||
@@ -163,6 +165,7 @@ class Unit(bonsai.core.tool.Unit):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_scene_unit_metric(cls) -> bool:
|
def is_scene_unit_metric(cls) -> bool:
|
||||||
|
assert bpy.context.scene
|
||||||
return bpy.context.scene.unit_settings.system in ["METRIC", "NONE"]
|
return bpy.context.scene.unit_settings.system in ["METRIC", "NONE"]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -189,6 +192,7 @@ class Unit(bonsai.core.tool.Unit):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def blender_format_unit(cls, value: float) -> str:
|
def blender_format_unit(cls, value: float) -> str:
|
||||||
|
assert bpy.context.scene
|
||||||
return bpy.utils.units.to_string(
|
return bpy.utils.units.to_string(
|
||||||
bpy.context.scene.unit_settings.system,
|
bpy.context.scene.unit_settings.system,
|
||||||
"LENGTH",
|
"LENGTH",
|
||||||
|
|||||||
@@ -0,0 +1,652 @@
|
|||||||
|
#include "Iterator.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns true if the iterator is initialized with any elements, false otherwise.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* - A true return value does not guarantee successful initialization of all elements.
|
||||||
|
* Some elements may have failed to initialize. Check had_error_processing_elements()
|
||||||
|
* to see whether there were errors during the initialization.
|
||||||
|
*
|
||||||
|
* - For non-concurrent iterators, a false return may occur if initialization of the first
|
||||||
|
* element fails, even if subsequent elements could be initialized successfully.
|
||||||
|
*/
|
||||||
|
bool IfcGeom::Iterator::initialize() {
|
||||||
|
using std::chrono::high_resolution_clock;
|
||||||
|
|
||||||
|
if (initialization_outcome_) {
|
||||||
|
return *initialization_outcome_;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_points[0] = high_resolution_clock::now();
|
||||||
|
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
|
||||||
|
if (num_threads_ != 1) {
|
||||||
|
// @todo this shouldn't be necessary with properly immutable taxonomy items
|
||||||
|
converter_->mapping()->use_caching() = false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
converter_->mapping()->get_representations(reps, filters_);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
Logger::Error(e);
|
||||||
|
}
|
||||||
|
time_points[1] = high_resolution_clock::now();
|
||||||
|
|
||||||
|
for (auto& task : reps) {
|
||||||
|
geometry_conversion_result res;
|
||||||
|
res.index = task.index;
|
||||||
|
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||||
|
res.representation = task.representation;
|
||||||
|
res.products_2 = task.products;
|
||||||
|
} else {
|
||||||
|
res.item = converter_->mapping()->map(task.representation);
|
||||||
|
if (!res.item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::transform(task.products->begin(), task.products->end(), std::back_inserter(res.products), [this, &res](IfcUtil::IfcBaseClass* prod) {
|
||||||
|
auto prod_item = converter_->mapping()->map(prod);
|
||||||
|
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
tasks_.push_back(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() && settings_.get<ifcopenshell::geometry::settings::PermissiveShapeReuse>().get()) {
|
||||||
|
std::unordered_map<
|
||||||
|
ifcopenshell::geometry::taxonomy::item::ptr,
|
||||||
|
std::vector<std::pair<const IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::taxonomy::matrix4::ptr>>> folded;
|
||||||
|
|
||||||
|
for (auto& r : tasks_) {
|
||||||
|
auto i = r.item;
|
||||||
|
|
||||||
|
Eigen::Matrix4d m4 = Eigen::Matrix4d::Identity();
|
||||||
|
|
||||||
|
while (auto col = std::dynamic_pointer_cast<ifcopenshell::geometry::taxonomy::collection>(i)) {
|
||||||
|
if (col->children.size() == 1) {
|
||||||
|
if (col->matrix) {
|
||||||
|
m4 *= col->matrix->ccomponents();
|
||||||
|
}
|
||||||
|
i = col->children[0];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& p : r.products) {
|
||||||
|
auto pl = ifcopenshell::geometry::taxonomy::matrix4::ptr(p.second->clone_());
|
||||||
|
pl->components() *= m4;
|
||||||
|
folded[i].push_back(
|
||||||
|
{ p.first, pl }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (folded.size() < tasks_.size()) {
|
||||||
|
auto old_size = tasks_.size();
|
||||||
|
tasks_.clear();
|
||||||
|
size_t i = 0;
|
||||||
|
for (auto& p : folded) {
|
||||||
|
tasks_.emplace_back();
|
||||||
|
tasks_.back().index = i++;
|
||||||
|
tasks_.back().item = p.first;
|
||||||
|
tasks_.back().products = p.second;
|
||||||
|
}
|
||||||
|
Logger::Notice("Merged " + std::to_string(old_size) + " tasks into " + std::to_string(tasks_.size()) + " tasks due to permissive shape reuse");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num_products = 0;
|
||||||
|
for (auto& r : tasks_) {
|
||||||
|
num_products += !settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() ? r.products_2->size() : r.products.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
time_points[2] = high_resolution_clock::now();
|
||||||
|
|
||||||
|
/*
|
||||||
|
// What to do, map representation and product individually?
|
||||||
|
// There needs to be two options, mapped item respecting (does that still work?), and optimized based on topology sorting.
|
||||||
|
// Or is the sorting not necessary if we just cache?
|
||||||
|
|
||||||
|
std::vector<taxonomy::ptr> items;
|
||||||
|
std::map<taxonomy::ptr, taxonomy::matrix4> placements;
|
||||||
|
std::transform(products.begin(), products.end(), std::back_inserter(items), [this, &placements](IfcUtil::IfcBaseClass* p) {
|
||||||
|
auto item = converter_->mapping()->map(p);
|
||||||
|
// Product placements do not affect item reuse and should temporarily be swapped to identity
|
||||||
|
if (item) {
|
||||||
|
std::swap(placements[item], ((taxonomy::geom_ptr)item)->matrix);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
items.erase(std::remove(items.begin(), items.end(), nullptr), items.end());
|
||||||
|
std::sort(items.begin(), items.end(), taxonomy::less);
|
||||||
|
auto it = items.begin();
|
||||||
|
while (it < items.end()) {
|
||||||
|
auto jt = std::upper_bound(it, items.end(), *it, taxonomy::less);
|
||||||
|
geometry_conversion_result r;
|
||||||
|
r.item = *it;
|
||||||
|
std::transform(it, jt, std::back_inserter(r.products), [&r, &placements](taxonomy::ptr product_node) {
|
||||||
|
return std::make_pair((IfcUtil::IfcBaseEntity*) product_node->instance, placements[product_node]);
|
||||||
|
});
|
||||||
|
tasks_.push_back(r);
|
||||||
|
it = jt;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Logger::Notice("Created " + boost::lexical_cast<std::string>(tasks_.size()) + " tasks for " + boost::lexical_cast<std::string>(num_products) + " products");
|
||||||
|
|
||||||
|
if (tasks_.size() == 0) {
|
||||||
|
Logger::Warning("No representations encountered, aborting");
|
||||||
|
initialization_outcome_.reset(false);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
task_iterator_ = tasks_.begin();
|
||||||
|
|
||||||
|
task_result_index_ = 0;
|
||||||
|
done = 0;
|
||||||
|
total = (int)tasks_.size();
|
||||||
|
|
||||||
|
if (num_threads_ != 1) {
|
||||||
|
init_future_ = std::async(std::launch::async, [this]() { process_concurrently(); });
|
||||||
|
|
||||||
|
// wait for the first element, because after init(), get() can be called.
|
||||||
|
// so the element conversion must succeed
|
||||||
|
initialization_outcome_ = wait_for_element();
|
||||||
|
} else {
|
||||||
|
initialization_outcome_ = create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *initialization_outcome_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfcGeom::Iterator::process_finished_rep(geometry_conversion_result* rep) {
|
||||||
|
if (rep->elements.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lk(element_ready_mutex_);
|
||||||
|
|
||||||
|
all_processed_elements_.insert(all_processed_elements_.end(), rep->elements.begin(), rep->elements.end());
|
||||||
|
all_processed_native_elements_.insert(all_processed_native_elements_.end(), rep->breps.begin(), rep->breps.end());
|
||||||
|
|
||||||
|
if (!task_result_ptr_initialized) {
|
||||||
|
task_result_iterator_ = all_processed_elements_.begin();
|
||||||
|
native_task_result_iterator_ = all_processed_native_elements_.begin();
|
||||||
|
task_result_ptr_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress_ = (int)(++processed_ * 100 / tasks_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfcGeom::Iterator::process_concurrently() {
|
||||||
|
size_t conc_threads = num_threads_;
|
||||||
|
if (conc_threads > tasks_.size()) {
|
||||||
|
conc_threads = tasks_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel_pool.reserve(conc_threads);
|
||||||
|
for (unsigned i = 0; i < conc_threads; ++i) {
|
||||||
|
kernel_pool.push_back(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::future<geometry_conversion_result*>> threadpool;
|
||||||
|
|
||||||
|
for (auto& rep : tasks_) {
|
||||||
|
ifcopenshell::geometry::Converter* K = nullptr;
|
||||||
|
if (threadpool.size() < kernel_pool.size()) {
|
||||||
|
K = kernel_pool[threadpool.size()];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (threadpool.size() == conc_threads) {
|
||||||
|
for (int i = 0; i < (int)threadpool.size(); i++) {
|
||||||
|
auto& fu = threadpool[i];
|
||||||
|
std::future_status status;
|
||||||
|
status = fu.wait_for(std::chrono::seconds(0));
|
||||||
|
if (status == std::future_status::ready) {
|
||||||
|
process_finished_rep(fu.get());
|
||||||
|
|
||||||
|
std::swap(threadpool[i], threadpool.back());
|
||||||
|
threadpool.pop_back();
|
||||||
|
std::swap(kernel_pool[i], kernel_pool.back());
|
||||||
|
K = kernel_pool.back();
|
||||||
|
break;
|
||||||
|
} // if
|
||||||
|
} // for
|
||||||
|
} // while
|
||||||
|
|
||||||
|
std::future<geometry_conversion_result*> fu = std::async(
|
||||||
|
std::launch::async, [this](
|
||||||
|
ifcopenshell::geometry::Converter* kernel,
|
||||||
|
ifcopenshell::geometry::Settings settings,
|
||||||
|
geometry_conversion_result* rep) {
|
||||||
|
// Catch exceptions to be safe from freezing the iterator.
|
||||||
|
try {
|
||||||
|
this->create_element_(kernel, settings, rep);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
Logger::Error(
|
||||||
|
std::string("Exception '") + e.what() +
|
||||||
|
std::string("' occurred while iterator was creating a shape: "),
|
||||||
|
rep->item->instance
|
||||||
|
);
|
||||||
|
had_error_processing_elements_ = true;
|
||||||
|
} catch (...) {
|
||||||
|
Logger::Error(
|
||||||
|
"Unknown exception occurred while iteartor was creating a shape: ",
|
||||||
|
rep->item->instance
|
||||||
|
);
|
||||||
|
had_error_processing_elements_ = true;
|
||||||
|
}
|
||||||
|
return rep;
|
||||||
|
},
|
||||||
|
K,
|
||||||
|
std::ref(settings_),
|
||||||
|
&rep);
|
||||||
|
|
||||||
|
if (terminating_) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
threadpool.emplace_back(std::move(fu));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& fu : threadpool) {
|
||||||
|
process_finished_rep(fu.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
finished_ = true;
|
||||||
|
|
||||||
|
Logger::SetProduct(boost::none);
|
||||||
|
|
||||||
|
if (!terminating_) {
|
||||||
|
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(all_processed_elements_.size()) +
|
||||||
|
" objects) ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes model's bounding box (bounds_min and bounds_max).
|
||||||
|
/// @note Can take several minutes for large files.
|
||||||
|
void IfcGeom::Iterator::compute_bounds(bool with_geometry)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
bounds_min_.components()(i) = std::numeric_limits<double>::infinity();
|
||||||
|
bounds_max_.components()(i) = -std::numeric_limits<double>::infinity();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (with_geometry) {
|
||||||
|
size_t num_created = 0;
|
||||||
|
do {
|
||||||
|
IfcGeom::Element* geom_object = get();
|
||||||
|
const IfcGeom::TriangulationElement* o = static_cast<const IfcGeom::TriangulationElement*>(geom_object);
|
||||||
|
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
|
||||||
|
auto mat = o->transformation().data()->ccomponents();
|
||||||
|
Eigen::Vector4d vec, transformed;
|
||||||
|
|
||||||
|
for (typename std::vector<double>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end();) {
|
||||||
|
const double& x = *(it++);
|
||||||
|
const double& y = *(it++);
|
||||||
|
const double& z = *(it++);
|
||||||
|
vec << x, y, z, 1.;
|
||||||
|
transformed = mat * vec;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
bounds_min_.components()(i) = std::min(bounds_min_.components()(i), transformed(i));
|
||||||
|
bounds_max_.components()(i) = std::max(bounds_max_.components()(i), transformed(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (++num_created, next());
|
||||||
|
} else {
|
||||||
|
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
|
||||||
|
converter_->mapping()->get_representations(reps, filters_);
|
||||||
|
|
||||||
|
std::vector<IfcUtil::IfcBaseClass*> products;
|
||||||
|
for (auto& r : reps) {
|
||||||
|
std::copy(r.products->begin(), r.products->end(), std::back_inserter(products));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& product : products) {
|
||||||
|
auto prod_item = converter_->mapping()->map(product);
|
||||||
|
auto vec = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix->translation_part();
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
bounds_min_.components()(i) = std::min(bounds_min_.components()(i), vec(i));
|
||||||
|
bounds_max_.components()(i) = std::max(bounds_max_.components()(i), vec(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const IfcUtil::IfcBaseClass* IfcGeom::Iterator::create_shape_model_for_next_entity() {
|
||||||
|
geometry_conversion_result* task = nullptr;
|
||||||
|
for (; task_iterator_ < tasks_.end();) {
|
||||||
|
task = &*task_iterator_++;
|
||||||
|
create_element_(converter_, settings_, task);
|
||||||
|
if (task->elements.empty()) {
|
||||||
|
task = nullptr;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (task) {
|
||||||
|
process_finished_rep(task);
|
||||||
|
return task->item->instance->as<IfcUtil::IfcBaseClass>();
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kernel, ifcopenshell::geometry::Settings settings, geometry_conversion_result* rep)
|
||||||
|
{
|
||||||
|
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||||
|
rep->item = kernel->mapping()->map(rep->representation);
|
||||||
|
if (!rep->item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::transform(rep->products_2->begin(), rep->products_2->end(), std::back_inserter(rep->products), [this, &rep, kernel](IfcUtil::IfcBaseClass* prod) {
|
||||||
|
auto prod_item = kernel->mapping()->map(prod);
|
||||||
|
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
auto product_node = rep->products.front();
|
||||||
|
const IfcUtil::IfcBaseEntity* product = product_node.first;
|
||||||
|
const auto& place = product_node.second;
|
||||||
|
|
||||||
|
Logger::SetProduct(product);
|
||||||
|
|
||||||
|
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product, place, rep]() {
|
||||||
|
return kernel->create_brep_for_representation_and_product(rep->item, product, place);
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!brep) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto elem = process_based_on_settings(settings, brep);
|
||||||
|
if (!elem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rep->breps = { brep };
|
||||||
|
rep->elements = { elem };
|
||||||
|
|
||||||
|
for (auto it = rep->products.begin() + 1; it != rep->products.end(); ++it) {
|
||||||
|
const auto& p = *it;
|
||||||
|
const IfcUtil::IfcBaseEntity* product2 = p.first;
|
||||||
|
const auto& place2 = p.second;
|
||||||
|
|
||||||
|
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product2, place2, brep]() {
|
||||||
|
return kernel->create_brep_for_processed_representation(product2, place2, brep);
|
||||||
|
}));
|
||||||
|
if (brep2) {
|
||||||
|
auto elem2 = process_based_on_settings(settings, brep2, dynamic_cast<IfcGeom::TriangulationElement*>(elem));
|
||||||
|
if (elem2) {
|
||||||
|
rep->breps.push_back(brep2);
|
||||||
|
rep->elements.push_back(elem2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geometry::Settings settings, IfcGeom::BRepElement* elem, IfcGeom::TriangulationElement* previous)
|
||||||
|
{
|
||||||
|
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
|
||||||
|
try {
|
||||||
|
return new IfcGeom::SerializedElement(*elem);
|
||||||
|
} catch (...) {
|
||||||
|
Logger::Message(Logger::LOG_ERROR, "Getting a serialized element from model failed.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} else if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::TRIANGULATED) {
|
||||||
|
// the part before the hyphen is the representation id
|
||||||
|
auto gid2 = elem->geometry().id();
|
||||||
|
auto hyphen = gid2.find("-");
|
||||||
|
if (hyphen != std::string::npos) {
|
||||||
|
gid2 = gid2.substr(0, hyphen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return decorate_with_cache_(GeometrySerializer::READ_TRIANGULATION, elem->guid(), gid2, [elem, previous]() {
|
||||||
|
try {
|
||||||
|
if (!previous) {
|
||||||
|
return new TriangulationElement(*elem);
|
||||||
|
} else {
|
||||||
|
return new TriangulationElement(*elem, previous->geometry_pointer());
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
Logger::Message(Logger::LOG_ERROR, "Getting a triangulation element from model failed.");
|
||||||
|
}
|
||||||
|
return (TriangulationElement*)nullptr;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IfcGeom::Iterator::wait_for_element() {
|
||||||
|
while (true) {
|
||||||
|
size_t s;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(element_ready_mutex_);
|
||||||
|
s = all_processed_elements_.size();
|
||||||
|
}
|
||||||
|
if (s > async_elements_returned_) {
|
||||||
|
++async_elements_returned_;
|
||||||
|
return true;
|
||||||
|
} else if (finished_) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfcGeom::Iterator::log_timepoints() const {
|
||||||
|
using std::chrono::high_resolution_clock;
|
||||||
|
using std::chrono::duration;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
std::array<std::string, 3> labels = {
|
||||||
|
"Initializing mapping"s,
|
||||||
|
"Performing mapping"s,
|
||||||
|
"Geometry interpretation"s
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto it = time_points.begin() + 1; it != time_points.end(); ++it) {
|
||||||
|
auto jt = it - 1;
|
||||||
|
duration<double, std::milli> ms_double = (*it) - (*jt);
|
||||||
|
Logger::Notice(labels[std::distance(time_points.begin(), jt)] + " took " + std::to_string(ms_double.count()) + "ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moves to the next shape representation, create its geometry, and returns the associated product.
|
||||||
|
/// Use get() to retrieve the created geometry.
|
||||||
|
const IfcUtil::IfcBaseClass* IfcGeom::Iterator::next() {
|
||||||
|
using std::chrono::high_resolution_clock;
|
||||||
|
|
||||||
|
if (*native_task_result_iterator_ != *task_result_iterator_) {
|
||||||
|
delete* native_task_result_iterator_;
|
||||||
|
}
|
||||||
|
delete* task_result_iterator_;
|
||||||
|
|
||||||
|
if (num_threads_ != 1) {
|
||||||
|
if (!wait_for_element()) {
|
||||||
|
Logger::SetProduct(boost::none);
|
||||||
|
time_points[3] = high_resolution_clock::now();
|
||||||
|
log_timepoints();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
task_result_iterator_++;
|
||||||
|
native_task_result_iterator_++;
|
||||||
|
|
||||||
|
return (*task_result_iterator_)->product();
|
||||||
|
} else {
|
||||||
|
// Increment the iterator over the list of products using the current
|
||||||
|
// shape representation
|
||||||
|
if (task_result_iterator_ == --all_processed_elements_.end()) {
|
||||||
|
if (!create()) {
|
||||||
|
Logger::SetProduct(boost::none);
|
||||||
|
time_points[3] = high_resolution_clock::now();
|
||||||
|
log_timepoints();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task_result_iterator_++;
|
||||||
|
native_task_result_iterator_++;
|
||||||
|
|
||||||
|
return (*task_result_iterator_)->product();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the representation of the current geometrical entity.
|
||||||
|
IfcGeom::Element* IfcGeom::Iterator::get()
|
||||||
|
{
|
||||||
|
if (!initialization_outcome_) {
|
||||||
|
throw std::runtime_error("Iterator not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ret = *task_result_iterator_;
|
||||||
|
|
||||||
|
// If we want to organize the element considering their hierarchy
|
||||||
|
if (settings_.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get()) {
|
||||||
|
// We are going to build a vector with the element parents.
|
||||||
|
// First, create the parent vector
|
||||||
|
std::vector<const IfcGeom::Element*> parents;
|
||||||
|
|
||||||
|
// if the element has a parent
|
||||||
|
if (ret->parent_id() != -1) {
|
||||||
|
const IfcGeom::Element* parent_object = NULL;
|
||||||
|
bool hasParent = true;
|
||||||
|
|
||||||
|
// get the parent
|
||||||
|
try {
|
||||||
|
parent_object = get_object(ret->parent_id());
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
Logger::Error(e);
|
||||||
|
hasParent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the previously found parent to the vector
|
||||||
|
if (hasParent) parents.insert(parents.begin(), parent_object);
|
||||||
|
|
||||||
|
// We need to find all the parents
|
||||||
|
while (parent_object != NULL && hasParent && parent_object->parent_id() != -1) {
|
||||||
|
// Find the next parent
|
||||||
|
try {
|
||||||
|
parent_object = get_object(parent_object->parent_id());
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
Logger::Error(e);
|
||||||
|
hasParent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the previously found parent to the vector
|
||||||
|
if (hasParent) parents.insert(parents.begin(), parent_object);
|
||||||
|
|
||||||
|
hasParent = hasParent && parent_object->parent_id() != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when done push the parent list in the Element object
|
||||||
|
ret->SetParents(parents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IfcGeom::Element* IfcGeom::Iterator::get_object(int id) {
|
||||||
|
ifcopenshell::geometry::taxonomy::matrix4::ptr m4;
|
||||||
|
int parent_id = -1;
|
||||||
|
std::string instance_type, product_name, product_guid;
|
||||||
|
IfcUtil::IfcBaseEntity* ifc_product = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ifc_product = ifc_file->instance_by_id(id)->as<IfcUtil::IfcBaseEntity>();
|
||||||
|
instance_type = ifc_product->declaration().name();
|
||||||
|
|
||||||
|
if (ifc_product->declaration().is("IfcRoot")) {
|
||||||
|
product_guid = (std::string)ifc_product->get("GlobalId");
|
||||||
|
product_name = ifc_product->get_value<std::string>("Name", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parent_object = converter_->mapping()->get_decomposing_entity(ifc_product);
|
||||||
|
if (parent_object) {
|
||||||
|
parent_id = parent_object->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
// fails in case of IfcProject
|
||||||
|
auto mapped = converter_->mapping()->map(ifc_product);
|
||||||
|
auto casted = mapped ? ifcopenshell::geometry::taxonomy::dcast<ifcopenshell::geometry::taxonomy::geom_item>(mapped) : nullptr;
|
||||||
|
|
||||||
|
if (casted) {
|
||||||
|
m4 = casted->matrix;
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
Logger::Error(e);
|
||||||
|
}
|
||||||
|
#ifdef IFOPSH_WITH_OPENCASCADE
|
||||||
|
catch (const Standard_Failure& e) {
|
||||||
|
if (e.GetMessageString() && strlen(e.GetMessageString())) {
|
||||||
|
Logger::Error(e.GetMessageString());
|
||||||
|
} else {
|
||||||
|
Logger::Error("Unknown error returning product");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
catch (...) {
|
||||||
|
Logger::Error("Unknown error returning product");
|
||||||
|
}
|
||||||
|
|
||||||
|
Element* ifc_object = new Element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product);
|
||||||
|
return ifc_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IfcUtil::IfcBaseClass* IfcGeom::Iterator::create() {
|
||||||
|
const IfcUtil::IfcBaseClass* product = nullptr;
|
||||||
|
try {
|
||||||
|
product = create_shape_model_for_next_entity();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
Logger::Error(e);
|
||||||
|
had_error_processing_elements_ = true;
|
||||||
|
}
|
||||||
|
#ifdef IFOPSH_WITH_OPENCASCADE
|
||||||
|
catch (const Standard_Failure& e) {
|
||||||
|
if (e.GetMessageString() && strlen(e.GetMessageString())) {
|
||||||
|
Logger::Error(e.GetMessageString());
|
||||||
|
} else {
|
||||||
|
Logger::Error("Unknown error creating geometry");
|
||||||
|
}
|
||||||
|
had_error_processing_elements_ = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
catch (...) {
|
||||||
|
Logger::Error("Unknown error creating geometry");
|
||||||
|
had_error_processing_elements_ = true;
|
||||||
|
}
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcGeom::Iterator::~Iterator() {
|
||||||
|
if (num_threads_ != 1) {
|
||||||
|
terminating_ = true;
|
||||||
|
|
||||||
|
if (init_future_.valid()) {
|
||||||
|
init_future_.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& k : kernel_pool) {
|
||||||
|
delete k;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task_result_ptr_initialized) {
|
||||||
|
while (task_result_iterator_ != --all_processed_elements_.end()) {
|
||||||
|
if (*native_task_result_iterator_ != *task_result_iterator_) {
|
||||||
|
delete* native_task_result_iterator_;
|
||||||
|
}
|
||||||
|
delete* task_result_iterator_++;
|
||||||
|
native_task_result_iterator_++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete converter_;
|
||||||
|
}
|
||||||
+67
-696
@@ -123,7 +123,6 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
std::mutex element_ready_mutex_;
|
std::mutex element_ready_mutex_;
|
||||||
bool task_result_ptr_initialized = false;
|
bool task_result_ptr_initialized = false;
|
||||||
// ?
|
|
||||||
size_t async_elements_returned_ = 0;
|
size_t async_elements_returned_ = 0;
|
||||||
size_t task_result_index_ = 0;
|
size_t task_result_index_ = 0;
|
||||||
|
|
||||||
@@ -155,354 +154,10 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
// Should not be destructed because, destructor is blocking
|
// Should not be destructed because, destructor is blocking
|
||||||
std::future<void> init_future_;
|
std::future<void> init_future_;
|
||||||
|
std::mutex caching_mutex_;
|
||||||
|
|
||||||
std::array<std::chrono::high_resolution_clock::time_point, 4> time_points;
|
std::array<std::chrono::high_resolution_clock::time_point, 4> time_points;
|
||||||
|
|
||||||
/// @todo public/private sections all over the place: move all public to the beginning of the class
|
|
||||||
public:
|
|
||||||
void set_cache(GeometrySerializer* cache) { cache_ = cache; }
|
|
||||||
|
|
||||||
const std::string& unit_name() const { return converter_->mapping()->get_length_unit_name(); }
|
|
||||||
double unit_magnitude() const { return converter_->mapping()->get_length_unit(); }
|
|
||||||
// Check if error occurred during iterator initialization or iteration over elements.
|
|
||||||
bool had_error_processing_elements() const { return had_error_processing_elements_; }
|
|
||||||
|
|
||||||
boost::optional<bool> initialization_outcome_;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns true if the iterator is initialized with any elements, false otherwise.
|
|
||||||
*
|
|
||||||
* @note
|
|
||||||
* - A true return value does not guarantee successful initialization of all elements.
|
|
||||||
* Some elements may have failed to initialize. Check had_error_processing_elements()
|
|
||||||
* to see whether there were errors during the initialization.
|
|
||||||
*
|
|
||||||
* - For non-concurrent iterators, a false return may occur if initialization of the first
|
|
||||||
* element fails, even if subsequent elements could be initialized successfully.
|
|
||||||
*/
|
|
||||||
bool initialize() {
|
|
||||||
using std::chrono::high_resolution_clock;
|
|
||||||
|
|
||||||
if (initialization_outcome_) {
|
|
||||||
return *initialization_outcome_;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_points[0] = high_resolution_clock::now();
|
|
||||||
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
|
|
||||||
if (num_threads_ != 1) {
|
|
||||||
// @todo this shouldn't be necessary with properly immutable taxonomy items
|
|
||||||
converter_->mapping()->use_caching() = false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
converter_->mapping()->get_representations(reps, filters_);
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
Logger::Error(e);
|
|
||||||
}
|
|
||||||
time_points[1] = high_resolution_clock::now();
|
|
||||||
|
|
||||||
for (auto& task : reps) {
|
|
||||||
geometry_conversion_result res;
|
|
||||||
res.index = task.index;
|
|
||||||
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
|
||||||
res.representation = task.representation;
|
|
||||||
res.products_2 = task.products;
|
|
||||||
} else {
|
|
||||||
res.item = converter_->mapping()->map(task.representation);
|
|
||||||
if (!res.item) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::transform(task.products->begin(), task.products->end(), std::back_inserter(res.products), [this, &res](IfcUtil::IfcBaseClass* prod) {
|
|
||||||
auto prod_item = converter_->mapping()->map(prod);
|
|
||||||
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tasks_.push_back(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() && settings_.get<ifcopenshell::geometry::settings::PermissiveShapeReuse>().get()) {
|
|
||||||
std::unordered_map<
|
|
||||||
ifcopenshell::geometry::taxonomy::item::ptr,
|
|
||||||
std::vector<std::pair<const IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::taxonomy::matrix4::ptr>>> folded;
|
|
||||||
|
|
||||||
for (auto& r : tasks_) {
|
|
||||||
auto i = r.item;
|
|
||||||
|
|
||||||
Eigen::Matrix4d m4 = Eigen::Matrix4d::Identity();
|
|
||||||
|
|
||||||
while (auto col = std::dynamic_pointer_cast<ifcopenshell::geometry::taxonomy::collection>(i)) {
|
|
||||||
if (col->children.size() == 1) {
|
|
||||||
if (col->matrix) {
|
|
||||||
m4 *= col->matrix->ccomponents();
|
|
||||||
}
|
|
||||||
i = col->children[0];
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& p : r.products) {
|
|
||||||
auto pl = ifcopenshell::geometry::taxonomy::matrix4::ptr(p.second->clone_());
|
|
||||||
pl->components() *= m4;
|
|
||||||
folded[i].push_back(
|
|
||||||
{ p.first, pl }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (folded.size() < tasks_.size()) {
|
|
||||||
auto old_size = tasks_.size();
|
|
||||||
tasks_.clear();
|
|
||||||
size_t i = 0;
|
|
||||||
for (auto& p : folded) {
|
|
||||||
tasks_.emplace_back();
|
|
||||||
tasks_.back().index = i++;
|
|
||||||
tasks_.back().item = p.first;
|
|
||||||
tasks_.back().products = p.second;
|
|
||||||
}
|
|
||||||
Logger::Notice("Merged " + std::to_string(old_size) + " tasks into " + std::to_string(tasks_.size()) + " tasks due to permissive shape reuse");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t num_products = 0;
|
|
||||||
for (auto& r : tasks_) {
|
|
||||||
num_products += !settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() ? r.products_2->size() : r.products.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
time_points[2] = high_resolution_clock::now();
|
|
||||||
|
|
||||||
/*
|
|
||||||
// What to do, map representation and product individually?
|
|
||||||
// There needs to be two options, mapped item respecting (does that still work?), and optimized based on topology sorting.
|
|
||||||
// Or is the sorting not necessary if we just cache?
|
|
||||||
|
|
||||||
std::vector<taxonomy::ptr> items;
|
|
||||||
std::map<taxonomy::ptr, taxonomy::matrix4> placements;
|
|
||||||
std::transform(products.begin(), products.end(), std::back_inserter(items), [this, &placements](IfcUtil::IfcBaseClass* p) {
|
|
||||||
auto item = converter_->mapping()->map(p);
|
|
||||||
// Product placements do not affect item reuse and should temporarily be swapped to identity
|
|
||||||
if (item) {
|
|
||||||
std::swap(placements[item], ((taxonomy::geom_ptr)item)->matrix);
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
items.erase(std::remove(items.begin(), items.end(), nullptr), items.end());
|
|
||||||
std::sort(items.begin(), items.end(), taxonomy::less);
|
|
||||||
auto it = items.begin();
|
|
||||||
while (it < items.end()) {
|
|
||||||
auto jt = std::upper_bound(it, items.end(), *it, taxonomy::less);
|
|
||||||
geometry_conversion_result r;
|
|
||||||
r.item = *it;
|
|
||||||
std::transform(it, jt, std::back_inserter(r.products), [&r, &placements](taxonomy::ptr product_node) {
|
|
||||||
return std::make_pair((IfcUtil::IfcBaseEntity*) product_node->instance, placements[product_node]);
|
|
||||||
});
|
|
||||||
tasks_.push_back(r);
|
|
||||||
it = jt;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Logger::Notice("Created " + boost::lexical_cast<std::string>(tasks_.size()) + " tasks for " + boost::lexical_cast<std::string>(num_products) + " products");
|
|
||||||
|
|
||||||
if (tasks_.size() == 0) {
|
|
||||||
Logger::Warning("No representations encountered, aborting");
|
|
||||||
initialization_outcome_.reset(false);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
task_iterator_ = tasks_.begin();
|
|
||||||
|
|
||||||
task_result_index_ = 0;
|
|
||||||
done = 0;
|
|
||||||
total = (int) tasks_.size();
|
|
||||||
|
|
||||||
if (num_threads_ != 1) {
|
|
||||||
init_future_ = std::async(std::launch::async, [this]() { process_concurrently(); });
|
|
||||||
|
|
||||||
// wait for the first element, because after init(), get() can be called.
|
|
||||||
// so the element conversion must succeed
|
|
||||||
initialization_outcome_ = wait_for_element();
|
|
||||||
} else {
|
|
||||||
initialization_outcome_ = create();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *initialization_outcome_;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t processed_ = 0;
|
|
||||||
|
|
||||||
void process_finished_rep(geometry_conversion_result* rep) {
|
|
||||||
if (rep->elements.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(element_ready_mutex_);
|
|
||||||
|
|
||||||
all_processed_elements_.insert(all_processed_elements_.end(), rep->elements.begin(), rep->elements.end());
|
|
||||||
all_processed_native_elements_.insert(all_processed_native_elements_.end(), rep->breps.begin(), rep->breps.end());
|
|
||||||
|
|
||||||
if (!task_result_ptr_initialized) {
|
|
||||||
task_result_iterator_ = all_processed_elements_.begin();
|
|
||||||
native_task_result_iterator_ = all_processed_native_elements_.begin();
|
|
||||||
task_result_ptr_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress_ = (int) (++processed_ * 100 / tasks_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void process_concurrently() {
|
|
||||||
size_t conc_threads = num_threads_;
|
|
||||||
if (conc_threads > tasks_.size()) {
|
|
||||||
conc_threads = tasks_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_pool.reserve(conc_threads);
|
|
||||||
for (unsigned i = 0; i < conc_threads; ++i) {
|
|
||||||
kernel_pool.push_back(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::future<geometry_conversion_result*>> threadpool;
|
|
||||||
|
|
||||||
for (auto& rep : tasks_) {
|
|
||||||
ifcopenshell::geometry::Converter* K = nullptr;
|
|
||||||
if (threadpool.size() < kernel_pool.size()) {
|
|
||||||
K = kernel_pool[threadpool.size()];
|
|
||||||
}
|
|
||||||
|
|
||||||
while (threadpool.size() == conc_threads) {
|
|
||||||
for (int i = 0; i < (int)threadpool.size(); i++) {
|
|
||||||
auto& fu = threadpool[i];
|
|
||||||
std::future_status status;
|
|
||||||
status = fu.wait_for(std::chrono::seconds(0));
|
|
||||||
if (status == std::future_status::ready) {
|
|
||||||
process_finished_rep(fu.get());
|
|
||||||
|
|
||||||
std::swap(threadpool[i], threadpool.back());
|
|
||||||
threadpool.pop_back();
|
|
||||||
std::swap(kernel_pool[i], kernel_pool.back());
|
|
||||||
K = kernel_pool.back();
|
|
||||||
break;
|
|
||||||
} // if
|
|
||||||
} // for
|
|
||||||
} // while
|
|
||||||
|
|
||||||
std::future<geometry_conversion_result*> fu = std::async(
|
|
||||||
std::launch::async, [this](
|
|
||||||
ifcopenshell::geometry::Converter* kernel,
|
|
||||||
ifcopenshell::geometry::Settings settings,
|
|
||||||
geometry_conversion_result* rep) {
|
|
||||||
// Catch exceptions to be safe from freezing the iterator.
|
|
||||||
try {
|
|
||||||
this->create_element_(kernel, settings, rep);
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
Logger::Error(
|
|
||||||
std::string("Exception '") + e.what() +
|
|
||||||
std::string("' occurred while iterator was creating a shape: "),
|
|
||||||
rep->item->instance
|
|
||||||
);
|
|
||||||
had_error_processing_elements_ = true;
|
|
||||||
} catch (...) {
|
|
||||||
Logger::Error(
|
|
||||||
"Unknown exception occurred while iteartor was creating a shape: ",
|
|
||||||
rep->item->instance
|
|
||||||
);
|
|
||||||
had_error_processing_elements_ = true;
|
|
||||||
}
|
|
||||||
return rep;
|
|
||||||
},
|
|
||||||
K,
|
|
||||||
std::ref(settings_),
|
|
||||||
&rep);
|
|
||||||
|
|
||||||
if (terminating_) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
threadpool.emplace_back(std::move(fu));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& fu : threadpool) {
|
|
||||||
process_finished_rep(fu.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
finished_ = true;
|
|
||||||
|
|
||||||
Logger::SetProduct(boost::none);
|
|
||||||
|
|
||||||
if (!terminating_) {
|
|
||||||
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(all_processed_elements_.size()) +
|
|
||||||
" objects) ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes model's bounding box (bounds_min and bounds_max).
|
|
||||||
/// @note Can take several minutes for large files.
|
|
||||||
void compute_bounds(bool with_geometry)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
bounds_min_.components()(i) = std::numeric_limits<double>::infinity();
|
|
||||||
bounds_max_.components()(i) = -std::numeric_limits<double>::infinity();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (with_geometry) {
|
|
||||||
size_t num_created = 0;
|
|
||||||
do {
|
|
||||||
IfcGeom::Element* geom_object = get();
|
|
||||||
const IfcGeom::TriangulationElement* o = static_cast<const IfcGeom::TriangulationElement*>(geom_object);
|
|
||||||
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
|
|
||||||
auto mat = o->transformation().data()->ccomponents();
|
|
||||||
Eigen::Vector4d vec, transformed;
|
|
||||||
|
|
||||||
for (typename std::vector<double>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end();) {
|
|
||||||
const double& x = *(it++);
|
|
||||||
const double& y = *(it++);
|
|
||||||
const double& z = *(it++);
|
|
||||||
vec << x, y, z, 1.;
|
|
||||||
transformed = mat * vec;
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
bounds_min_.components()(i) = std::min(bounds_min_.components()(i), transformed(i));
|
|
||||||
bounds_max_.components()(i) = std::max(bounds_max_.components()(i), transformed(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (++num_created, next());
|
|
||||||
} else {
|
|
||||||
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
|
|
||||||
converter_->mapping()->get_representations(reps, filters_);
|
|
||||||
|
|
||||||
std::vector<IfcUtil::IfcBaseClass*> products;
|
|
||||||
for (auto& r : reps) {
|
|
||||||
std::copy(r.products->begin(), r.products->end(), std::back_inserter(products));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& product : products) {
|
|
||||||
auto prod_item = converter_->mapping()->map(product);
|
|
||||||
auto vec = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix->translation_part();
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
bounds_min_.components()(i) = std::min(bounds_min_.components()(i), vec(i));
|
|
||||||
bounds_max_.components()(i) = std::max(bounds_max_.components()(i), vec(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int progress() const {
|
|
||||||
return progress_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getLog() const { return Logger::GetLog(); }
|
|
||||||
|
|
||||||
IfcParse::IfcFile* file() const { return ifc_file; }
|
|
||||||
|
|
||||||
const std::vector<IfcGeom::filter_t>& filters() const { return filters_; }
|
|
||||||
std::vector<IfcGeom::filter_t>& filters() { return filters_; }
|
|
||||||
|
|
||||||
const ifcopenshell::geometry::taxonomy::point3& bounds_min() const { return bounds_min_; }
|
|
||||||
const ifcopenshell::geometry::taxonomy::point3& bounds_max() const { return bounds_max_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::mutex caching_mutex_;
|
|
||||||
|
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
Element* decorate_with_cache_(GeometrySerializer::read_type rt, const std::string& product_guid, const std::string& representation_id, Fn f) {
|
Element* decorate_with_cache_(GeometrySerializer::read_type rt, const std::string& product_guid, const std::string& representation_id, Fn f) {
|
||||||
|
|
||||||
@@ -529,7 +184,7 @@ namespace IfcGeom {
|
|||||||
std::lock_guard<std::mutex> lk(caching_mutex_);
|
std::lock_guard<std::mutex> lk(caching_mutex_);
|
||||||
|
|
||||||
if (rt == GeometrySerializer::READ_TRIANGULATION) {
|
if (rt == GeometrySerializer::READ_TRIANGULATION) {
|
||||||
cache_->write((IfcGeom::TriangulationElement*) element);
|
cache_->write((IfcGeom::TriangulationElement*)element);
|
||||||
} else {
|
} else {
|
||||||
cache_->write((IfcGeom::BRepElement*)element);
|
cache_->write((IfcGeom::BRepElement*)element);
|
||||||
}
|
}
|
||||||
@@ -539,347 +194,24 @@ namespace IfcGeom {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IfcUtil::IfcBaseClass* create_shape_model_for_next_entity() {
|
const IfcUtil::IfcBaseClass* create_shape_model_for_next_entity();
|
||||||
geometry_conversion_result* task = nullptr;
|
|
||||||
for (; task_iterator_ < tasks_.end();) {
|
|
||||||
task = &*task_iterator_++;
|
|
||||||
create_element_(converter_, settings_, task);
|
|
||||||
if (task->elements.empty()) {
|
|
||||||
task = nullptr;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (task) {
|
|
||||||
process_finished_rep(task);
|
|
||||||
return task->item->instance->as<IfcUtil::IfcBaseClass>();
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_element_(
|
void create_element_(
|
||||||
ifcopenshell::geometry::Converter* kernel,
|
ifcopenshell::geometry::Converter* kernel,
|
||||||
ifcopenshell::geometry::Settings settings,
|
ifcopenshell::geometry::Settings settings,
|
||||||
geometry_conversion_result* rep)
|
geometry_conversion_result* rep);
|
||||||
{
|
|
||||||
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
|
||||||
rep->item = kernel->mapping()->map(rep->representation);
|
|
||||||
if (!rep->item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::transform(rep->products_2->begin(), rep->products_2->end(), std::back_inserter(rep->products), [this, &rep, kernel](IfcUtil::IfcBaseClass* prod) {
|
|
||||||
auto prod_item = kernel->mapping()->map(prod);
|
|
||||||
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
|
|
||||||
auto product_node = rep->products.front();
|
|
||||||
const IfcUtil::IfcBaseEntity* product = product_node.first;
|
|
||||||
const auto& place = product_node.second;
|
|
||||||
|
|
||||||
Logger::SetProduct(product);
|
|
||||||
|
|
||||||
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product, place, rep]() {
|
|
||||||
return kernel->create_brep_for_representation_and_product(rep->item, product, place);
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (!brep) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto elem = process_based_on_settings(settings, brep);
|
|
||||||
if (!elem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rep->breps = { brep };
|
|
||||||
rep->elements = { elem };
|
|
||||||
|
|
||||||
for (auto it = rep->products.begin() + 1; it != rep->products.end(); ++it) {
|
|
||||||
const auto& p = *it;
|
|
||||||
const IfcUtil::IfcBaseEntity* product2 = p.first;
|
|
||||||
const auto& place2 = p.second;
|
|
||||||
|
|
||||||
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product2, place2, brep]() {
|
|
||||||
return kernel->create_brep_for_processed_representation(product2, place2, brep);
|
|
||||||
}));
|
|
||||||
if (brep2) {
|
|
||||||
auto elem2 = process_based_on_settings(settings, brep2, dynamic_cast<IfcGeom::TriangulationElement*>(elem));
|
|
||||||
if (elem2) {
|
|
||||||
rep->breps.push_back(brep2);
|
|
||||||
rep->elements.push_back(elem2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IfcGeom::Element* process_based_on_settings(
|
IfcGeom::Element* process_based_on_settings(
|
||||||
ifcopenshell::geometry::Settings settings,
|
ifcopenshell::geometry::Settings settings,
|
||||||
IfcGeom::BRepElement* elem,
|
IfcGeom::BRepElement* elem,
|
||||||
IfcGeom::TriangulationElement* previous = nullptr)
|
IfcGeom::TriangulationElement* previous = nullptr);
|
||||||
{
|
|
||||||
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
|
|
||||||
try {
|
|
||||||
return new IfcGeom::SerializedElement(*elem);
|
|
||||||
} catch (...) {
|
|
||||||
Logger::Message(Logger::LOG_ERROR, "Getting a serialized element from model failed.");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
} else if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::TRIANGULATED) {
|
|
||||||
// the part before the hyphen is the representation id
|
|
||||||
auto gid2 = elem->geometry().id();
|
|
||||||
auto hyphen = gid2.find("-");
|
|
||||||
if (hyphen != std::string::npos) {
|
|
||||||
gid2 = gid2.substr(0, hyphen);
|
|
||||||
}
|
|
||||||
|
|
||||||
return decorate_with_cache_(GeometrySerializer::READ_TRIANGULATION, elem->guid(), gid2, [elem, previous]() {
|
bool wait_for_element();
|
||||||
try {
|
|
||||||
if (!previous) {
|
|
||||||
return new TriangulationElement(*elem);
|
|
||||||
} else {
|
|
||||||
return new TriangulationElement(*elem, previous->geometry_pointer());
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
Logger::Message(Logger::LOG_ERROR, "Getting a triangulation element from model failed.");
|
|
||||||
}
|
|
||||||
return (TriangulationElement*)nullptr;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wait_for_element() {
|
void log_timepoints() const;
|
||||||
while (true) {
|
|
||||||
size_t s;
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lk(element_ready_mutex_);
|
|
||||||
s = all_processed_elements_.size();
|
|
||||||
}
|
|
||||||
if (s > async_elements_returned_) {
|
|
||||||
++async_elements_returned_;
|
|
||||||
return true;
|
|
||||||
} else if (finished_) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_timepoints() const {
|
|
||||||
using std::chrono::high_resolution_clock;
|
|
||||||
using std::chrono::duration;
|
|
||||||
using namespace std::string_literals;
|
|
||||||
|
|
||||||
std::array<std::string, 3> labels = {
|
|
||||||
"Initializing mapping"s,
|
|
||||||
"Performing mapping"s,
|
|
||||||
"Geometry interpretation"s
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto it = time_points.begin() + 1; it != time_points.end(); ++it) {
|
|
||||||
auto jt = it - 1;
|
|
||||||
duration<double, std::milli> ms_double = (*it) - (*jt);
|
|
||||||
Logger::Notice(labels[std::distance(time_points.begin(), jt)] + " took " + std::to_string(ms_double.count()) + "ms");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// @todo public/private sections all over the place: move all public to the beginning of the class
|
||||||
public:
|
public:
|
||||||
/// Returns what would be the product for the next shape representation
|
|
||||||
/// @todo Double-check and test the impl.
|
|
||||||
//IfcSchema::IfcProduct* peek_next() const
|
|
||||||
//{
|
|
||||||
// if (ifcproducts && ifcproduct_iterator + 1 != ifcproducts->end()){
|
|
||||||
// return *(ifcproduct_iterator + 1);
|
|
||||||
// } else {
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// @todo Would this be as simple as the following code?
|
|
||||||
//void skip_next() { if (ifcproducts) { ++ifcproduct_iterator; } }
|
|
||||||
|
|
||||||
/// Moves to the next shape representation, create its geometry, and returns the associated product.
|
|
||||||
/// Use get() to retrieve the created geometry.
|
|
||||||
const IfcUtil::IfcBaseClass* next() {
|
|
||||||
using std::chrono::high_resolution_clock;
|
|
||||||
|
|
||||||
if (*native_task_result_iterator_ != *task_result_iterator_) {
|
|
||||||
delete* native_task_result_iterator_;
|
|
||||||
}
|
|
||||||
delete *task_result_iterator_;
|
|
||||||
|
|
||||||
if (num_threads_ != 1) {
|
|
||||||
if (!wait_for_element()) {
|
|
||||||
Logger::SetProduct(boost::none);
|
|
||||||
time_points[3] = high_resolution_clock::now();
|
|
||||||
log_timepoints();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
task_result_iterator_++;
|
|
||||||
native_task_result_iterator_++;
|
|
||||||
|
|
||||||
return (*task_result_iterator_)->product();
|
|
||||||
} else {
|
|
||||||
// Increment the iterator over the list of products using the current
|
|
||||||
// shape representation
|
|
||||||
if (task_result_iterator_ == --all_processed_elements_.end()) {
|
|
||||||
if (!create()) {
|
|
||||||
Logger::SetProduct(boost::none);
|
|
||||||
time_points[3] = high_resolution_clock::now();
|
|
||||||
log_timepoints();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task_result_iterator_++;
|
|
||||||
native_task_result_iterator_++;
|
|
||||||
|
|
||||||
return (*task_result_iterator_)->product();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the representation of the current geometrical entity.
|
|
||||||
Element* get()
|
|
||||||
{
|
|
||||||
if (!initialization_outcome_) {
|
|
||||||
throw std::runtime_error("Iterator not initialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ret = *task_result_iterator_;
|
|
||||||
|
|
||||||
// If we want to organize the element considering their hierarchy
|
|
||||||
if (settings_.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get())
|
|
||||||
{
|
|
||||||
// We are going to build a vector with the element parents.
|
|
||||||
// First, create the parent vector
|
|
||||||
std::vector<const IfcGeom::Element*> parents;
|
|
||||||
|
|
||||||
// if the element has a parent
|
|
||||||
if (ret->parent_id() != -1)
|
|
||||||
{
|
|
||||||
const IfcGeom::Element* parent_object = NULL;
|
|
||||||
bool hasParent = true;
|
|
||||||
|
|
||||||
// get the parent
|
|
||||||
try {
|
|
||||||
parent_object = get_object(ret->parent_id());
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
Logger::Error(e);
|
|
||||||
hasParent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the previously found parent to the vector
|
|
||||||
if (hasParent) parents.insert(parents.begin(), parent_object);
|
|
||||||
|
|
||||||
// We need to find all the parents
|
|
||||||
while (parent_object != NULL && hasParent && parent_object->parent_id() != -1)
|
|
||||||
{
|
|
||||||
// Find the next parent
|
|
||||||
try {
|
|
||||||
parent_object = get_object(parent_object->parent_id());
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
Logger::Error(e);
|
|
||||||
hasParent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the previously found parent to the vector
|
|
||||||
if (hasParent) parents.insert(parents.begin(), parent_object);
|
|
||||||
|
|
||||||
hasParent = hasParent && parent_object->parent_id() != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// when done push the parent list in the Element object
|
|
||||||
ret->SetParents(parents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the native (Open Cascade or CGAL) representation of the current geometrical entity.
|
|
||||||
BRepElement* get_native()
|
|
||||||
{
|
|
||||||
return *native_task_result_iterator_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Element* get_object(int id) {
|
|
||||||
ifcopenshell::geometry::taxonomy::matrix4::ptr m4;
|
|
||||||
int parent_id = -1;
|
|
||||||
std::string instance_type, product_name, product_guid;
|
|
||||||
IfcUtil::IfcBaseEntity* ifc_product = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ifc_product = ifc_file->instance_by_id(id)->as<IfcUtil::IfcBaseEntity>();
|
|
||||||
instance_type = ifc_product->declaration().name();
|
|
||||||
|
|
||||||
if (ifc_product->declaration().is("IfcRoot")) {
|
|
||||||
product_guid = (std::string) ifc_product->get("GlobalId");
|
|
||||||
product_name = ifc_product->get_value<std::string>("Name", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto parent_object = converter_->mapping()->get_decomposing_entity(ifc_product);
|
|
||||||
if (parent_object) {
|
|
||||||
parent_id = parent_object->id();
|
|
||||||
}
|
|
||||||
|
|
||||||
// fails in case of IfcProject
|
|
||||||
auto mapped = converter_->mapping()->map(ifc_product);
|
|
||||||
auto casted = mapped ? ifcopenshell::geometry::taxonomy::dcast<ifcopenshell::geometry::taxonomy::geom_item>(mapped) : nullptr;
|
|
||||||
|
|
||||||
if (casted) {
|
|
||||||
m4 = casted->matrix;
|
|
||||||
}
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
Logger::Error(e);
|
|
||||||
}
|
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
|
||||||
catch (const Standard_Failure& e) {
|
|
||||||
if (e.GetMessageString() && strlen(e.GetMessageString())) {
|
|
||||||
Logger::Error(e.GetMessageString());
|
|
||||||
} else {
|
|
||||||
Logger::Error("Unknown error returning product");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
catch (...) {
|
|
||||||
Logger::Error("Unknown error returning product");
|
|
||||||
}
|
|
||||||
|
|
||||||
Element* ifc_object = new Element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product);
|
|
||||||
return ifc_object;
|
|
||||||
}
|
|
||||||
|
|
||||||
const IfcUtil::IfcBaseClass* create() {
|
|
||||||
const IfcUtil::IfcBaseClass* product = nullptr;
|
|
||||||
try {
|
|
||||||
product = create_shape_model_for_next_entity();
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
Logger::Error(e);
|
|
||||||
had_error_processing_elements_ = true;
|
|
||||||
}
|
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
|
||||||
catch (const Standard_Failure& e) {
|
|
||||||
if (e.GetMessageString() && strlen(e.GetMessageString())) {
|
|
||||||
Logger::Error(e.GetMessageString());
|
|
||||||
} else {
|
|
||||||
Logger::Error("Unknown error creating geometry");
|
|
||||||
}
|
|
||||||
had_error_processing_elements_ = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
catch (...) {
|
|
||||||
Logger::Error("Unknown error creating geometry");
|
|
||||||
had_error_processing_elements_ = true;
|
|
||||||
}
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
|
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
|
||||||
: settings_(settings)
|
: settings_(settings)
|
||||||
, ifc_file(file)
|
, ifc_file(file)
|
||||||
@@ -927,31 +259,70 @@ namespace IfcGeom {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~Iterator() {
|
~Iterator();
|
||||||
if (num_threads_ != 1) {
|
|
||||||
terminating_ = true;
|
|
||||||
|
|
||||||
if (init_future_.valid()) {
|
void set_cache(GeometrySerializer* cache) { cache_ = cache; }
|
||||||
init_future_.wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& k : kernel_pool) {
|
const std::string& unit_name() const { return converter_->mapping()->get_length_unit_name(); }
|
||||||
delete k;
|
double unit_magnitude() const { return converter_->mapping()->get_length_unit(); }
|
||||||
}
|
// Check if error occurred during iterator initialization or iteration over elements.
|
||||||
|
bool had_error_processing_elements() const { return had_error_processing_elements_; }
|
||||||
|
|
||||||
if (task_result_ptr_initialized) {
|
boost::optional<bool> initialization_outcome_;
|
||||||
while (task_result_iterator_ != --all_processed_elements_.end()) {
|
|
||||||
if (*native_task_result_iterator_ != *task_result_iterator_) {
|
|
||||||
delete* native_task_result_iterator_;
|
|
||||||
}
|
|
||||||
delete *task_result_iterator_++;
|
|
||||||
native_task_result_iterator_++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete converter_;
|
/**
|
||||||
|
* @return Returns true if the iterator is initialized with any elements, false otherwise.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* - A true return value does not guarantee successful initialization of all elements.
|
||||||
|
* Some elements may have failed to initialize. Check had_error_processing_elements()
|
||||||
|
* to see whether there were errors during the initialization.
|
||||||
|
*
|
||||||
|
* - For non-concurrent iterators, a false return may occur if initialization of the first
|
||||||
|
* element fails, even if subsequent elements could be initialized successfully.
|
||||||
|
*/
|
||||||
|
bool initialize();
|
||||||
|
|
||||||
|
size_t processed_ = 0;
|
||||||
|
|
||||||
|
void process_finished_rep(geometry_conversion_result* rep);
|
||||||
|
|
||||||
|
void process_concurrently();
|
||||||
|
|
||||||
|
/// Computes model's bounding box (bounds_min and bounds_max).
|
||||||
|
/// @note Can take several minutes for large files.
|
||||||
|
void compute_bounds(bool with_geometry);
|
||||||
|
|
||||||
|
int progress() const {
|
||||||
|
return progress_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getLog() const { return Logger::GetLog(); }
|
||||||
|
|
||||||
|
IfcParse::IfcFile* file() const { return ifc_file; }
|
||||||
|
|
||||||
|
const std::vector<IfcGeom::filter_t>& filters() const { return filters_; }
|
||||||
|
std::vector<IfcGeom::filter_t>& filters() { return filters_; }
|
||||||
|
|
||||||
|
const ifcopenshell::geometry::taxonomy::point3& bounds_min() const { return bounds_min_; }
|
||||||
|
const ifcopenshell::geometry::taxonomy::point3& bounds_max() const { return bounds_max_; }
|
||||||
|
|
||||||
|
/// Moves to the next shape representation, create its geometry, and returns the associated product.
|
||||||
|
/// Use get() to retrieve the created geometry.
|
||||||
|
const IfcUtil::IfcBaseClass* next();
|
||||||
|
|
||||||
|
/// Gets the representation of the current geometrical entity.
|
||||||
|
Element* get();
|
||||||
|
|
||||||
|
/// Gets the native (Open Cascade or CGAL) representation of the current geometrical entity.
|
||||||
|
BRepElement* get_native()
|
||||||
|
{
|
||||||
|
return *native_task_result_iterator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Element* get_object(int id);
|
||||||
|
|
||||||
|
const IfcUtil::IfcBaseClass* create();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
Submodule src/svgfill updated: 0ebff78309...37448e9ba5
Reference in New Issue
Block a user