vizoogmbh / u3m

Unified 3D Material (U3M)
http://www.u3m.info
BSD 3-Clause "New" or "Revised" License
40 stars 20 forks source link

U3MG #11

Open ofirbw opened 5 years ago

ofirbw commented 5 years ago

A suggestion on how to represent a group of materials within u3ma archive

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "description": "UUID4 represented as string with or without {}",
      "type": "string",
      "pattern": "^({{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}}{0,1})$"
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string"
    },
    "created": {
      "type": "string",
      "format": "date-time"
    },
    "modified": {
      "type": "string",
      "format": "date-time"
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "pattern": ".*\\.(u3m|u3ma|json)$"
          }
        }
      }
    },
    "custom": {
      "type": ["object", "null"]
    }
  }
}

An example can look something like this:

{
  "custom": {
    "Browzwear": {
      "type": "fabric",
      "items": [
        {
          "id": "1",
          "allover_print": true
        },
        {
          "id": "2",
          "blending_mode": "normal"
        },
        {
          "id": "3",
          "blending_mode": "multiply"
        },
        {
          "id": "4",
          "blending_mode": "multiply"
        }
      ],
      "physics_material_Id": 2
    }
  },
  "id": "{ff38227a-e00a-40b0-b0cd-d3ef56b04b45}",
  "modified": "2018-10-22T16:31:40",
  "created": "2018-10-22T16:31:40",
  "name": "Group 1",
  "items": [
    {
      "id": "1",
      "path": "BlackFabric\\BlackFabric.u3m"
    },
    {
      "id": "2",
      "path": "GreenLeather\\GreenLeather.u3m"
    },
    {
      "id": "3",
      "path": "GreyHeather\\GreyHeather.u3m"
    },
    {
      "id": "4",
      "path": "PinkGlitter_meshfabric\\PinkGlitter_meshfabric.u3m"
    }
  ]
}
vizoomartin commented 5 years ago

Thanks for the input! definitely makes sense, and an archive will also simplidy moving u3ms between applications.

just a few suggestions/questions:

  1. is the "id" parameter indicating the layer position, i.e. whether the material is on top or on the bottom, or is it used to identify the material, e.g. for use in the "Custom" section? Otherwise, is the layer order indicated by the order in the array itself? If so, maybe we can create a unique ID for each group layer as well?

  2. "pattern": ".*\.(u3m|u3ma|json)$" <- whats the expected behaviour for a .json?

  3. and just a preference on my end, maybe we can always create a group.json, even if there's only one item in the u3ma. This would make the reading of u3mas m ore predictable. Or is that implementation problematic?

  4. We should avoid additionalproperties and add required properties in the json schema.

  5. Same as for the u3m, maybe we can add the version of the group schema as well? Just in case there are changes in the future, to avoid compatibility issues

ofirbw commented 5 years ago
  1. it is used to identify the material, e.g. for use in the "Custom" section, the order is according to the array. Not sure I full understand maybe "we can create a unique ID for each group layer as well?", for what purpose?
  2. group is represented as a group_name_group.json and each group can contain another group (for example, group material which has 3d object with multiple sections - zipper), do you suggest different extension for group?
  3. what if the group contains 1 material, should the application present this material as a single material or a group? from my POV this is application / user decision
  4. Agree, we will update the schema
  5. Agree, we will update the schema
vizoomartin commented 5 years ago
  1. Just to have a rule on how to create an "id" for each group item, ideally without having to go through all items and checking whether an "id" is already in use. Otherwise how do i know if id:"4" is already in use?
  2. ah understood now, thank you
  3. That should probably depend on the application decision. But does it make sense to display a single material as a group inside an application? having less special cases in how a group can look like and has to be read would just make implementation for everyone easier
ofirbw commented 5 years ago
  1. Tend to agree with you on the "id", so just to make sure that I understand your suggestion, instead of having a random id, we will add the u3m unique id and we will also have unique id for the group (in case of group inside group)
  2. this might be related to your suggestion on #3 but I will ask anyway... in order to allow full flexibility for different naming convention, what do you say about have different extension for group instruction file (u3mg?) otherwise we will have to relay on the filename or the prefix of the filename
GalKatzir commented 5 years ago

