1515from typish import instance_of
1616from uuid import uuid1 as uuid
1717from warnings import warn
18+ from itertools import chain
1819
1920from .cq import Workplane
20- from .occ_impl .shapes import Shape , Compound , isSubshape
21+ from .occ_impl .shapes import Shape , Compound , isSubshape , compound
2122from .occ_impl .geom import Location
2223from .occ_impl .assembly import Color
2324from .occ_impl .solver import (
3839from .occ_impl .importers .assembly import importStep as _importStep , importXbf , importXml
3940
4041from .selectors import _expression_grammar as _selector_grammar
41- from .utils import deprecate
42+ from .utils import deprecate , BiDict
4243
4344# type definitions
4445AssemblyObjects = Union [Shape , Workplane , None ]
4849PATH_DELIM = "/"
4950
5051# entity selector grammar definition
52+
53+
5154def _define_grammar ():
5255
5356 from pyparsing import (
@@ -98,9 +101,9 @@ class Assembly(object):
98101 constraints : List [Constraint ]
99102
100103 # Allows metadata to be stored for exports
101- _subshape_names : dict [Shape , str ]
102- _subshape_colors : dict [Shape , Color ]
103- _subshape_layers : dict [Shape , str ]
104+ _subshape_names : BiDict [Shape , str ]
105+ _subshape_colors : BiDict [Shape , Color ]
106+ _subshape_layers : BiDict [Shape , str ]
104107
105108 _solve_result : Optional [Dict [str , Any ]]
106109
@@ -147,9 +150,9 @@ def __init__(
147150
148151 self ._solve_result = None
149152
150- self ._subshape_names = {}
151- self ._subshape_colors = {}
152- self ._subshape_layers = {}
153+ self ._subshape_names = BiDict ()
154+ self ._subshape_colors = BiDict ()
155+ self ._subshape_layers = BiDict ()
153156
154157 def _copy (self ) -> "Assembly" :
155158 """
@@ -158,9 +161,9 @@ def _copy(self) -> "Assembly":
158161
159162 rv = self .__class__ (self .obj , self .loc , self .name , self .color , self .metadata )
160163
161- rv ._subshape_colors = dict (self ._subshape_colors )
162- rv ._subshape_names = dict (self ._subshape_names )
163- rv ._subshape_layers = dict (self ._subshape_layers )
164+ rv ._subshape_colors = BiDict (self ._subshape_colors )
165+ rv ._subshape_names = BiDict (self ._subshape_names )
166+ rv ._subshape_layers = BiDict (self ._subshape_layers )
164167
165168 for ch in self .children :
166169 ch_copy = ch ._copy ()
@@ -754,40 +757,54 @@ def addSubshape(
754757
755758 return self
756759
757- def __getitem__ (self , name : str ) -> "Assembly" :
760+ def __getitem__ (self , name : str ) -> Union [ "Assembly" , Shape ] :
758761 """
759762 [] based access to children.
763+
760764 """
761765
762- return self .objects [name ]
766+ if name in self .objects :
767+ return self .objects [name ]
768+ elif name in self ._subshape_names .inv :
769+ rv = self ._subshape_names .inv [name ]
770+ return rv [0 ] if len (rv ) == 1 else compound (rv )
771+
772+ raise KeyError
763773
764774 def _ipython_key_completions_ (self ) -> List [str ]:
765775 """
766776 IPython autocompletion helper.
767777 """
768778
769- return list (self .objects .keys ())
779+ return list (chain ( self .objects .keys (), self . _subshape_names . inv . keys () ))
770780
771781 def __contains__ (self , name : str ) -> bool :
772782
773- return name in self .objects
783+ return name in self .objects or name in self . _subshape_names . inv
774784
775- def __getattr__ (self , name : str ) -> "Assembly" :
785+ def __getattr__ (self , name : str ) -> Union [ "Assembly" , Shape ] :
776786 """
777787 . based access to children.
778788 """
779789
780790 if name in self .objects :
781791 return self .objects [name ]
792+ elif name in self ._subshape_names .inv :
793+ rv = self ._subshape_names .inv [name ]
794+ return rv [0 ] if len (rv ) == 1 else compound (rv )
782795
783- raise AttributeError
796+ raise AttributeError ( f" { name } is not an attribute of { self } " )
784797
785798 def __dir__ (self ):
786799 """
787800 Modified __dir__ for autocompletion.
788801 """
789802
790- return list (self .__dict__ ) + list (ch .name for ch in self .children )
803+ return (
804+ list (self .__dict__ )
805+ + list (ch .name for ch in self .children )
806+ + list (self ._subshape_names .inv .keys ())
807+ )
791808
792809 def __getstate__ (self ):
793810 """
0 commit comments