Material overhaul

Looking forward to post 0.21 release, I want to start a discussion thread to cover how Materials should work, without constraining it to how they work now, or changes proposed previously. This may mean refactoring code that is external to materials like architecture and FEM, and any external workbenches.

Yes, I have read this thread: https://devtalk.freecad.org/t/material-improvements/14445/1 I haven’t built and tested the code yet, but I will shortly. I don’t want to comment on all the ideas in this build until I’ve had a chance to play with it.

I have some ideas for how things should work, but I’m keeping an open mind here. Some ideas may be discarded, while others merely need enhancement.

A summary of what I’m thinking, and some of this has been covered before elsewhere:

  1. If it has a shape, it can have a material. Setting the material should be a matter of right clicking. Material properties are inherited, but overridable. Multi-material objects should also be handled and there a number of options for that. The physical properties of the material should automatically be applied where appropriate. For example, mass, center of gravity, etc. should be set when the material is set.

  2. The default appearance should be that of the material, unless overridden. Obviously that means it should be possible to be overridden. Appearance workflows will need to be integrated with the materials. That means the materials in the appearance dialog should use the same materials available in FEM, for example. Cards can be created to replace the hard coded appearance values.

  3. Where possible, it should be transparent to the user. For example, materials are assigned to the objects. Documents should not require Material dictionaries in the project tree. This could be an optional feature, or perhaps a summary table produced by a right click or menu option. I wouldn’t read this bullet as a requirement so much as a goal. This is an area where I’m keeping an open mind.

  4. One source for materials. Everything is specified in a card. As I understand it the previous attempt used an object that allowed for multiple data sources. I still need to look into this to understand it properly but this seems to be undesirable to me.

  5. Material Cards need to be enhanced. For example, some physical properties may vary with temperature. It should be possible to specify properties for specific value ranges. Default values for those ranges should be specifiable in the material configuration: STP, NTP, or customizable values, etc. Similarly direction should be specifiable. For example, carbon fiber direction, or wood grain directions.

  6. Saving material properties in the document should be optional, configurable via preferences. This should help with bullet 3

  7. Some types of import/exports can be enhanced to include material information

These are just thoughts and open to discussion. I’ll be first to admit that there’s a lot I don’t know. Rants are welcome. What else would you like to see?

Some other information I’d like to know before beginning:

  1. What workbenches currently use materials? (e.g. Arch, FEM, etc.)

  2. What EXTERNAL workbenches use materials?

  3. What imports/exports use or could use material information?

This is a very good overview of the problem. Materials in FreeCAD is a large thing that spans on different areas (object aspect → -> physical properties). And there is the problem of how they are represented to the user. And the problem of how they are kept/stored.

I believe the cards system we now have is good. Cards are not tied to anything, they are easily editable and very flexible. I think we should build from there.

The main users of materials inside FreeCAD are indeed Arch and FEM. Another external one that uses them AFAIR is Render. But any other WB that uses simulations like openfoam should be using them too.

I’d say the main thing here is to design a good UI/UX workflow.

Have a look too at the materials manager in the BIM workbench. Not the perfect thing but close to what I imagine would be handy

I would like to add material characterization support to FEM workbench (along with a new solver we’ve been developing). For that, I’d like a way to represent uncertainty in material parameters. In the simplest case, this might be a material with a nominal value and (max, min) bounds on elastic moduli and yield stress/hardening parameters, but many will want Weibull distribution parameters. In a Bayesian context, this input would be called the prior, and after a characterization solve, the FEA tool would create a new card with the posterior (better constrained based on matching experiments).

Typically, a material is characterized by a “simple” experiment like a dog-bone necking or nano-indentation, and the characterized material (“posterior card”) is used in larger/more complicated geometry and loading scenarios. It would be good to be able to store some provenance information in the posterior card.

I’m trying to do a proper requirements analysis for this as its effects can be far reaching. I’ve already contacted some people for a zoom session as I can get more information talking face to face.

If I haven’t contacted you and you would like to have input, message me and I’ll set something up.

You can also continue to post here. I’ll post summaries as I go so that everyone can see what’s going on.