I updated the group schema

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "schema": {
            "enum": [
                "1.0"
            ]
        },
        "id": {
            "description": "UUID4 represented as string with or without {}",
            "type": "string",
            "pattern": "^({{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}}{0,1})$"
        },
        "name": {
            "type": "string",
            "minLength": 1
        },
        "description": {
            "type": "string"
        },
        "created": {
            "type": "string",
            "format": "date-time"
        },
        "modified": {
            "type": "string",
            "format": "date-time"
        },
        "items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "pattern": ".*\\.(u3m|u3ma|json)$"
                    },
                    "id": {
                        "description": "UUID4 represented as string with or without {}",
                        "type": "string",
                        "pattern": "^({{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}}{0,1})$"
                    }
                },
                "additionalProperties": false,
                "required": [
                    "path",
                    "id"
                ]
            }
        },
        "custom": {
            "type": [
                "object",
                "null"
            ]
        }
    },
    "additionalProperties": false,
    "required": [
        "schema",
        "id",
        "name",
        "created",
        "modified",
        "items",
        "custom"
    ]
}

And here an example for the group object

{
    "created": "2018-10-22T13:02:04",
    "custom": {
        "Browzwear": {
            "edges": [],
            "facing": 0,
            "front_axis": 0,
            "items": [
                {
                    "entry_id": 0,
                    "id": "{dc728729-1d85-11e9-b13b-d481d7a83ea2}",
                    "name": "Button"
                },
                {
                    "entry_id": 1,
                    "id": "{dc72872a-1d85-11e9-8925-d481d7a83ea2}",
                    "name": "Thread1"
                },
                {
                    "entry_id": 2,
                    "id": "{dc72872b-1d85-11e9-8eea-d481d7a83ea2}",
                    "name": "Thread2"
                }
            ],
            "markers": [
                {},
                {}
            ],
            "mass": 5.0,
            "material": {
                "basecolor": {
                    "texture": {
                        "factor": {
                            "b": 0.0,
                            "g": 0.0,
                            "r": 0.0
                        },
                        "image": {
                            "crop": {
                                "height": 10.583333015441895,
                                "width": 10.583333015441895,
                                "x": 0.0,
                                "y": 0.0
                            },
                            "dpi": 72,
                            "flip_x": false,
                            "flip_y": false,
                            "height": 10.582010269165039,
                            "layout_angle": -0.0,
                            "mip_map": true,
                            "path": "textures/7b795661c50003275e4ad08e3fedf84a.png",
                            "repeat": null,
                            "rotation_angle": 0.0,
                            "tile_mode": "auto_size",
                            "width": 10.582010269165039
                        },
                        "mode": "multiply"
                    }
                },
                "user_information": ""
            },
            "metadata": {},
            "mirror": true,
            "path": "textures/3aa254196e894803d6653981f769a777/buttonWithThread-v5.fbx",
            "preview": "preview.png",
            "scale": {
                "x": 1.1739660501480103,
                "y": 1.1746066808700562,
                "z": 1.2120625972747803
            },
            "type": "trim3d",
            "up_axis": 1,
            "vertical": 2
        }
    },
    "description": "",
    "id": "{dc728728-1d85-11e9-9cc7-d481d7a83ea2}",
    "items": [
        {
            "id": "{dc728729-1d85-11e9-b13b-d481d7a83ea2}",
            "path": "Button/Button.u3m"
        },
        {
            "id": "{dc72872a-1d85-11e9-8925-d481d7a83ea2}",
            "path": "Thread1/Thread1.u3m"
        },
        {
            "id": "{dc72872b-1d85-11e9-8eea-d481d7a83ea2}",
            "path": "Thread2/Thread2.u3m"
        }
    ],
    "modified": "2018-10-22T13:02:04",
    "name": "buttonWithThreads",
    "schema": "1.0"
}
PatrickOnVizoo3d commented 5 years ago

gal's schema above looks good (except for the *.json part that has to be replaced by the extension for the u3m group file) what extension do you propose (u3mg?)?

as far as i understood, your u3mas are just plain *.zip files containing u3ms, other u3mas and u3m group files. which standard did you use (ISO/IEC 21320-1:2015 vs PKWARE APPNOTE 6.3.6)? ZIP or ZIP64? which compression algorithms should we support? which do you currently support? is encryption support required? is spanning (splitting the data across multiple files) support required? what is with ACLS or other file attributes? Do they need to be supported or not?