ocga-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ocga_cli-0.1.0/LICENSE +21 -0
- ocga_cli-0.1.0/MANIFEST.in +18 -0
- ocga_cli-0.1.0/PKG-INFO +85 -0
- ocga_cli-0.1.0/README.md +63 -0
- ocga_cli-0.1.0/docs/OCGA.md +156 -0
- ocga_cli-0.1.0/docs/ocga_samples/alexander_column-rewrite.osm +790 -0
- ocga_cli-0.1.0/docs/ocga_samples/alexander_column.ocga +151 -0
- ocga_cli-0.1.0/docs/ocga_samples/alexander_column.osm +36 -0
- ocga_cli-0.1.0/docs/ocga_samples/church_at_the_kaluga_gate-rewrite.osm +752 -0
- ocga_cli-0.1.0/docs/ocga_samples/church_at_the_kaluga_gate.ocga +93 -0
- ocga_cli-0.1.0/docs/ocga_samples/church_at_the_kaluga_gate.osm +85 -0
- ocga_cli-0.1.0/docs/ocga_samples/church_of_st_louis-rewrite.osm +994 -0
- ocga_cli-0.1.0/docs/ocga_samples/church_of_st_louis.ocga +190 -0
- ocga_cli-0.1.0/docs/ocga_samples/church_of_st_louis.osm +89 -0
- ocga_cli-0.1.0/docs/ocga_samples/danilov_belltower.ocga +106 -0
- ocga_cli-0.1.0/docs/ocga_samples/danilov_belltower.osm +90 -0
- ocga_cli-0.1.0/docs/ocga_samples/gorky_park_entrance-rewrite.osm +2574 -0
- ocga_cli-0.1.0/docs/ocga_samples/gorky_park_entrance.ocga +193 -0
- ocga_cli-0.1.0/docs/ocga_samples/gorky_park_entrance.osm +65 -0
- ocga_cli-0.1.0/docs/ocga_samples/gorky_park_rotunda-rewrite.osm +949 -0
- ocga_cli-0.1.0/docs/ocga_samples/gorky_park_rotunda.ocga +86 -0
- ocga_cli-0.1.0/docs/ocga_samples/gorky_park_rotunda.osm +43 -0
- ocga_cli-0.1.0/docs/ocga_samples/komsomolskaya_station-rewrite.osm +3812 -0
- ocga_cli-0.1.0/docs/ocga_samples/komsomolskaya_station.ocga +231 -0
- ocga_cli-0.1.0/docs/ocga_samples/komsomolskaya_station.osm +74 -0
- ocga_cli-0.1.0/docs/ocga_samples/main_cathedral_of_russian_army-rewrite.osm +1524 -0
- ocga_cli-0.1.0/docs/ocga_samples/main_cathedral_of_russian_army.ocga +255 -0
- ocga_cli-0.1.0/docs/ocga_samples/main_cathedral_of_russian_army.osm +90 -0
- ocga_cli-0.1.0/docs/ocga_samples/moscow_manege-rewrite.osm +10158 -0
- ocga_cli-0.1.0/docs/ocga_samples/moscow_manege.ocga +98 -0
- ocga_cli-0.1.0/docs/ocga_samples/moscow_manege.osm +114 -0
- ocga_cli-0.1.0/docs/ocga_samples/novokuznetskaya-rewrite.osm +1260 -0
- ocga_cli-0.1.0/docs/ocga_samples/novokuznetskaya.ocga +86 -0
- ocga_cli-0.1.0/docs/ocga_samples/novokuznetskaya.osm +70 -0
- ocga_cli-0.1.0/docs/ocga_samples/rossi_pavilion.ocga +279 -0
- ocga_cli-0.1.0/docs/ocga_samples/rossi_pavilion.osm +58 -0
- ocga_cli-0.1.0/docs/ocga_samples/tsaritsino_rotunda-rewrite.osm +4197 -0
- ocga_cli-0.1.0/docs/ocga_samples/tsaritsino_rotunda.ocga +149 -0
- ocga_cli-0.1.0/docs/ocga_samples/tsaritsino_rotunda.osm +51 -0
- ocga_cli-0.1.0/example.bat +24 -0
- ocga_cli-0.1.0/example.sh +18 -0
- ocga_cli-0.1.0/pyproject.toml +37 -0
- ocga_cli-0.1.0/setup.cfg +4 -0
- ocga_cli-0.1.0/src/ocga/__init__.py +8 -0
- ocga_cli-0.1.0/src/ocga/cli.py +26 -0
- ocga_cli-0.1.0/src/ocga/mdlMisc.py +269 -0
- ocga_cli-0.1.0/src/ocga/mdlOsmParser.py +486 -0
- ocga_cli-0.1.0/src/ocga/ocga_engine.py +1590 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/__init__.py +7 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/main.py +228 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocga.g4 +175 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocga.interp +174 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocga.tokens +139 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocgaLexer.interp +233 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocgaLexer.py +361 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocgaLexer.tokens +139 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocgaListener.py +189 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocgaParser.py +2240 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/ocgaVisitor.py +60 -0
- ocga_cli-0.1.0/src/ocga/ocgaparser/rebuild_parser.bat +2 -0
- ocga_cli-0.1.0/src/ocga/osmparser/__init__.py +9 -0
- ocga_cli-0.1.0/src/ocga/osmparser/main.py +85 -0
- ocga_cli-0.1.0/src/ocga/osmparser/mdlXmlParser.py +64 -0
- ocga_cli-0.1.0/src/ocga/osmparser/osmGeometry.py +439 -0
- ocga_cli-0.1.0/src/ocga_cli.egg-info/PKG-INFO +85 -0
- ocga_cli-0.1.0/src/ocga_cli.egg-info/SOURCES.txt +69 -0
- ocga_cli-0.1.0/src/ocga_cli.egg-info/dependency_links.txt +1 -0
- ocga_cli-0.1.0/src/ocga_cli.egg-info/entry_points.txt +2 -0
- ocga_cli-0.1.0/src/ocga_cli.egg-info/requires.txt +1 -0
- ocga_cli-0.1.0/src/ocga_cli.egg-info/top_level.txt +1 -0
- ocga_cli-0.1.0/tests/test_main.py +87 -0
ocga_cli-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Zkir
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Include essential documentation, license, and example files
|
|
2
|
+
include README.md
|
|
3
|
+
include LICENSE
|
|
4
|
+
include example.bat
|
|
5
|
+
include example.sh
|
|
6
|
+
|
|
7
|
+
# Recursively include the source code directory
|
|
8
|
+
graft src
|
|
9
|
+
|
|
10
|
+
# include tests and docs. Not that tests require samples in the doc foloder
|
|
11
|
+
graft docs
|
|
12
|
+
graft tests
|
|
13
|
+
|
|
14
|
+
# Exclude generated output from the docs folder
|
|
15
|
+
prune docs/ocga_output
|
|
16
|
+
|
|
17
|
+
global-exclude *.py[co]
|
|
18
|
+
global-exclude __pycache__
|
ocga_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ocga-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A procedural modeling engine for OpenStreetMap building generation.
|
|
5
|
+
Author-email: Zkir <zkir@zkir.ru>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Zkir/ocga
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/Zkir/ocga/issues
|
|
9
|
+
Project-URL: Documentation, https://github.com/Zkir/ocga/blob/main/docs/OCGA.md
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
14
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: antlr4-python3-runtime
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# OCGA: Procedural 3D Buildings for OpenStreetMap
|
|
24
|
+
|
|
25
|
+
Creating detailed [3D buildings](https://wiki.openstreetmap.org/wiki/Simple_3D_Buildings) in OSM by manually adding **building:part's** and moving nodes back and forth is tedious and slow.
|
|
26
|
+
|
|
27
|
+
OCGA (OSM Computer-Generated Architecture) is built on a key insight: much like music, architecture is often based on the **repetition of common elements and patterns**.
|
|
28
|
+
|
|
29
|
+
Because architecture is inherently rule-based, we can leverage a different approach: **procedural generation**. Instead of building models by hand, you define these architectural patterns using a simple `.ocga` language, and let the engine execute the repetitive work of generating the complex geometry for you.
|
|
30
|
+
|
|
31
|
+
To achieve this, we have developed a new, unique domain-specific language: **OCGA**. This project provides both the **[OCGA language specification](https://github.com/Zkir/ocga/blob/main/docs/OCGA.md)** and a simple **command-line tool** that interprets this new language, enabling rapid creation of detailed building models.
|
|
32
|
+
|
|
33
|
+
While certain ideas were adopted from ESRI's CityEngine, OCGA is not its clone, and many things are implemented differently.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Install the package from PyPI:
|
|
39
|
+
```bash
|
|
40
|
+
pip install ocga
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Workflow
|
|
44
|
+
|
|
45
|
+
The intended cycle for using OCGA is as follows:
|
|
46
|
+
|
|
47
|
+
1. **Create an Outline:** Start by saving a building's footprint/outline into its own `.osm` file.
|
|
48
|
+
|
|
49
|
+
2. **Define the Rules:** Write a corresponding `.ocga` rules file tailored to that building's architecture. This is where you describe how to procedurally generate the model's parts.
|
|
50
|
+
|
|
51
|
+
3. **Generate the Model:** Run the `ocga` command-line tool, providing it with your outline and rules files.
|
|
52
|
+
```bash
|
|
53
|
+
ocga -i <path/to/your_building.osm> -r <path/to/your_rules.ocga> -o <path/to/generated_model.osm>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
4. **Verify Before Uploading!** Before you upload the data to OpenStreetMap, it is **crucial** to visually inspect the generated model.
|
|
57
|
+
- **Primary Method (JOSM):** The easiest way is to open the generated `.osm` file in JOSM and use the **[UrbanEye3D](https://wiki.openstreetmap.org/wiki/JOSM/Plugins/Urban_Eye_3D)** plugin viewer.
|
|
58
|
+
- **Alternative Method:** You can use `osm2world` to export the model to a `.gltf` file, which can then be opened in any standard 3D viewer (like the built-in Windows 3D Viewer or `f3d` on Linux).
|
|
59
|
+
|
|
60
|
+
5. **Upload to OpenStreetMap:** Once you are satisfied, you can upload the data from JOSM. You may need to merge the layer containing the generated model with your main data layer before uploading.
|
|
61
|
+
|
|
62
|
+
## Usage as a Library
|
|
63
|
+
|
|
64
|
+
While the primary use case for OCGA is the command-line tool, its core engine can be imported and used directly in your own Python projects, as permitted by the MIT license.
|
|
65
|
+
|
|
66
|
+
The main entry point function is `ocga_process2`, which can be imported from the top-level package. Its function is analogous to the CLI tool:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from ocga import ocga_process2
|
|
70
|
+
|
|
71
|
+
input_file = "path/to/building.osm"
|
|
72
|
+
rules_file = "path/to/rules.ocga"
|
|
73
|
+
output_file = "path/to/generated.osm"
|
|
74
|
+
|
|
75
|
+
# The other arguments are optional
|
|
76
|
+
ocga_process2(input_file, output_file, rules_file)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Other functions from the engine modules (e.g., from `ocga.ocga_engine`) can also be imported, but their APIs are not guaranteed to be stable and may change. Use them at your own risk.
|
|
80
|
+
|
|
81
|
+
## Language and Examples
|
|
82
|
+
|
|
83
|
+
- For a complete guide to the syntax and operations, see the **[OCGA Language Reference](https://github.com/Zkir/ocga/blob/main/docs/OCGA.md)**.
|
|
84
|
+
- A collection of sample `.osm` and `.ocga` files can be found in the **[docs/ocga_samples](https://github.com/Zkir/ocga/tree/main/docs/ocga_samples)** directory.
|
|
85
|
+
- The `example.bat` and `example.sh` scripts in the root directory demonstrate how to run the tool on these samples.
|
ocga_cli-0.1.0/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# OCGA: Procedural 3D Buildings for OpenStreetMap
|
|
2
|
+
|
|
3
|
+
Creating detailed [3D buildings](https://wiki.openstreetmap.org/wiki/Simple_3D_Buildings) in OSM by manually adding **building:part's** and moving nodes back and forth is tedious and slow.
|
|
4
|
+
|
|
5
|
+
OCGA (OSM Computer-Generated Architecture) is built on a key insight: much like music, architecture is often based on the **repetition of common elements and patterns**.
|
|
6
|
+
|
|
7
|
+
Because architecture is inherently rule-based, we can leverage a different approach: **procedural generation**. Instead of building models by hand, you define these architectural patterns using a simple `.ocga` language, and let the engine execute the repetitive work of generating the complex geometry for you.
|
|
8
|
+
|
|
9
|
+
To achieve this, we have developed a new, unique domain-specific language: **OCGA**. This project provides both the **[OCGA language specification](https://github.com/Zkir/ocga/blob/main/docs/OCGA.md)** and a simple **command-line tool** that interprets this new language, enabling rapid creation of detailed building models.
|
|
10
|
+
|
|
11
|
+
While certain ideas were adopted from ESRI's CityEngine, OCGA is not its clone, and many things are implemented differently.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
Install the package from PyPI:
|
|
17
|
+
```bash
|
|
18
|
+
pip install ocga
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
The intended cycle for using OCGA is as follows:
|
|
24
|
+
|
|
25
|
+
1. **Create an Outline:** Start by saving a building's footprint/outline into its own `.osm` file.
|
|
26
|
+
|
|
27
|
+
2. **Define the Rules:** Write a corresponding `.ocga` rules file tailored to that building's architecture. This is where you describe how to procedurally generate the model's parts.
|
|
28
|
+
|
|
29
|
+
3. **Generate the Model:** Run the `ocga` command-line tool, providing it with your outline and rules files.
|
|
30
|
+
```bash
|
|
31
|
+
ocga -i <path/to/your_building.osm> -r <path/to/your_rules.ocga> -o <path/to/generated_model.osm>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
4. **Verify Before Uploading!** Before you upload the data to OpenStreetMap, it is **crucial** to visually inspect the generated model.
|
|
35
|
+
- **Primary Method (JOSM):** The easiest way is to open the generated `.osm` file in JOSM and use the **[UrbanEye3D](https://wiki.openstreetmap.org/wiki/JOSM/Plugins/Urban_Eye_3D)** plugin viewer.
|
|
36
|
+
- **Alternative Method:** You can use `osm2world` to export the model to a `.gltf` file, which can then be opened in any standard 3D viewer (like the built-in Windows 3D Viewer or `f3d` on Linux).
|
|
37
|
+
|
|
38
|
+
5. **Upload to OpenStreetMap:** Once you are satisfied, you can upload the data from JOSM. You may need to merge the layer containing the generated model with your main data layer before uploading.
|
|
39
|
+
|
|
40
|
+
## Usage as a Library
|
|
41
|
+
|
|
42
|
+
While the primary use case for OCGA is the command-line tool, its core engine can be imported and used directly in your own Python projects, as permitted by the MIT license.
|
|
43
|
+
|
|
44
|
+
The main entry point function is `ocga_process2`, which can be imported from the top-level package. Its function is analogous to the CLI tool:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from ocga import ocga_process2
|
|
48
|
+
|
|
49
|
+
input_file = "path/to/building.osm"
|
|
50
|
+
rules_file = "path/to/rules.ocga"
|
|
51
|
+
output_file = "path/to/generated.osm"
|
|
52
|
+
|
|
53
|
+
# The other arguments are optional
|
|
54
|
+
ocga_process2(input_file, output_file, rules_file)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Other functions from the engine modules (e.g., from `ocga.ocga_engine`) can also be imported, but their APIs are not guaranteed to be stable and may change. Use them at your own risk.
|
|
58
|
+
|
|
59
|
+
## Language and Examples
|
|
60
|
+
|
|
61
|
+
- For a complete guide to the syntax and operations, see the **[OCGA Language Reference](https://github.com/Zkir/ocga/blob/main/docs/OCGA.md)**.
|
|
62
|
+
- A collection of sample `.osm` and `.ocga` files can be found in the **[docs/ocga_samples](https://github.com/Zkir/ocga/tree/main/docs/ocga_samples)** directory.
|
|
63
|
+
- The `example.bat` and `example.sh` scripts in the root directory demonstrate how to run the tool on these samples.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# OCGA Language Reference
|
|
2
|
+
|
|
3
|
+
This document describes the OCGA (OpenStreetMap Computer Generated Architecture) language, its syntax, and supported operations.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Execution Model
|
|
7
|
+
|
|
8
|
+
OCGA is a declarative language used to define rules for generating 3D building models (building:part's) from 2D OpenStreetMap data.
|
|
9
|
+
|
|
10
|
+
OCGA processes shapes through a series of rule applications. The workflow operates as follows:
|
|
11
|
+
|
|
12
|
+
1. **Input:** The engine starts with an `.osm` file containing one or more building outlines.
|
|
13
|
+
2. **Entry Point:** The special rule named **`building`** is the entry point, which is automatically applied to all objects with a `building` tag found in the input file.
|
|
14
|
+
3. **Transformation and Subdivision:** When a rule is applied to an object, it can perform various operations: modify geometry, assign tags, or, most importantly, subdivide the object into new parts using operators like `split`, `comp`, or `continue`.
|
|
15
|
+
4. **Rule Chaining:** When an object is subdivided, each new part is assigned a new rule name. This new rule will be applied to the corresponding part on a subsequent cycle.
|
|
16
|
+
5. **Termination:** The engine runs in a loop. It continues processing as long as there are objects with unprocessed rules. When a full processing cycle completes and there are no more new parts with rules to apply, the execution stops, and the final geometry is produced.
|
|
17
|
+
|
|
18
|
+
## 1. Language Syntax
|
|
19
|
+
|
|
20
|
+
### Program Structure
|
|
21
|
+
|
|
22
|
+
An OCGA program (`.ocga` file) generally follows this structure:
|
|
23
|
+
|
|
24
|
+
```ocga
|
|
25
|
+
ocga <VERSION_NUMBER>
|
|
26
|
+
const <CONSTANT_NAME> = <expression>
|
|
27
|
+
...
|
|
28
|
+
const <ANOTHER_CONSTANT_NAME> = <expression>
|
|
29
|
+
...
|
|
30
|
+
rule <RULE_NAME> :
|
|
31
|
+
<operator1>
|
|
32
|
+
<operator2>
|
|
33
|
+
...
|
|
34
|
+
rule <ANOTHER_RULE_NAME> :
|
|
35
|
+
<operatorN>
|
|
36
|
+
...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
* **`ocga <VERSION_NUMBER>`**: The program must start with an `ocga` keyword followed by a version number.
|
|
40
|
+
* **`const <CONSTANT_NAME> = <expression>`**: (Optional) Defines a constant that can be used in expressions.
|
|
41
|
+
* **`rule <RULE_NAME> :`**: Defines a named block of one or more operators. The engine applies rules to objects when their conditions are met.
|
|
42
|
+
* **Entry Point:** The rule named **`building`** is the special entry point. It is automatically applied to top-level objects from the input `.osm` file that have a `building` tag.
|
|
43
|
+
* `<RULE_NAME>`: An identifier for the rule (e.g., `building`, `MainWall`, `Window`). Other rules are typically applied to the new objects created by `split` or `comp` operations.
|
|
44
|
+
|
|
45
|
+
### Conditional Statements
|
|
46
|
+
|
|
47
|
+
OCGA supports `if-then-else` conditional logic:
|
|
48
|
+
|
|
49
|
+
```ocga
|
|
50
|
+
if <logical_expression> then
|
|
51
|
+
<operator1>
|
|
52
|
+
<operator2>
|
|
53
|
+
else
|
|
54
|
+
<operator3>
|
|
55
|
+
endif
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
* **`if <logical_expression> then ... endif`**: Executes operators if the `logical_expression` is true.
|
|
59
|
+
* **`else ...`**: (Optional) Executes operators if the `logical_expression` is false.
|
|
60
|
+
|
|
61
|
+
### Expressions
|
|
62
|
+
|
|
63
|
+
* **`expr` (Arithmetic Expression)**: Can include numbers, literals, constants, relative numbers, and basic arithmetic operations (`+`, `-`, `*`, `/`, `%`).
|
|
64
|
+
* **Relative Numbers**: Numbers prefixed with an apostrophe (e.g., `'0.5`) are treated as relative values, often calculated based on the current object's scope dimensions.
|
|
65
|
+
* **`lexpr` (Logical Expression)**: Used in `if` statements. Supports comparisons (`<`, `>`, `<=`, `>=`, `==`, `!=`), `not`, `and`, `or`.
|
|
66
|
+
* **`list`**: A list of numbers enclosed in square brackets (e.g., `[0, 1, 5]`), typically used to specify indices of edges or nodes.
|
|
67
|
+
|
|
68
|
+
### Split Patterns
|
|
69
|
+
|
|
70
|
+
Used with `split_x`, `split_y`, `split_z` operators to define how an object is subdivided and which rule applies to each subdivision.
|
|
71
|
+
|
|
72
|
+
```ocga
|
|
73
|
+
<split_selector> : <rule_name> | <split_selector> : <rule_name> | <split_selector> : <rule_name>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
* **`<split_selector>`**:
|
|
77
|
+
* A number (e.g., `10`, `'0.3`) indicating a fixed size or a relative proportion.
|
|
78
|
+
* `~<NUMBER>`: An "approximately" size, where the number acts as a weight, and the actual size is calculated proportionally based on remaining space.
|
|
79
|
+
* **`<rule_name>`**: The rule to apply to the newly created object (subdivision).
|
|
80
|
+
* **Compound Split Patterns**: `(<split_pattern>) * <NUMBER>` can be used for repeating sections of a split pattern.
|
|
81
|
+
|
|
82
|
+
### Comments
|
|
83
|
+
|
|
84
|
+
Single-line comments start with `#`.
|
|
85
|
+
|
|
86
|
+
## 2. Supported Operations
|
|
87
|
+
|
|
88
|
+
Operations manipulate the current 3D object (a `T3DObject`). Many operations produce new objects, which are then added to the processing queue.
|
|
89
|
+
|
|
90
|
+
### Attributes (Tagging)
|
|
91
|
+
|
|
92
|
+
* **`tag <key>, <value>`**: Sets an OpenStreetMap tag (`key=value`) on the current object.
|
|
93
|
+
* **`colour <value>`**: Sets the `building:colour` tag. Hexadecimal values can be prefixed with `&` (e.g., `&RRGGBB`).
|
|
94
|
+
* **`material <value>`**: Sets the `building:material` tag.
|
|
95
|
+
* **`roof_colour <value>`**: Sets the `roof:colour` tag.
|
|
96
|
+
* **`roof_material <value>`**: Sets the `roof:material` tag.
|
|
97
|
+
* **`roof_direction <value>`**: Sets the `roof:direction` tag, typically an angle in degrees.
|
|
98
|
+
|
|
99
|
+
### Scope Operations
|
|
100
|
+
|
|
101
|
+
* **`align_scope ('geometry' | 'x_to_longer_side')`**: Aligns the object's local coordinate system (scope).
|
|
102
|
+
* `'geometry'`: Aligns to the geometry's bounding box.
|
|
103
|
+
* `'x_to_longer_side'`: Rotates the scope so its X-axis aligns with the longer side of the object.
|
|
104
|
+
* **`rotate_scope <angle_z>`**: Rotates the object's local coordinate system around the Z-axis by `angle_z` degrees.
|
|
105
|
+
|
|
106
|
+
### Geometry Creation
|
|
107
|
+
|
|
108
|
+
* **`outer_rectangle <rule_name>`**: Replaces the current object's geometry with its outer bounding rectangle, then applies `rule_name` to this new shape.
|
|
109
|
+
* **`primitive_cylinder <radius>` / `primitive_cylinder <radius>, [<nVertices>]` / `primitive_cylinder <radius>, [<nVertices>], [<pattern>]`**: Replaces the current object's geometry with a circular/cylindrical shape.
|
|
110
|
+
* `radius`: The radius of the circle.
|
|
111
|
+
* `nVertices`: (Optional) Number of vertices for the approximation of the circle (default 12).
|
|
112
|
+
* `pattern`: (Optional) Pattern for angular distribution of vertices.
|
|
113
|
+
* **`primitive_halfcylinder <radius>, [<nVertices>]`**: Replaces the current object's geometry with a half-circular/half-cylindrical shape.
|
|
114
|
+
* **`create_roof <roof_shape>, <roof_height>`**: Sets `roof:shape` and `roof:height` tags for the current object. `roof_height` can be relative to the object's current Z-scope.
|
|
115
|
+
|
|
116
|
+
### Geometry Subdivision
|
|
117
|
+
|
|
118
|
+
These operations split the current object into multiple new objects, typically applying a rule to each new part. The original object is often 'nil'-ed (removed) after the split.
|
|
119
|
+
|
|
120
|
+
* **`split_x <split_pattern>`**: Splits the object along its local X-axis according to the `split_pattern`.
|
|
121
|
+
* **`split_y <split_pattern>`**: Splits the object along its local Y-axis according to the `split_pattern`.
|
|
122
|
+
* **`split_z <split_pattern>`**: Splits the object along its local Z-axis (height) according to the `split_pattern`. Handles roof preservation.
|
|
123
|
+
* **`comp_border <distance>, <rule_name>`**: Creates new objects representing an offset border around the current object, then applies `rule_name`. Designed for symmetrical shapes.
|
|
124
|
+
* **`comp_edges <distance>, <rule_name>`**: Creates new objects, each representing a "band" along an edge of the current object (similar to `comp_border` but for each edge individually), then applies `rule_name`.
|
|
125
|
+
* **`comp_roof <rule_name>`**: Creates a new object that represents the roof of the current object (with adjusted `min_height` and `height`), then applies `rule_name`.
|
|
126
|
+
|
|
127
|
+
### Transformations
|
|
128
|
+
|
|
129
|
+
These operations modify the scale, position, or rotation of the current object.
|
|
130
|
+
|
|
131
|
+
* **`scale <sx>, <sy>, [<sz>]`**: Scales the current object along its local X, Y, and optionally Z axes. `sx`, `sy`, `sz` can be relative.
|
|
132
|
+
* **`translate <dx>, <dy>, [<dz>]`**: Translates (moves) the current object along its local X, Y, and optionally Z axes. `dx`, `dy`, `dz` can be relative.
|
|
133
|
+
* **`rotate <angle_z>`**: Rotates the current object around its local Z-axis by `angle_z` degrees.
|
|
134
|
+
|
|
135
|
+
### Geometry Modifications
|
|
136
|
+
|
|
137
|
+
* **`bevel <radius>, [<node_list>]`**: Applies a bevel (rounding or chamfering of corners) to the current object.
|
|
138
|
+
* `radius`: The radius of the bevel.
|
|
139
|
+
* `node_list`: (Optional) A list of node indices to apply the bevel to. Only works for closed polygons.
|
|
140
|
+
* **`insert2 <a_param>, <b_param>, [<edge_list>]`**: Inserts new geometry into the current object's edges. Creates new nodes along the edges, potentially pushing them inwards or outwards.
|
|
141
|
+
* `a_param`: Controls the distance along the edge where new nodes are inserted.
|
|
142
|
+
* `b_param`: Controls the offset distance (e.g., inwards/outwards) from the edge.
|
|
143
|
+
* `edge_list`: (Optional) A list of edge indices to apply the operation to. Only works for closed polygons.
|
|
144
|
+
|
|
145
|
+
### Flow Control Operations
|
|
146
|
+
|
|
147
|
+
* **`massModel <rule_name>`**: For a building outline, it applies a `split_z` operation to generate a mass model part and then applies `rule_name` to it.
|
|
148
|
+
* **`continue <rule_name>`**: This is a fundamental object transformation, not a subroutine call. It performs the following steps:
|
|
149
|
+
1. A new object, identical to the current one, is created.
|
|
150
|
+
2. This new object is scheduled to be processed by `<rule_name>` on the next cycle of the engine.
|
|
151
|
+
3. The original object remains in the current context, and subsequent operations within the same rule block can still act on it.
|
|
152
|
+
This allows for powerful, non-destructive transformations. For example, using `continue` twice with different rules will result in two new, identical objects being created from the original, each scheduled for a different rule. Not allowed for top-level buildings.
|
|
153
|
+
* **`nope`**: A no-operation, effectively doing nothing. Can be useful as a placeholder.
|
|
154
|
+
* **`restore`**: Ensures the current object remains in the list of active objects, useful if it was previously removed (e.g., by a `split` operation).
|
|
155
|
+
* **`nil`**: Removes the current object from the list of active objects. Useful for creating holes.
|
|
156
|
+
* **`print <expression>`**: Prints the value of the expression to the console (for debugging).
|