3737from ansys .geometry .core .connection .client import GrpcClient
3838from ansys .geometry .core .connection .defaults import DEFAULT_HOST , DEFAULT_PORT
3939from ansys .geometry .core .errors import GeometryRuntimeError , protect_grpc
40- from ansys .geometry .core .logger import LOG
41- from ansys .geometry .core .misc .checks import check_type , min_backend_version
40+ from ansys .geometry .core .misc .checks import check_type , deprecated_method , min_backend_version
4241from ansys .geometry .core .misc .options import ImportOptions
4342from ansys .geometry .core .tools .measurement_tools import MeasurementTools
4443from ansys .geometry .core .tools .prepare_tools import PrepareTools
@@ -120,15 +119,15 @@ def __init__(
120119 backend_type = backend_type ,
121120 )
122121
123- # Maintaining references to all designs within the modeler workspace
124- self ._designs : dict [ str , "Design" ] = {}
122+ # Single design for the Modeler
123+ self ._design : Optional [ "Design" ] = None
125124
126125 # Initialize the RepairTools - Not available on Linux
127126 # TODO: delete "if" when Linux service is able to use repair tools
128127 # https://github.com/ansys/pyansys-geometry/issues/1319
129128 if BackendType .is_core_service (self .client .backend_type ):
130129 self ._measurement_tools = None
131- LOG .warning ("CoreService backend does not support measurement tools." )
130+ self . client . log .warning ("CoreService backend does not support measurement tools." )
132131 else :
133132 self ._measurement_tools = MeasurementTools (self ._grpc_client )
134133
@@ -138,28 +137,26 @@ def __init__(
138137 self ._geometry_commands = GeometryCommands (self ._grpc_client )
139138 self ._unsupported = UnsupportedCommands (self ._grpc_client , self )
140139
141- # Check if the backend allows for multiple designs and throw warning if needed
142- if not self .client .multiple_designs_allowed :
143- LOG .warning (
144- "Linux and Ansys Discovery backends do not support multiple "
145- "designs open in the same session. Only the last design created "
146- "will be available to perform modeling operations."
147- )
148-
149140 @property
150141 def client (self ) -> GrpcClient :
151142 """``Modeler`` instance client."""
152143 return self ._grpc_client
153144
154145 @property
146+ def design (self ) -> "Design" :
147+ """Retrieve the design within the modeler workspace."""
148+ return self ._design
149+
150+ @property
151+ @deprecated_method (alternative = "design" )
155152 def designs (self ) -> dict [str , "Design" ]:
156- """All designs within the modeler workspace.
153+ """Retrieve the design within the modeler workspace.
157154
158155 Notes
159156 -----
160- This property is read-only. **DO NOT** modify the dictionary .
157+ This method is deprecated. Use the :func:`design` property instead .
161158 """
162- return self ._designs
159+ return { self ._design . id : self . _design }
163160
164161 def create_design (self , name : str ) -> "Design" :
165162 """Initialize a new design with the connected client.
@@ -177,14 +174,20 @@ def create_design(self, name: str) -> "Design":
177174 from ansys .geometry .core .designer .design import Design
178175
179176 check_type (name , str )
177+
178+ # If a previous design was available... inform the user that it will be deleted
179+ # when creating a new design.
180+ if self ._design is not None and self ._design .is_active :
181+ self .client .log .warning ("Closing previous design before creating a new one." )
182+ self ._design .close ()
183+
184+ # Create the new design
180185 design = Design (name , self )
181- self ._designs [design .design_id ] = design
182- if len (self ._designs ) > 1 :
183- LOG .warning (
184- "Some backends only support one design. "
185- + "Previous designs may be deleted (on the service) when creating a new one."
186- )
187- return self ._designs [design .design_id ]
186+
187+ # Update the design stored in the modeler
188+ self ._design = design
189+
190+ return self ._design
188191
189192 def get_active_design (self , sync_with_backend : bool = True ) -> "Design" :
190193 """Get the active design on the modeler object.
@@ -201,14 +204,13 @@ def get_active_design(self, sync_with_backend: bool = True) -> "Design":
201204 Design
202205 Design object already existing on the modeler.
203206 """
204- for _ , design in self ._designs .items ():
205- if design ._is_active :
206- # Check if sync_with_backend is requested
207- if sync_with_backend :
208- design ._update_design_inplace ()
209-
210- # Return the active design
211- return design
207+ if self ._design is not None and self ._design .is_active :
208+ # Check if sync_with_backend is requested
209+ if sync_with_backend :
210+ self ._design ._update_design_inplace ()
211+ return self ._design
212+ else :
213+ self .client .log .warning ("No active design available." )
212214
213215 return None
214216
@@ -222,43 +224,45 @@ def read_existing_design(self) -> "Design":
222224 """
223225 from ansys .geometry .core .designer .design import Design
224226
225- design = Design ("" , self , read_existing_design = True )
226- self ._designs [design .design_id ] = design
227- if len (self ._designs ) > 1 :
228- LOG .warning (
229- "Some backends only support one design. "
230- + "Previous designs may be deleted (on the service) when reading a new one."
231- )
232- return self ._designs [design .design_id ]
227+ # Simply deactivate the existing design in case it is active...
228+ # - If it is the same design, it will be re-read (but we should not close it on the server)
229+ # - If it is a different design, it was closed previously (via open_file or create_design)
230+ if self ._design is not None and self ._design .is_active :
231+ self ._design ._is_active = False
233232
234- def close (self , close_designs : bool = True ) -> None :
233+ self ._design = Design ("" , self , read_existing_design = True )
234+
235+ return self ._design
236+
237+ def close (self , close_design : bool = True ) -> None :
235238 """Access the client's close method.
236239
237240 Parameters
238241 ----------
239- close_designs : bool, default: True
240- Whether to close all designs before closing the client.
242+ close_design : bool, default: True
243+ Whether to close the design before closing the client.
241244 """
242- # Close all designs (if requested)
243- [design .close () for design in self ._designs .values () if close_designs ]
245+ # Close design (if requested)
246+ if close_design and self ._design is not None :
247+ self ._design .close ()
244248
245249 # Close the client
246250 self .client .close ()
247251
248- def exit (self , close_designs : bool = True ) -> None :
252+ def exit (self , close_design : bool = True ) -> None :
249253 """Access the client's close method.
250254
251255 Parameters
252256 ----------
253- close_designs : bool, default: True
254- Whether to close all designs before closing the client.
257+ close_design : bool, default: True
258+ Whether to close the design before closing the client.
255259
256260 Notes
257261 -----
258262 This method is calling the same method as
259263 :func:`close() <ansys.geometry.core.modeler.Modeler.close>`.
260264 """
261- self .close (close_designs = close_designs )
265+ self .close (close_design = close_design )
262266
263267 def _upload_file (
264268 self ,
@@ -301,7 +305,7 @@ def _upload_file(
301305 with fp_path .open (mode = "rb" ) as file :
302306 data = file .read ()
303307
304- c_stub = CommandsStub (self ._grpc_client .channel )
308+ c_stub = CommandsStub (self .client .channel )
305309
306310 response = c_stub .UploadFile (
307311 UploadFileRequest (
@@ -348,6 +352,10 @@ def open_file(
348352 # Use str format of Path object here
349353 file_path = str (file_path ) if isinstance (file_path , Path ) else file_path
350354
355+ # Close the existing design if it is active
356+ if self ._design is not None and self ._design .is_active :
357+ self ._design .close ()
358+
351359 # Format-specific logic - upload the whole containing folder for assemblies
352360 if upload_to_server :
353361 if any (
@@ -361,7 +369,7 @@ def open_file(
361369 self ._upload_file (full_path )
362370 self ._upload_file (file_path , True , import_options )
363371 else :
364- DesignsStub (self ._grpc_client .channel ).Open (
372+ DesignsStub (self .client .channel ).Open (
365373 OpenRequest (filepath = file_path , import_options = import_options .to_dict ())
366374 )
367375
@@ -372,7 +380,7 @@ def __repr__(self) -> str:
372380 lines = []
373381 lines .append (f"Ansys Geometry Modeler ({ hex (id (self ))} )" )
374382 lines .append ("" )
375- lines .append (str (self ._grpc_client ))
383+ lines .append (str (self .client ))
376384 return "\n " .join (lines )
377385
378386 @protect_grpc
@@ -468,7 +476,7 @@ def run_discovery_script_file(
468476 api_version = ApiVersions .parse_input (api_version )
469477
470478 serv_path = self ._upload_file (file_path )
471- ga_stub = DbuApplicationStub (self ._grpc_client .channel )
479+ ga_stub = DbuApplicationStub (self .client .channel )
472480 request = RunScriptFileRequest (
473481 script_path = serv_path ,
474482 script_args = script_args ,
0 commit comments