import AP214StepModel from "./ap214_step_model.js"; import { AP214ProductShapeMap } from "./ap214_product_shape_map.js"; /** * A node in the extracted STEP product / assembly structure. * * The structure is *occurrence*-keyed, not product-keyed: STEP instancing lets * one `product_definition` (a part *type*) appear many times in an assembly via * distinct `next_assembly_usage_occurrence` (NAUO) edges. A scalar express id of * the product cannot tell two visual instances apart, so each occurrence node * carries both its NAUO express id (`expressID`) and the ordered * `occurrencePath` (root→node, NAUO ids) that is the stable * selection / permalink token. See * `design/new/step-metadata-nist.md` §"Occurrence identity". * * This is the forcing function for Share's goal of generalizing its scalar * `expressID` selection key into a format-agnostic *occurrence path* — flag it * wherever this tree is consumed Share-side. */ export interface ProductStructureNode { /** * Node selection key. For an occurrence node this is the NAUO express id; for * a root (single-part files have no NAUO) it falls back to the * `product_definition` express id. */ expressID: number; /** * Readable node kind: `'product'` for roots, `'product_occurrence'` for NAUO * nodes, `'solid'` for ephemeral sub-product solid nodes. */ type: string; /** Display label: `product.name`, falling back to the NAUO name / reference designator. */ name: string; /** Express id of the underlying `product_definition` (the part *type*). */ productDefinitionExpressID: number; /** NAUO express id for occurrence nodes; `undefined` for roots. */ occurrenceExpressID?: number; /** * Ordered occurrence path (NAUO express ids) from the top-level occurrence to * this node. Empty for roots. Disambiguates instances of the same part — e.g. * `[3810, 1921, 1910]` vs `[6217, 1921, 1910]` for the two bolts in `as1`. */ occurrencePath: number[]; /** * Shape representation express ids linked to this part (via * `product_definition_shape` → `shape_definition_representation`). The seam to * scene geometry for NavTree-click ⇄ viewport-pick round-tripping. */ shapeRepresentationIds: number[]; /** Child occurrence nodes (and, when opted in, ephemeral solid nodes). */ children: ProductStructureNode[]; /** * True for ephemeral (non-product) nodes — pickable geometry that carries * identity in the file but has no product semantics, e.g. one named solid of * a multibody part. Consumers should render these lighter-weight, * selectable-but-not-product. See `design/new/step-nonproduct-semantics.md`. */ ephemeral?: boolean; /** * Number of this node's solids suppressed by the ephemeral-layer limits * (unnamed-soup suppression or the per-product cap), so a consumer can * render an "N more…" affordance instead of silently truncating. */ droppedSolids?: number; } /** * Options for {@link AP214ProductStructureExtraction.extractProductStructure}. */ export interface ProductStructureOptions { /** * Surface an ephemeral layer of solid-level nodes beneath each multibody * product (default false). A product only gets solid children when its shape * representation holds at least two solids — a single-solid product already * maps 1:1 onto its node — and an all-unnamed set larger than * {@link maxUnnamedSolidsPerProduct} is suppressed as meaningless "solid * soup" (the DSA2 case: 28k unnamed single-face shells under one product). */ includeSolids?: boolean; /** * Hard cap on emitted solid children per product occurrence * (default {@link DEFAULT_MAX_SOLIDS_PER_PRODUCT}); overflow is reported via * {@link ProductStructureNode.droppedSolids}. */ maxSolidsPerProduct?: number; /** * When a product's solids are *all* unnamed and outnumber this (default * {@link DEFAULT_MAX_UNNAMED_SOLIDS_PER_PRODUCT}), emit none of them: * large anonymous solid dumps (ECAD merged-component products, tessellated * surface soup) carry no navigable semantics. Named solids are never * suppressed by this limit. */ maxUnnamedSolidsPerProduct?: number; } /** Default hard cap on emitted solid children per product occurrence. */ export declare const DEFAULT_MAX_SOLIDS_PER_PRODUCT = 256; /** Default suppression threshold for a product whose solids are all unnamed. */ export declare const DEFAULT_MAX_UNNAMED_SOLIDS_PER_PRODUCT = 32; /** * Extracts the STEP product / assembly structure from a populated * {@link AP214StepModel} into a nested, named, occurrence-keyed tree. * * Mirrors the IFC precedent (`src/ifc/ifc_property_extraction.ts`) but for * AP214/AP242: walks `product` / `product_definition` / * `next_assembly_usage_occurrence` into a tree, resolves labels from * `product.name`, and links each part to its shape representations so a NavTree * node can highlight the right geometry instance. */ export declare class AP214ProductStructureExtraction { private readonly model; private readonly productShapeMap?; private readonly nauosByParent_; private readonly childProductDefIds_; private readonly productDefById_; private readonly shapeRepsByProductDef_; private readonly solidsByProductDef_; private readonly solidIdsByProductDef_; private includeSolids_; private maxSolidsPerProduct_; private maxUnnamedSolidsPerProduct_; /** * @param model The populated AP214/AP242 step model to walk. * @param productShapeMap Optional product↔shape map populated during geometry * extraction. When provided its links are merged with the ones derived here so * the tree's `shapeRepresentationIds` agree with the scene; the map is empty * unless geometry extraction has run, so the entity-graph walk below is the * primary source. */ constructor(model: AP214StepModel, productShapeMap?: AP214ProductShapeMap | undefined); /** * Build the product-structure tree. * * @param options Optional {@link ProductStructureOptions}; pass * `{ includeSolids: true }` to add the ephemeral solid layer beneath * multibody products. * @return {ProductStructureNode[]} The roots of the assembly forest. A * single-part file yields one root; a multi-level assembly (e.g. `as1`) yields * one root whose descendants are the NAUO occurrences. */ extractProductStructure(options?: ProductStructureOptions): ProductStructureNode[]; /** * Index every `product_definition` by express id for O(1) lookup during the * recursive walk. */ private indexProductDefinitions; /** * Index every NAUO by its parent (`relating_product_definition`) express id * and record which product definitions appear as a child * (`related_product_definition`) so roots can be identified. */ private indexAssemblyUsages; /** * Link product definitions to their shape representations by walking * `shape_definition_representation` → `product_definition_shape` → * `product_definition`, and merge any links already present in the * geometry-extraction product↔shape map. */ private indexShapeRepresentations; /** * Index the solid-level bodies of each product definition for the ephemeral * layer: walk each `shape_definition_representation`'s representation, plus * any representation reachable over a *plain* `shape_representation_relationship` * (SolidWorks binds a part's multibody `advanced_brep_shape_representation` * to its SDR-bound representation that way — the NEMA motor pattern), and * collect the solid items. Transformation-bearing relationship variants are * assembly placements (parent rep ↔ child rep), so following them would leak * every child part's solids into its parent assembly; they are skipped. */ private indexSolids; /** * Record a solid for a product definition, de-duplicating by the solid's * express id (a body can be reachable both directly and over a * representation relationship). * * @param productDefId The owning product definition express id. * @param solid The solid to record. */ private addSolid; /** * Record a shape-representation id for a product definition, de-duplicating. * * @param productDefId The product definition express id. * @param shapeId The shape representation express id to associate. */ private addShapeRepresentation; /** * Recursively build a tree node for one product-definition occurrence. * * @param productDef The product definition this node represents. * @param occurrence The NAUO edge that introduced this occurrence, or * `undefined` for a root. * @param parentPath The occurrence path of the parent node (NAUO ids). * @param onPath Product-definition ids currently on the recursion stack; * guards against a malformed cyclic assembly causing infinite recursion (a * legitimately re-used part in sibling branches is unaffected). * @return {ProductStructureNode} The built node, with children. */ private buildNode; /** * Append this node's ephemeral solid children, applying the layer's * heuristics (see {@link ProductStructureOptions}): nothing for a * single-solid product, full suppression for oversized all-unnamed sets, * and the hard per-product cap — suppressed/overflow counts are surfaced * via {@link ProductStructureNode.droppedSolids}. * * @param node The product/occurrence node to attach solid children to. */ private appendSolidChildren; /** * Resolve a node label, preferring the product name, then the occurrence's * own name / reference designator. * * @param productDef The product definition for the node. * @param occurrence The NAUO edge, when this is an occurrence node. * @return {string} The best available human-readable label. */ private resolveLabel; /** * Resolve the owning `product_definition` express id from a * `property_definition`-style `definition` select. Handles the direct * `product_definition` case and the `product_definition_shape` indirection * (its own `definition` points at the product definition). * * @param definition The resolved `definition` reference, or `undefined`. * @return {number | undefined} The product definition express id, or * `undefined` if it does not resolve to one. */ static resolveProductDefinitionId(definition: { expressID?: number; } | undefined): number | undefined; } //# sourceMappingURL=ap214_product_structure_extraction.d.ts.map