Elements icon indicating copy to clipboard operation
Elements copied to clipboard

Make Representation an Element

Open ikeough opened this issue 4 years ago • 2 comments

This issue consolidates one part of the conversation started in #450. The reason that GeometricElement.IsElementDefinition and ElementInstance exist was solely to allow the sharing of geometric representations between elements with different transforms. It was overkill for the intended purpose however, and did not consider patterns that are already widely used and enforce separation of concerns in C# code like dependency injection. Instead of creating a new type, ElementInstance which references a base definition, we could have simply given every instance of a type with a shared representation a reference to that representation. This was impossible of course because we have no way of referencing a shared representation in a Model unless Representation becomes an element. That is what this enhancement proposes to do.

By making Representation inherit from Element, we gain the ability to store Representation instances in the Model in the same way that we store Material and Profile instances.

The enhancement proposes the following work.

  • Make Representation inherit from Element.
  • Make Material a property of Representation.
    • This is possibly the most controversial part of this proposal as a "material" in AEC provides both visual characteristics and mechanical properties. As Material currently only represents visual characteristics in Elements this associates the material with the representation for that purpose.
  • Create a base Representation class:
public abstract class Representation
{
  public Material Material {get;set;}

  public Representation(Material material)
  {
    this.Material = material;
  }
  
}
  • Create a new SolidRepresentation class which replaces the current method for creating CSGs from BREPs.
public class SolidRepresentation: Representation, IList<SolidOperation>
{
  public SolidRepresentation(Material material, solids): base(material){}
  // Implementation of IList<SolidOperation>
  ...
}
  • Create a new MeshRepresentation class.
public abstract class MeshRepresentation: Representation{}
  • Create classes for each path for mesh import.
public class STLImport: MeshRepresentation{...}
public class GlbImport: MeshRepresentation{...}
var rep = new SolidRepresentation();
rep.Add(new Extrude(...));
rep.Add(new Sweep(..., isVoid: true));

// Create two instances of Foo, which use the same representation but different transforms.
var foo1 = new Foo(instanceProp1, instanceProp2, ... transform1, rep, Guid.NewGuid(), "foo1");
var foo2 = new Foo(instanceProp3, instanceProp4, ..., transform2, rep, Guid.NewGuid(), "foo2");

// Create a representation from an import
var meshRep = new STLImport(stlPath);
var foo3 = new Foo(instanceProp5, instanceProp6, ..., transform3, meshRep, Guid.NewGuid(), "foo3"
  • Remove MeshElement
  • Remove ImportElement
  • Remove GeometricElement.IsElementDefinition
  • Remove GeometricElement.CreateInstance
  • Remove ElementInstance
  • Remove ITessellate

Serialization

  • Forward Migration
    • The IMigration framework is proposed in #482 to mutate JSON before deserialization to a state compatible with this version of elements.
  • Backward Migration
    • Existing Material and Representation properties are left in GeometricElement.json.
    • All properties are removed from the required array, to avoid the deserializer throwing a validation exception.
    • The Material and Representation properties are marked deprecated to enforce usage of the new properties.

Being implemented in:

  • [x] #471 - Improvements to type generation.
  • [x] #472 - Mesh serialization.
  • [ ] #489 - Representation as an Element.

ikeough avatar Nov 23 '20 23:11 ikeough

@andrewheumann @wynged I believe this addresses a number of concerns that we discussed.

ikeough avatar Nov 23 '20 23:11 ikeough

There is a further simplification to the object model that can be made by collapsing GeometricElement into Element, and adding a HasRepresentation property. Then a developer can do a check whether the element visualizes by saying if(foo.HasRepresentation)....

ikeough avatar Nov 23 '20 23:11 ikeough