Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Material mapping and assignment #138

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions .antora/modules/specification/nav-openmaterial.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@
** xref:geometry/general.adoc[]
** xref:geometry/object-classes.adoc[]
** xref:geometry/file-format-support.adoc[]
** xref:geometry/metadata.adoc[]
** xref:geometry/performance.adoc[]
** xref:geometry/asset-schema.adoc[]
** xref:geometry/mapping-schema.adoc[]
* Material
** xref:material/introduction.adoc[]
** xref:material/file-format.adoc[]
** xref:material/metadata.adoc[]
** xref:material/material-properties.adoc[Material properties]
** xref:material/lookup-tables.adoc[]
** xref:material/file-structure.adoc[]
** xref:material/material-schema.adoc[]
** xref:material/material-emp-schema.adoc[]
16 changes: 8 additions & 8 deletions .github/workflows/antora-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ jobs:
- name: Generate AsciiDoc from JSON
working-directory: repo/scripts
run: |
python3 json2asciidoc.py ../schemas/asset_schema.json metadata
mv metadata.adoc ../content/geometry/
python3 json2asciidoc.py ../schemas/material_schema.json metadata
mv metadata.adoc ../content/material/
python3 json2asciidoc.py ../schemas/material_schema.json materialProperties
mv materialProperties.adoc ../content/material/material-properties.adoc
python3 json2asciidoc.py ../schemas/material_emp_schema.json electromagneticProperties
mv electromagneticProperties.adoc ../content/material/electromagnetic-properties.adoc
python3 json2asciidoc.py ../schemas/asset_schema.json
mv asset-schema.adoc ../content/geometry/
python3 json2asciidoc.py ../schemas/mapping_schema.json
mv mapping-schema.adoc ../content/geometry/
python3 json2asciidoc.py ../schemas/material_schema.json
mv material-schema.adoc ../content/material/
python3 json2asciidoc.py ../schemas/material_emp_schema.json
mv material-emp-schema.adoc ../content/material/

