Formerly ianmackenzie/elm-step-file. Search finds this package by either name.
This module allows you to encode data in ISO 10303-21 (STEP file) format.
Here is a sample STEP file (adapted from Wikipedia):
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('A minimal AP214 example with a single part'),'2;1');
FILE_NAME('demo','2003-12-27T11:57:53',('Lothar Klein'),('LKSoft'),' ','IDA-STEP',' ');
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 2 1 1}'));
ENDSEC;
DATA;
#10=ORGANIZATION('O0001','LKSoft','company');
#11=PRODUCT_DEFINITION_CONTEXT('part definition',#12,'manufacturing');
#12=APPLICATION_CONTEXT('mechanical design');
#13=APPLICATION_PROTOCOL_DEFINITION('','automotive_design',2003,#12);
#14=PRODUCT_DEFINITION('0',$,#15,#11);
#15=PRODUCT_DEFINITION_FORMATION('1',$,#16);
#16=PRODUCT('A0001','Test Part 1','',(#18));
#17=PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#16));
#18=PRODUCT_CONTEXT('',#12,'');
#19=APPLIED_ORGANIZATION_ASSIGNMENT(#10,#20,(#16));
#20=ORGANIZATION_ROLE('id owner');
ENDSEC;
END-ISO-10303-21;To create this file using this package, you could write
module Example exposing (..)
import Step.Encode as Encode
stepFile : String
stepFile =
let
header =
{ description = [ "A minimal AP214 example with a single part" ]
, implementationLevel = "2;1"
, fileName = "demo"
, timeStamp = "2003-12-27T11:57:53"
, author = [ "Lothar Klein" ]
, organization = [ "LKSoft" ]
, preprocessorVersion = " "
, originatingSystem = "IDA-STEP"
, authorization = " "
, schemaIdentifiers = [ "AUTOMOTIVE_DESIGN { 1 0 10303 214 2 1 1}" ]
}
applicationContext =
Encode.entity "APPLICATION_CONTEXT"
[ Encode.string "mechanical design"
]
applicationProtocolDefinition =
Encode.entity "APPLICATION_PROTOCOL_DEFINITION"
[ Encode.string ""
, Encode.string "automotive_design"
, Encode.int 2003
, Encode.referenceTo applicationContext
]
product =
Encode.entity "PRODUCT"
[ Encode.string "A0001"
, Encode.string "Test Part 1"
, Encode.string ""
, Encode.list Encode.referenceTo
[ Encode.entity "PRODUCT_CONTEXT"
[ Encode.string ""
, Encode.referenceTo applicationContext
, Encode.string ""
]
]
]
productDefinition =
Encode.entity "PRODUCT_DEFINITION"
[ Encode.string "0"
, Encode.null
, Encode.referenceTo <|
Encode.entity "PRODUCT_DEFINITION_FORMATION"
[ Encode.string "1"
, Encode.null
, Encode.referenceTo product
]
, Encode.referenceTo <|
Encode.entity "PRODUCT_DEFINITION_CONTEXT"
[ Encode.string "part definition"
, Encode.referenceTo applicationContext
, Encode.string "manufacturing"
]
]
productRelatedProductCategory =
Encode.entity "PRODUCT_RELATED_PRODUCT_CATEGORY"
[ Encode.string "part"
, Encode.null
, Encode.list Encode.referenceTo [ product ]
]
appliedOrganizationAssignment =
Encode.entity "APPLIED_ORGANIZATION_ASSIGNMENT"
[ Encode.referenceTo <|
Encode.entity "ORGANIZATION"
[ Encode.string "O0001"
, Encode.string "LKSoft"
, Encode.string "company"
]
, Encode.referenceTo <|
Encode.entity "ORGANIZATION_ROLE"
[ Encode.string "id owner"
]
, Encode.list Encode.referenceTo [ product ]
]
in
Encode.file header
[ applicationContext
, applicationProtocolDefinition
, productDefinition
, productRelatedProductCategory
, appliedOrganizationAssignment
]Note that entities can be declared directly 'inside' other entities where this
makes sense, and not all entities have to be explicitly listed in the
Encode.file call, only top-level ones. Any entities directly or indirectly
referenced by the listed entities will also be included in the output. Entity
IDs are automatically generated and entities may be written out in arbitrary
order.
Construct a single simple entity with the given type and attributes. The
type name will be capitalized if necessary. An IfcDirection
representing the positive Y direction in 3D could be created using
direction =
Encode.entity "IFCDIRECTION"
[ Encode.list Encode.float [ 0, 1, 0 ]
]which might get encoded as #1=IFCDIRECTION((0.,1.,0.));.
If a given entity is only referred to by a single other entity, you can create it directly inside the definition of the parent entity. For example, to create entity #121 from this AP214 example, you could use
Encode.entity "AXIS2_PLACEMENT_3D"
[ Encode.string ""
, Encode.referenceTo <|
Encode.entity "CARTESIAN_POINT"
[ Encode.string ""
, Encode.list Encode.float [ 20, 7.5, 0 ]
]
, Encode.referenceTo <|
Encode.entity "DIRECTION"
[ Encode.string ""
, Encode.list Encode.float [ 1, 0, 0 ]
]
, Encode.referenceTo <|
Encode.entity "DIRECTION"
[ Encode.string ""
, Encode.list Encode.float [ 0, 0, -1 ]
]
]When actually encoded to a STEP file, this will get converted into four separate entities, with the top-level entity referring to the other three by their automatically-generated IDs, something like:
#1=AXIS2_PLACEMENT_3D('',#2,#3,#4);
#2=CARTESIAN_POINT('',(20.,7.5,0.));
#3=DIRECTION('',(1.,0.,0.));
#4=DIRECTION('',(0.,0.,-1.));Construct a single 'complex entity'; for example
Encode.complexEntity
[ ( "A", [ Encode.int 1 ] )
, ( "B"
, [ Encode.int 2
, Encode.string "three"
]
)
, ( "C", [ Encode.enum "FOUR" ] )
]will be encoded as
#1=(A(1)B(2,'three')C(.FOUR.));The special 'derived value' attribute (* in the resulting STEP file).
The special 'null value' attribute ($ in the resulting STEP file).
Encode a Maybe either using the given decoder if it is a Just value, or
as null if it is Nothing.
Construct a Boolean-valued attribute.
Boolean values are actually encoded as enumeration values .T. and .F..
Construct an integer-valued attribute.
Construct a real-valued attribute.
Construct a string-valued attribute. Unicode characters will be properly escaped according to the (weird, custom) method specified in the STEP standard; for example,
Encode.string "see § 4.1"will end up being encoded as
'see \X\A7 4.1'Construct a reference to another STEP entity (will end up being encoded
using an integer ID in the resulting STEP file, e.g. #123).
Construct an attribute that refers to an enumeration value defined in an
EXPRESS schema. Enumeration values are always encoded as all-caps with leading
and trailing periods, like .STEEL..
This function will capitalize and add periods if necessary, so both
Encode.enum "steel" and Encode.enum ".STEEL." will be encoded as
.STEEL..
Construct a binary-valued attribute. The provided string is assumed to already be hex encoded as required by the STEP standard.
Construct an attribute which is itself a list of other attributes. You provide a list of values and a function to convert each of those values to an attribute (which will usually be one of the attribute construction functions in this module!). For example, to construct an attribute which is a list of floats:
Encode.list Encode.float [ 0, 1, 0 ]To construct a list of references to various entities:
Encode.list Encode.referenceTo
[ firstEntity
, secondEntity
, thirdEntity
]In the odd case where you already have a List Attribute, you can use Elm's
built-in identity function as the first argument:
Encode.list identity
[ firstAttribute
, secondAttribute
, thirdAttribute
]Encode a tuple of two values as a list using the given encoding function.
Encode a tuple of three values as a list using the given encoding function.
Typed attributes are sometimes needed when dealing with SELECT types.
Construct a type-tagged Boolean-valued attribute.
Construct a type-tagged integer-valued attribute.
Construct a type-tagged float-valued attribute.
Construct a type-tagged string-valued attribute.
Construct a type-tagged enumeration attribute.
Construct a type-tagged binary-valued attribute.
Construct a type-tagged list attribute.
Build a string representing a complete STEP file from a header and a list of entities. Entities will be assigned integer IDs automatically, and nested entities (entities that reference other entities) will be 'flattened' into separate entities referring to each other by their automatically-generated IDs.
Note that it is not actually necessary to list all entities explicitly, only top-level ones; any entities that are referenced by entities in the given list will also get included in the output.