Community Tip - When posting, your subject should be specific and summarize your question. Here are some additional tips on asking a great question. X
Hello,
I am trying to write a LISP routine to iteratively create views of all open models.
I found some stuff on the internet but am not able to modify it properly to get what I want. I also tried using the inbuilt Recorder to get some lisp..
Can someone help me on how do I loop through a list of things.. parts in this case and perform a set of actions on each of them? Basically like For each element in... do XYZ...
Thanks,
Shweta
This is probably similar in concept to what you are looking for.
Here's a working example of a piece of code that'll create configurations for all parts that DON'T match some naming patterns, provided they have a model or "contents" name is set.
It looks fairly complicated due to the specific qualifiers for parts to ignore, and the requirements that contents name. This code can create a nice pile of configurations with one of each part shown in the viewport.
(use-package :oli)
; (LoadCode "create_conf") SIMPLE_CONFIGURATIONS
(sd-defdialog 'SIMPLE_CONFIGURATIONS
:dialog-title "SIMPLE CONFIGURATIONS"
:variables '(
(MAIN_ASSEMBLY_object :TITLE "MAIN_ASSEMBLY" :value-type :assembly :initial-value nil)
)
:ok-action
'(progn
(setf MAIN_ASSEMBLY_name (SD-INQ-OBJ-CONTENTS-NAME MAIN_ASSEMBLY_object))
(setf MAIN_ASSEMBLY_path (SD-INQ-OBJ-PATHNAME MAIN_ASSEMBLY_object))
(setf list_of_patterns_to_ignore (list "X*" "287*" "G*" "E*" "S*"))
;; get a list of all parts in a assembly, (recursively)
(setf list_of_all_parts (sd-call-cmds (get_selection :allow_face_part :allow_wire_part :focus_type *sd-part-seltype* :select :recursive :in_assembly MAIN_ASSEMBLY_object)))
;; new empty list
(setf list_of_unique_parts '())
;;iterate over every part
(dolist (obj list_of_all_parts)
;; continue if the contents name has been set, otherwise skip this object
(if (not (null(SD-INQ-OBJ-CONTENTS-NAME OBJ)))
(progn
; Reset the ignore pattern
(setf ignorematch nil)
(setf current_part_name (SD-INQ-OBJ-CONTENTS-NAME obj) )
(dolist (pattern1 list_of_patterns_to_ignore)
(if (sd-string-match-pattern-p pattern1 current_part_name )
;; ignore pattern matched, ignore this part
(setf ignorematch t)
)
)
(if (null ignorematch) ; ignore pattern not matched
(when (null (FIND current_part_name list_of_unique_parts :test #'equal) )
;; if partname isn't found in list_of_unique_parts then, the configuration hasn't yet been created
(progn
;; add the part name to list_of_unique_parts so only one configuration will be made
(setf list_of_unique_parts (cons current_part_name list_of_unique_parts))
;; new string - a configuration name with part name embedded
(setf new_configuration_name (format nil "CONFIGURATION_~A" current_part_name))
;; drawlist1 is what objects to show in the configuration
(setf drawlist1 (list obj))
;; created a new configuration, overwrite any existing configurations
(sd-create-configuration :name new_configuration_name :name-conflict :delete-old :owner MAIN_ASSEMBLY_object :drawlist drawlist1 )
;; define my_list as the current list of all configurations in MAIN_ASSEMBLY_object
(setf my_list (sd-inq-configurations :owner MAIN_ASSEMBLY_object))
;; loop list of configurations
(dolist (configuration_obj my_list)
;;until current configuration is found
(if (sd-string-match-pattern-p ( getf (sd-inq-configuration-props configuration_obj) :NAME) new_configuration_name)
(progn
;; activate the current configuration
(sd-call-cmds (cfn_activate_configuration :CONFIG configuration_obj :ALL_VPS t))
;; fit part to current viewport window
(fit_vp (sd-inq-current-vp))
;;Capture camera and drawlist for current configuration
(cfn_capture :consider_drawlist :ON :consider_camera :ON :config configuration_obj :end_name complete)
);;progn
);;if
);;dolist
);;progn
);;when
);;if
);;progn
);;if
);;dolist
);;progn for ok-action
) ;; (sd-defdialog
Hey thanks for the response.
What I was trying to do is simpler, I could use a dolist to iterate through all visible parts and create a new drawing with a few views for each.
Can you explain more about what you mean by "views of all open models"? Do you want these views on a drawing in Annotation? If there are assemblies, do you want views of the individual models, or of the assemblies, or both?
Hi, Thanks for the response.
No there aren't any assemblies. Just parts.
Actually since I am new to Lisp (and CED) not sure if I used the right terminologies..
"views of all open models" meaning all parts visible in the current viewport.
But I could do it now, using a dolist on the list of visible parts, to place a few views in a different drawing for each part.
Yes using Annotation.
But I have a different query now...which I will post 🙂
For multiple parts, you can start with a Dialog (similar to what Pete provided) which selects multiple parts (instead of an assembly). However, that is only the first step of developing a non-trivial Dialog in LISP.
The programming Language is LISP, but experience with the SolidDesigner I-KIT is required as well.
You could use this command:
(setf my_parts (sd-inq-vp-drawlist-objects (oli::sd-inq-current-vp)))
The result is a list with all items that have a black checkbox in front of them in the browser (that is, not the grey ones).
However, if an assy is completely visible, it's children are not in that list. So you'd have to loop through it's children in order to get all parts.
Another trick could be to use this function in order to obtain all models below an assy:
(defun jb-inq-obj-tree-list (obj)
(cons obj
(apply #'nconc
(mapcar #'jb-inq-obj-tree-list
(sd-inq-obj-children obj)
)
)
)
)
If you call it with:
(setf all_items (jb-inq-obj-tree-list (sd-pathname-to-obj "/")))
you have all items in session.
Then, you could go through this list and check if it's visible with this function:
(sd-inq-vp-drawlist-member-p vport obj)
Regards,
Jaap