The requirements gathering is progressing and I promised updates so here goes. In this post I’m going to discuss the material cards and associated UI. A lot of the rest of the overhaul is going to flow from there. This is still a work in progress so feel free to add you $0.02 now before things solidify. I’ll be prototyping some of this over the next week so it will be easier to visualize. I’ll show them as they become available.

The overall consensus is that the cards have worked well, but are limited. The capabilities will need to be expanded to support a number of workflows. Desired features are:

  • Inheritance - you only specify what’s different in your custom material. All other values are in the parent


  • Expanded values - in the current implementation they’re simple name value pairs, with the value being a string, float, int, etc. Some other values that are desirable include
    • Distributions and associated parameters
  • Upper and lower bounds
  • Temperature series
  • Arrays


  • DOI citation lookups (https://doi.org). This will be similar to a description in that it is documentation, but it should be possible to link from the UI


  • Units field - this can improve validations as well as aid in documentation. This would be a type such as ‘Pressure’ rather than the units such as ‘MPa’ to accommodate user preferences for units

For mechanical properties, there are situations where the current linear elastic model (Shear modulus, Young’s modulus, poisson ratio) are insufficient. It should be possible to add non-linear (or other) models through an API and edit them in the UI. In many cases these models would provide their own parameter templates that may specify very different physical properties. This mechanism is currently being refined.

For the UI, the organization will change. A combobox was sufficient for the models currently supplied but as the number of models increases it quickly becomes unmanageable. A tree view will organize materials into libraries and folders. System (and workbench) libraries will be considered immutable. Changes must be saved to a custom card. A favourites folder would be at the top. This could be for materials already in use in the model, or for ones explicitly marked as favourite. When a property is edited, system cards would be saved as a custom card. For custom cards it can overwrite the existing card, or saved into a new card.

Properties will be separated into tabs based on the category. For example, General, Physical, Appearance, and Costs. Some properties may be added or removed as the workflow is improved. For example, the “Father” property may be replaced by something more appropriate when inheritance is implemented.

These changes are likely to break existing workbenches. For core workbenches such as FEM and Arch, any required fixes will be done. External workbenches may require some changes by the maintainers. The biggest impact will be in value lookups, as they will now return an object rather than a value. APIs will be made available to both C/C++ and Python developers to minimize their workload.

As I mentioned earlier in the post, expect some prototypes soon. This will help in the visualization.

What do you mean with one source of materials? Does this mean that an user cannot define their own library of materials? I don’t agree with that.

It just means they would be defined in one place. Currently FreeCAD defines physical and appearance properties using material cards, while the appearance dialog has a set of hard coded materials that are completely separate and include appearance properties only. The previous attempt tried to accommodate both, but we would eliminate the latter and only use cards. The current proposal would in fact enhance the users ability to create and use their own libraries.

Ah that makes sense and it’s very good, looking forward to this improvement! A tangent missing feature here is the ability to obtain center of gravity for Parts, right now I think FreeCAD does not take into account difference in density and treats all elements inside a Part container to have unitary density, it would be nice if once there is proper material support that the center of gravity is calculated taking this into account. I think we don’t have a way to directly get the weight of an object either.

In regards to that it might also make sense to have the possibility to specify density for surfaces, to model for example aircraft skins as just surfaces that will be treated as having thickness when calculating weight. This might be out of scope of your intent though, but keep in mind as possible future usage.

This is something that we will be digging in to. Right now for example selecting a material isn’t automatically applied to a part for things like CG or mass even though these capabilities are there.

This looks like a very good plan!

A couple of $0.02 ideas:

  • Maybe writing unit tests for Arch and FEM that test material support would be handy here so we can detect incompatibility issues early. For Arch there is one already: https://github.com/FreeCAD/FreeCAD/blob/master/src/Mod/Arch/TestArch.py#L399 but we might add a simpler one. For FEM I’m not sure

  • Think of the possibility for workbenches to implement some sort of “micro-editor”. Some workbenches might want to work with only a few material parameters, and will not want to use the full-fledged material editor. Maybe you could design your UI code in a way that some parts of it could be reused by others (I’m thinking for example, of the materials tree)

  • Some external resources might be needed, like texture images, or hatch patterns. These might be a simple file path, or an URL, but I imagine these could also be embedded, so we have a self-contained material. The ability to embed any kind of data could also be useful for the complex cases you described, I imagine a whole table or diagram or formula could be embedded too.

What heresy is this? :smiley:

Yes. Regression testing will be vital.

I’m already thinking along the same lines. The tree would definitely be useful as a widget if not a full mini editor. Even for my own stuff I need a combination of material properties (either Shear modulus or Young’s Modulus and poisson ratio), so perhaps a filtering function. Easier in an API than a UI, but potential performance issues either way.

Good idea. Yaml can handle binary data and links are links.

I’ve promised more information after creating some prototypes so here goes. There’s a lot to this so there I’ll split it into a few replies.

Most of the progress so far has been in material cards and their handling. One issue is that with large numbers of materials, potentially with workbenches adding to the list as well, the volume is much too large to handle with a combobox.
matgui1.png
Instead they’re organized into libraries and folders. The current materials are in a system library, with additional libraries added by workbenches and users. Selecting a card will display the information in 3 separate tabs, one each for general information, properties, and a special one for appearance based properties.
matgui2.png
matgui3.png
1/…

The current model is a single monloithic model containing a large number of predefined properties broken up into categories. That’s going away in favour of a larger number of more granular models described generically as Models and Appearance models matching the tabs.

For example, what are currently described as mechanical properties can be divided further, such as density, isotropic linear elasticity, and so on. The linear elastic model shown previously inherits from both density and isotropic linear elasticity models. Users will be able to add specific models they require.
matgui4.png
This has a few advantages. It makes the models expandable to support other mechanical models than what are stock in FreeCAD. These expansions would typically be provided by the external workbenches or macro developers. It will also allow them to require specific models to function, and to allow them to filter based on the completeness of those models. For example, I need density, or Orthotropic Linear Elasticity. The current version would require checking all parameters in each model individually. Inheritance would mean information would not need to be duplicated in multiple places, such is currently the case for density in both the mechanical and fluidic model categories. They can be more context aware. For example, the current model has a field Father which is meant to bestow a class of properties to that model of which the model card system is unaware. This can be defined in a model that relates to the context, such as in an architectural model.

Model files are defined using Yaml. This makes them user readable. They are identified using UUIDs so duplicate names become irrelevant. Here’s aan example (subject to change!):

Model:
  Name: 'Linear Elastic'
  UUID: '7b561d1d-fb9b-44f6-9da9-56a4f74d7536'
  URL: 'https://en.wikipedia.org/wiki/Linear_elasticity'
  Description: "Materials that are linearly elastic obey Hooke's law i.e. the stress and strain relationship is linear"
  DOI: "10.1016/j.ijplas.2004.06.004"
  Inherits:
    - Density:
      UUID: '454661e5-265b-4320-8e6f-fcf6223ac3af'
    - IsotropicLinearElastic:
      UUID: 'f6f9e48c-b116-4e82-ad7f-3659a9219c50'
  AngleOfFriction:
    Type: 'Quantity'
    Units: ''
    URL: 'https://en.wikipedia.org/wiki/Friction#Angle_of_friction'
    Description: "Further information can be found at https://en.wikipedia.org/wiki/Mohr%E2%80%93Coulomb_theory"
  CompressiveStrength:
    Type: 'Quantity'
...

2/…

Parameters will have expanded capabilities. Currently they describe single values, such as a string or quantity. This will be replaced with an object of a type appropriate to the parameter, such as a distribution, list, array, temperature based series, etc. Multivariable series could be queried as a table, or as an interpolated value. Default values can be specified for things such as temperature to simplify use by code not requiring a full series

The editor will have visualization aids where appropriate, such as a graph of time series data (ignore the graph shown here… it’s for visualization only)
matgui5.png
IMPORTANT

This is the portion that will have the biggest impact on existing code. The card data can no longer be supplied as a key/value dictionary. To get a value, the code will have to call an api, potentially parameterized with a temperature, pressure, etc. This should be transparent to the end user. Core workbenches will be fixed to support this but external workbench developers will have to be aware of this change.

3/…

Back to the cards themselves, there are a few additional points.

It should be possible to “inherit” cards i.e. copy and only change one or two parameters. This will be restricted to single inheritance but can be infinitely deep. Since the system library will be immutable (at least through the UI), this will be required if you intend to modify any of the standard cards. The UI for this operation has not yet been refined.

Card data could optionally be embedded into the document allowing it to be more easily shared.

Imports of material from other products should be possible from other products and CAD systems, but this will be part of a later effort.

The user interface shown here, or more appropriately the final form of what is shown here, will be what is displayed when assigning a material to a part.

Finally, there will be a lot of facilities made available to the developer. Widgets for card selection, object display and editing, etc. will be provided. Since the interface is shifting to APIs, this will be defined, refined, and supported. The goal is to make life for the addon developers as simple as possible.

4/…

From a development timeline point of view, this will be done first. Integrations into the core objects and appearance routines are all going to be informed by this. It’s also the part most likely to break other people’s code, so doing this first will provide the best opportunity for testing and fixing.

Implementation will be in the core in C++ with Python support as is currently done in the rest of the product. This will ensure maximal compatibility throughout the product.

UIs shown here are quick prototypes and are not complete. These will be refined as we progress.

I say ‘we’ here but so far it’s just me. If you feel like contributing to the coding, there are some good divisions of effort. If you prefer to contribute UI/UX, testing, or documentation expertise, that is also extremely welcome.\

../5

This is going great!!!

I would indeed take a moment to think of a good embedded <> linked solution. One might want to give a FreeCAD file to another person containing custom made materials. The other person does not have the card on their computer, so the data should be embedded into the FreeCAD file.

How will that work, what if the other person has a material with a same name on their computer, or even the same one but an older version. How will a “priority” system work.

Also, probably you saw that already, FreeCAD has the ability to save the contents of a property as a file inside the .FCStd file (ex. DiffuseColor or Path in the Path WB). It might be interesting to literally save materials as .FCMat cards inside the FCStd file, so the same priority system can be applied universally, for both in-cards and in-file materials, they would all technically be in-cards.

Also: Arch Materials have a small code that creates a colored icon from the material color :wink: https://github.com/FreeCAD/FreeCAD/blob/master/src/Mod/Arch/ArchMaterial.py#L441

Some thought has been given to some of this although perhaps not all.

As you pointed out, embedding in the file is an option. I see this being controlled with a selectable preference, similar to how preview images can be embedded in the file.

For name conflicts, files are referred to internally using a UUID created when the model/card is created. This will make name conflicts irrelevant. It doesn’t address the older version problem though. This will require some thought.

I’ll look at your icon code. That could be interesting.

For name conflicts, files are referred to internally using a UUID created when the model/card is created. This will make name conflicts irrelevant. It doesn’t address the older version problem though. This will require some thought.

I like this!

A possible suggestion: have the UI selector use a different color/font/italics or some other visual marker for the names of user-provided cards vs default cards. That way if two “Obsidian” entries are present, you can easily tell if it is the default Obsidian material or the user’s specific Obsidian material card.

Or, to make later python scripting easier, the visual marker could simply be punctuation in the string. So, Obsidian vs *Obsidian. Or, [Obsidian] vs Obsidian.

Also, a way-into-the-future comment: from the point of view of the Path workbench, I’ve long been hoping to use materials to control cutting paths with wood. These changes get me half-way there; allowing me to change travel and spin speeds based on specie of wood.

ignore the comment below. Having reviewed the forum and other items, people have been wanting grain direction, but again, I’d make that a “later project”:

But the materials are currently assumed to be isomorphic: they don’t have a direction (a 3d vector). It would be nice, if one day, they could have one. That way the spindle can change directions, speeds, (or even mill bit) depending on whether it is cutting cross-grain, with-grain, or an angle. And it would be nice if the visuals also showed the grain direction.

But adding a vector is probably a “something to do later” thing. IMO, I wouldn’t worry about it right now. Not many people are clamoring for it. :smiley:

Will the UUID change on each edit or only upon “creation”? What happens when a material is created and sent to a colleague, they edit parameters (like moduli, yield stress) and send it back. These are now two different materials with the same name. Are they related? Do they have the same or different UUID?

I think wood and other anisotropy should be represented by a field (can be spatially varying), and certainly not a vector defined in the material. Wood can be bent (e.g., steamed to make ribs in a boat), carbon fiber can be oriented arbitrarily, etc. Note that a vector (field) is not sufficient for general anisotropy. Equivariant constitutive models (those satisfying reference frame invariance) are typically modeled using a material tensor field.