- name: Configure Pages
uses: actions/configure-pages@v4
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/validate-json.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ jobs:
schema: ./schemas/asset_schema.json
file: ./examples/*.xoma

- name: Validate material mapping JSON schemas
uses: cardinalby/schema-validator-action@v3
with:
schema: ./schemas/mapping_schema.json
file: ./examples/*.xomm

- name: Validate material JSON schemas
uses: cardinalby/schema-validator-action@v3
with:
Expand Down
4 changes: 2 additions & 2 deletions content/geometry/geometry-index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
* xref:geometry/general.adoc[leveloffset=+1]
* xref:geometry/object-classes.adoc[leveloffset=+1]
* xref:geometry/file-format-support.adoc[leveloffset=+1]
* xref:geometry/metadata.adoc[leveloffset=+1]
* xref:geometry/performance.adoc[leveloffset=+1]
* xref:geometry/asset-schema.adoc[leveloffset=+1]
* xref:geometry/mapping-schema.adoc[leveloffset=+1]

11 changes: 5 additions & 6 deletions content/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,13 @@ include::geometry/introduction.adoc[leveloffset=+1]
include::geometry/general.adoc[leveloffset=+1]
include::geometry/object-classes.adoc[leveloffset=+1]
include::geometry/file-format-support.adoc[leveloffset=+1]
include::geometry/metadata.adoc[leveloffset=+1]
include::geometry/performance.adoc[leveloffset=+1]
include::geometry/asset-schema.adoc[leveloffset=+1]
include::geometry/mapping-schema.adoc[leveloffset=+1]
= Material
include::material/introduction.adoc[leveloffset=+1]
include::material/file-format.adoc[leveloffset=+1]
include::material/metadata.adoc[leveloffset=+1]
include::material/material-properties.adoc[leveloffset=+1]
include::material/lookup-tables.adoc[leveloffset=+1]
include::material/file-structure.adoc[leveloffset=+1]
include::material/material-schema.adoc[leveloffset=+1]
include::material/material-emp-schema.adoc[leveloffset=+1]



Expand Down
1 change: 0 additions & 1 deletion content/material/file-format.adoc

This file was deleted.

1 change: 1 addition & 0 deletions content/material/file-structure.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
= File structure
7 changes: 3 additions & 4 deletions content/material/material-index.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
= Material

* xref:material/introduction.adoc[leveloffset=+1]
* xref:material/file-format.adoc[leveloffset=+1]
* xref:material/metadata.adoc[leveloffset=+1]
* xref:material/material-properties.adoc[leveloffset=+1]
* xref:material/lookup-tables.adoc[leveloffset=+1]
* xref:material/file-structure.adoc[leveloffset=+1]
* xref:material/material-schema.adoc[leveloffset=+1]
* xref:material/material-emp-schema.adoc[leveloffset=+1]
10 changes: 5 additions & 5 deletions content/nav-openmaterial.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
** xref:geometry/general.adoc[]
** xref:geometry/object-classes.adoc[]
** xref:geometry/file-format-support.adoc[]
** xref:geometry/metadata.adoc[]
** xref:geometry/asset-schema.adoc[]
** xref:geometry/mapping-schema.adoc[]
** xref:geometry/performance.adoc[]
* xref:material/material-index.adoc[]
** xref:material/introduction.adoc[]
** xref:material/file-format.adoc[]
** xref:material/metadata.adoc[]
** xref:material/material-properties.adoc[Material properties]
** xref:material/lookup-tables.adoc[]
** xref:material/file-structure.adoc[]
** xref:material/material-schema.adoc[]
** xref:material/material-emp-schema.adoc[]



Expand Down
4 changes: 2 additions & 2 deletions examples/example_asset.xoma
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"z" : [0.0, 1.5]
}
},
"materialMapping": [
["10;50;255;127", "example_material.xomp", "metal with red paint"]
"materialTextureAssignment": [
["example_material_name", "example_texture.png"]
]
}
19 changes: 19 additions & 0 deletions examples/example_mapping.xomm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"metadata": {
"name": "example_mapping",
"description": "This is an example for a material mapping table. This file can be shared between multiple assets.",
"uuid": "c492bda27c8443e6be1903115545e844",
"mappingVersion": "1.0.0",
"openMaterialVersion": "1.0.0",
"copyright": "(C) 2023-2024, Example Company",
"license": "MPL-2.0",
"author": "[email protected]",
"creationDate": "20240703T101728Z",
},
"materialMapping": [
["material_red", "materials/material_a.xomp", "metal with red paint"],
["rgba:10;50;255;127", "materials/material_a.xomp", "metal with red paint"],
["material_green", "materials/material_b.xomp", "metal with green paint"],
["material_blue", "materials/material_c.xomp", "metal with blue paint"]
]
}
22 changes: 8 additions & 14 deletions schemas/asset_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,34 +157,28 @@
"boundingBox"
]
},
"materialMapping": {
"materialTextureAssignment": {
"type": "array",
"description": "Mapping of materials used in the asset",
"description": "Optional array containing material texture assignments. It links material names contained in the 3D model file to OpenMATERIAL assignment textures. In a separate material mapping file, the 'color' values in this texture are linked to OpenMATERIAL property files.",
"items": {
"type": "array",
"description": "Array of RGB values and material name",
"items": [
{
"type": "string",
"description": "RGB values in the format 'R;G;B;A'",
"pattern": "^\\d{1,3};\\d{1,3};\\d{1,3};\\d{1,3}$"
"description": "Name of the material in the 3D model file."
},
{
"type": "string",
"description": "Path to an OpenMATERIAL property file"
},
{
"type": "string",
"description": "Short but precise description of the material"
"description": "File path to the OpenMATERIAL assignment texture. Supported texture formats are png and jpg.",
"pattern": "^(\\./|/)?([a-zA-Z0-9_\\-./]+)\\.(png|jpg|jpeg)$"
}
],
"minItems": 3,
"maxItems": 3
"minItems": 2,
"maxItems": 2
}
}
},
"required": [
"metadata",
"materialMapping"
"metadata"
]
}
78 changes: 78 additions & 0 deletions schemas/mapping_schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Material Mapping Schema",
"type": "object",
"properties": {
"metadata": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the material mapping."
},
"description": {
"type": "string",
"description": "This is a short description of the material mapping table. Use 2-3 sentences."
},
"uuid": {
"type": "string",
"description": "Universally unique identifier for the material mapping.",
"pattern": "^[a-f0-9]{32}$"
},
"mappingVersion": {
"type": "string",
"description": "Version of the mapping table.",
"pattern": "^\\d+\\.\\d+\\.\\d+$"
},
"openMaterialVersion": {
"type": "string",
"description": "Version of the OpenMaterial format.",
"pattern": "^\\d+\\.\\d+\\.\\d+$"
},
"copyright": {
"type": "string",
"description": "Copyright information with year and company."
},
"license": {
"type": "string",
"description": "License information. For common open source licenses, provide an SPDX identifier or a URL to the license."
},
"author": {
"type": "string",
"description": "Email address or name of the author. Can also be a company name."
},
"creationDate": {
"type": "string",
"description": "Date and time when the material mapping was created in ISO 8601 format.",
"pattern": "^\\d{8}T\\d{6}Z$"
}
},
"required": ["name", "uuid", "mappingVersion", "openMaterialVersion", "creationDate"]
},
"materialMapping": {
"type": "array",
"description": "Array containing material mappings.",
"items": {
"type": "array",
"items": [
{
"type": "string",
"description": "Material name or RGBA code."
},
{
"type": "string",
"description": "File path to the material.",
"pattern": "^(\\./|/)?([a-zA-Z0-9_\\-./]+)\\.xomp$"
},
{
"type": "string",
"description": "Description of the material."
}
],
"minItems": 3,
"maxItems": 3
}
}
},
"required": ["metadata", "materialMapping"]
}
66 changes: 52 additions & 14 deletions scripts/json2asciidoc.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import os
import json
import argparse


def format_main_headline(file_name):
"""
Convert file name to a title-style headline for the AsciiDoc.
Replaces underscores with spaces and capitalizes the first letter.

Args:
file_name (str): The base name of the JSON schema file.

Returns:
str: The formatted headline.
"""
file_name = file_name.replace('_', ' ') # Replace underscores with spaces
file_name = file_name.replace('-', ' ') # Replace hyphens with spaces
return file_name.capitalize() # Capitalize the first letter


def escape_special_chars(pattern):
"""
Escape special characters in the pattern string for AsciiDoc compatibility.
Expand Down Expand Up @@ -107,13 +124,13 @@ def generate_asciidoc(field_name, schema, required_fields):
Returns:
str: The generated AsciiDoc content.
"""
asciidoc_content = f"= {field_name.capitalize()}\n\n"
asciidoc_content = f"== {field_name}\n\n"
field_data = schema['properties'][field_name]
asciidoc_content += field_data.get("description", "") + "\n\n"

# Generate the content for the properties, recursively handling nested properties
if 'properties' in field_data:
asciidoc_content += generate_asciidoc_properties(field_data['properties'], required_fields, level=2)
asciidoc_content += generate_asciidoc_properties(field_data['properties'], required_fields, level=3)
elif field_data.get('type') == 'array':
# Handle array fields directly
if 'items' in field_data and isinstance(field_data['items'], dict) and 'items' in field_data['items']:
Expand All @@ -134,9 +151,9 @@ def main():
Main function to handle command-line arguments, process the JSON schema, and generate the AsciiDoc documentation.
"""
# Set up argument parser
parser = argparse.ArgumentParser(description="Generate AsciiDoc documentation for a given JSON schema field.")
parser = argparse.ArgumentParser(description="Generate AsciiDoc documentation for a given JSON schema field or the entire schema.")
parser.add_argument('json_schema_path', type=str, help="Path to the JSON schema file.")
parser.add_argument('field_name', type=str, help="Name of the field (e.g., metadata) to generate documentation for.")
parser.add_argument('field_name', type=str, nargs='?', default='', help="Name of the field (e.g., metadata) to generate documentation for. Leave empty to generate documentation for the entire schema.")

# Parse the arguments
args = parser.parse_args()
Expand All @@ -147,19 +164,40 @@ def main():
with open(json_schema_path, 'r') as file:
schema = json.load(file)

# Check if the field exists in the schema
if field_name not in schema['properties']:
print(f"Error: The field '{field_name}' does not exist in the provided schema.")
return
# Generate documentation for the entire schema if field_name is empty
if not field_name:
# Generate AsciiDoc for all fields
print("Generating AsciiDoc for the entire schema...")

# Generate the main headline from the file name
base_filename = os.path.basename(json_schema_path).replace('_', '-')
headline = format_main_headline(os.path.splitext(base_filename)[0])
asciidoc_content = f"= {headline}\n\n"

# Process each field in the schema
for field in schema['properties']:
required_fields = schema['properties'][field].get('required', [])
asciidoc_content += generate_asciidoc(field, schema, required_fields)

# Save the AsciiDoc content to a file
base_filename = os.path.basename(json_schema_path).replace('_', '-')
output_filename = f"{os.path.splitext(base_filename)[0]}.adoc"
else:
# Check if the field exists in the schema
if field_name not in schema['properties']:
print(f"Error: The field '{field_name}' does not exist in the provided schema.")
return

# Get the required fields for the selected field
required_fields = schema['properties'][field_name].get('required', [])

# Get the required fields for the selected field
required_fields = schema['properties'][field_name].get('required', [])
# Generate the AsciiDoc content for the specific field
asciidoc_content = generate_asciidoc(field_name, schema, required_fields)

# Generate the AsciiDoc content
asciidoc_content = generate_asciidoc(field_name, schema, required_fields)
# Save the AsciiDoc content to a file
output_filename = f"{field_name}.adoc"

# Save the AsciiDoc content to a file
output_filename = f"{field_name}.adoc"
# Write the output to a file
with open(output_filename, 'w') as file:
file.write(asciidoc_content)

Expand Down
Loading