diff --git a/src/ifcclash/README.md b/src/ifcclash/README.md new file mode 100644 index 0000000000..7a46078732 --- /dev/null +++ b/src/ifcclash/README.md @@ -0,0 +1,115 @@ +# ifcclash + +`ifcclash` is both a CLI utility and library that lets you perform clash +detections on and between IFC files. + +## Installation + +`ifcclash` depends on +[`hppfcl`](https://github.com/humanoid-path-planner/hpp-fcl) and optionally +[`bcf`](https://github.com/IfcOpenShell/IfcOpenShell/tree/v0.6.0/src/bcf). Once +you have the dependencies, the `ifcclash` directory may be added to your Python +site packages like any other Python module. You can run it as a CLI like: + +``` +$ python -m ifcclash +``` + +If you want something more Unix-like ... + +``` +$ alias ifcclash='python -m ifcclash' +``` + +## Usage + +Instructions on what clashes to perform are structured in terms of clash sets. +Each clash set contains instructions of collisions that we want to perform, and +can be named so it is easy to distinguish. A typical name would be "Structure +and Pipes", to describe that we are are detecting collisions between structural +elements and pipes. + +Each clash set may include two groups of objects, named `A` and `B`. This tells +IfcClash to attempt to find collisions between any object in group `A` with any +object in group `B`. Group `A` is mandatory, but group `B` is optional. If group +`B` is not provided, IfcClash will detect all clashes within objects of group +`A`. + +Within group `A` or `B`, you may be define one or more data sources of objects. +A data source must include a path to the IFC file which the objects come from. +You may also optionally provide a filter to only include or exclude certain +objects. If no filter is provided, then all objects will be used to detect +collisions. + +Here's a sample JSON description of a single clash set, with both groups +defined with data sources. + +```json +[ + { + "name": "Clash Set A", + "a": [ + { + "file": "/path/to/one.ifc" + } + ], + "b": [ + { + "file": "/path/to/two.ifc" + "selector": ".IfcWall", + "mode": "i" + } + ] + }, + ... +] +``` + +Once your have your JSON description of your clashes, usage is like any other +CLI app. + +``` +$ ifcclash -h + +usage: __main__.py [-h] [-o OUTPUT] input + +Clashes geometry between two IFC files + +positional arguments: + input A JSON dataset describing a series of clashsets + +optional arguments: + -h, --help show this help message and exit + -o OUTPUT, --output OUTPUT + The JSON diff file to output. Defaults to output.json +``` + +In it simplest form, just present your JSON file. + +``` +$ ifcclash clash_sets.json +$ cat output.json +``` + +You can also use it as a library. + +```python +import sys +import json +import logging +import ifcclash + + +settings = ClashSettings() +settings.output = "output.json" +settings.logger = logging.getLogger("Clash") +settings.logger.setLevel(logging.DEBUG) +handler = logging.StreamHandler(sys.stdout) +handler.setLevel(logging.DEBUG) +settings.logger.addHandler(handler) +ifc_clasher = Clasher(settings) +with open(args.input, "r") as clash_sets_file: + ifc_clasher.clash_sets = json.loads(clash_sets_file.read()) +ifc_clasher.clash() +ifc_clasher.export() +``` diff --git a/src/ifcclash/ifcclash/__init__.py b/src/ifcclash/ifcclash/__init__.py new file mode 100644 index 0000000000..da77a5d72d --- /dev/null +++ b/src/ifcclash/ifcclash/__init__.py @@ -0,0 +1,31 @@ +import sys +import json +import logging +import argparse +from .ifcclash import Clasher, ClashSettings + + +def main(): + parser = argparse.ArgumentParser(description="Clashes geometry between two IFC files") + parser.add_argument("input", type=str, help="A JSON dataset describing a series of clashsets") + parser.add_argument( + "-o", "--output", type=str, help="The JSON diff file to output. Defaults to output.json", default="output.json" + ) + args = parser.parse_args() + + settings = ClashSettings() + settings.output = args.output + settings.logger = logging.getLogger("Clash") + settings.logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler(sys.stdout) + handler.setLevel(logging.DEBUG) + settings.logger.addHandler(handler) + ifc_clasher = Clasher(settings) + with open(args.input, "r") as clash_sets_file: + ifc_clasher.clash_sets = json.loads(clash_sets_file.read()) + ifc_clasher.clash() + ifc_clasher.export() + + +if __name__ == "__main__": + main() diff --git a/src/ifcclash/ifcclash/__main__.py b/src/ifcclash/ifcclash/__main__.py new file mode 100644 index 0000000000..0923453d15 --- /dev/null +++ b/src/ifcclash/ifcclash/__main__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 +import ifcclash + +ifcclash.main() diff --git a/src/ifcclash/ifcclash/ifcclash.py b/src/ifcclash/ifcclash/ifcclash.py index 89baee1b5b..76f22e668c 100644 --- a/src/ifcclash/ifcclash/ifcclash.py +++ b/src/ifcclash/ifcclash/ifcclash.py @@ -265,25 +265,3 @@ class ClashSettings: def __init__(self): self.logger = None self.output = "clashes.json" - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Clashes geometry between two IFC files") - parser.add_argument("input", type=str, help="A JSON dataset describing a series of clashsets") - parser.add_argument( - "-o", "--output", type=str, help="The JSON diff file to output. Defaults to output.json", default="output.json" - ) - args = parser.parse_args() - - settings = ClashSettings() - settings.output = args.output - settings.logger = logging.getLogger("Clash") - settings.logger.setLevel(logging.DEBUG) - handler = logging.StreamHandler(sys.stdout) - handler.setLevel(logging.DEBUG) - settings.logger.addHandler(handler) - ifc_clasher = Clasher(settings) - with open(args.input, "r") as clash_sets_file: - ifc_clasher.clash_sets = json.loads(clash_sets_file.read()) - ifc_clasher.clash() - ifc_clasher.export() diff --git a/src/ifcpatch/README.md b/src/ifcpatch/README.md index bf26bcea88..3be1198fed 100644 --- a/src/ifcpatch/README.md +++ b/src/ifcpatch/README.md @@ -59,8 +59,10 @@ $ ifcpatch -i input.ifc -o output.ifc -r ExtractElements -a ".IfcWall" You can also use it as a library. -``` +```python import ifcpatch + + ifcpatch.execute({ "input": "input.ifc", "output": "output.ifc",