- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi there,
We have a large AutoLISP codebase which provides a lot of extra functionality. One functionality is keeping a "label" together with an entity, such as a polyline:
This works using a persistent object reactor. By default, labels are not present on objects in a drawing. When users want to add a label to an object, they select entities to add these labels to. Our code then retrieves whether or not an object is already owned by a persistent object reactor, through (vlr-owners). We do this check to make sure there are no duplicate reactors, and to access the data via (vlr-data).
The current way we are doing this, is by looping through all persistent object reactors, checking what its (vlr-owners) are, and matching it with the entity we are looking for. The code for that looks like this:
;|
description: find what reactor belongs to a parent entity, by checking each reactor inside the current drawing
param: $entity - the parent entity
returns: the associated reactor, or nil if no reactor can be found
|;
(defun REA:GET_BY_ENTITY ($entity / $break $i $owners $reactor $reactors $vlaObject)
(setq $vlaObject (WTN:ENSURE_VLA $entity))
(setq $reactors (vlr-pers-list))
(setq $i 0
$break nil
)
(while (and (< $i (length $reactors)) (not $break))
(setq $reactor (nth $i $reactors))
(setq $owners (vlr-owners $reactor))
(if (/= (member $vlaObject $owners) nil)
(setq $break T)
)
(setq $i (1+ $i))
)
(if $break $reactor nil) ; if break has occurred, return reactor. otherwise no reactor found
)
This works great for a drawing with a few reactors. However, the drawings our users require can contain up to 10.000 entities and reactors. The performance tanks under these circumstances, and often just hangs.
Another approach we have attempted is generating an associated list with entity handles as keys, and reactor objects as values. The code for that looks like this:
;|
description: generate a list of entity handles and reactors
remarks: if a persistent reactor's owner is no longer present in the drawing, it is released (removed)
an association list with parent entity handles and the reactor it owns
|;
(defun REA:GET_MAP (/ fetch_entry $reactor $owner $entget $entity)
;|
description: returns reactor paired with the enthandle of the owner
remarks: local function for improved readability (instead of a lambda)
param: $reactor - current persistent reactor to process
returns: `(cons <enthandle> <reactor>)` or `nil`
|;
(defun fetch_entry ($reactor)
(if
(and (setq $owner (car (vlr-owners $reactor)))
(setq $entity (WTN:ENSURE_ENAME $owner))
(setq $entget (entget $entity))
)
(cons
(cdr (assoc 5 $entget))
$reactor
)
(progn
(vlr-pers-release $reactor)
(vlr-remove $reactor)
nil
)
)
)
(vl-remove-if 'null (mapcar 'fetch_entry (vlr-pers-list)))
)
We then query this map/dictionary for the entity handle of an object, and then retrieve the reactor it belongs to:
;|
description: find what reactor belongs to a parent entity, using a reactor map
param: $entity - the parent entity
param: $reactorMap - reactor map generated by `REA:GET_MAP`
returns: the associated reactor, or nil if no reactor can be found
|;
(defun REA:GET_FROM_MAP ($entity $reactorMap / $entget $handle)
(if
(and
(setq $entity (WTN:ENSURE_ENAME $entity))
(setq $entget (entget $entity))
(setq $handle (cdr (assoc 5 $entget)))
)
(cdr (assoc $handle $reactorMap))
nil
)
)
However, we are running into an issue here. When the drawing contains over 6000 reactors, AutoCAD will just hang when trying to generate this map/dictionary using REA:GET_MAP.
We have thought of a way to fix it. As we are in full control of when these reactors are created and added, we could write some kind of link into each entity as to what object reactor belongs to it. But it seems that persistent object reactors do not have a unique ID.
Now our question is: Is it true that persistent object reactors do not have a unique ID we can store somewhere and retrieve when needed? Is there any way we can get a persistent reactor belonging to an object without iterating through all persistent reactors, and thus tanking the performance?
Thank you for reading this, if you have come this far. We hope the community can help us progress with our AutoLISP scripts. If you need more information or context, feel free to ask.
-Sem
Solved! Go to Solution.