(in-package :ag-custom) (use-package :oli) (setq *inspection-dimension-delimiter* "|") (setq *inspection-dimension-table-sketch-name* "inspection-dimension-table") (sd-defdialog 'inspection-dimension :precondition '(if (sd-am-inq-curr-sheet-name) :ok :error) :dialog-title "Inspection dimension" :toolbox-button :force :variables '( ("Inspection dimension flags") ("-") (dimension-add :title "Create flag" :selection *sd-anno-dimension-seltype* :prompt-text "Select dimensions to create inspection dimension flag(s)." :multiple-items nil :next-variable 'dimension-add :after-input (progn (create-inspection-dimension-flag dimension-add next-index-no) (setq next-index-no (read-from-string (get-next-inspection-dimension-index))))) (next-index-no :title "Flag index" :value-type :positive-integer :initial-value (read-from-string (get-next-inspection-dimension-index)) :next-variable 'dimension-add :initial-enable nil) (manual-overwrite-index :title "Set index manually" :toggle-type :wide-toggle :value-type :boolean :initial-value nil :next-variable 'next-index-no :after-input (sd-set-variable-status 'next-index-no :enable manual-overwrite-index)) (dimension-remove :title "Remove flag" :selection *sd-anno-dimension-seltype* :prompt-text "Select dimensions to remove inspection dimension flag(s)." :multiple-items t :next-variable 'dimension-remove :after-input (progn (remove-inspection-dimension-flag dimension-remove) (setq next-index-no (read-from-string (get-next-inspection-dimension-index))))) (resort-button :title "Resort flags" :toggle-type :wide-toggle :push-action (progn (resort-inspection-dimension-flags) (setq next-index-no (read-from-string (get-next-inspection-dimension-index))))) ("-") ("Table") (preview :title "Preview" :expand-shrink (show-table-button hide-table-button)) (show-table-button :title "Show inspection dimensions" :toggle-type :wide-toggle :push-action (show-inspection-dimension-table)) (hide-table-button :title "Hide inspection dimensions" :toggle-type :wide-toggle :push-action (sd-hide-display-table "inspection-dimension-display-table")) ("-") (start-pnt :title "Start point" :value-type :docupoint :prompt-text "Select position for inspection dimension table." :after-input (create-inspection-dim-table-on-sheet :start-pnt start-pnt :sketch-name *inspection-dimension-table-sketch-name* :row-heights row-height :text-style text-style :grow-dir-vertical (if (or ul-corner ur-corner) :down :up) :grow-dir-horizontal (if (or ll-corner ul-corner) :right :left) :header-position (if header-on-top :top :bottom) :sort (if grow-dir-data-ascending :ascending :descending))) (table-settings :title "Settings" :expand-shrink ( row-height text-style table-sort grow-dir-data-ascending grow-dir-data-descending table-header header-on-top header-on-bottom table-orientation ul-corner ur-corner ll-corner lr-corner)) (row-height :title "Row height" :value-type :positive-number :initial-value 5.5) (text-style :titel "Text style" :range (:standard :large :small :medium)) (table-sort :title "Sort") (grow-dir-data-ascending :title "Ascending" :toggle-type :grouped-toggle :value-type :boolean :initial-value t) (grow-dir-data-descending :title "Descending" :toggle-type :grouped-toggle :value-type :boolean) (table-header :title "Header") (header-on-top :title "Top" :toggle-type :grouped-toggle :value-type :boolean :initial-value t) (header-on-bottom :title "Bottom" :toggle-type :grouped-toggle :value-type :boolean) (table-orientation :title "Orientation") (ul-corner :title "┌────" :value-type :boolean :toggle-type :grouped-toggle :indicator-type :none :after-input (progn (setq grow-dir-vertical :down) (setq grow-dir-horizontal :right)) :title-alignment :right) (ur-corner :title "────┐" :value-type :boolean :toggle-type :grouped-toggle :indicator-type :none :title-alignment :left) (ll-corner :title "└────" :value-type :boolean :toggle-type :grouped-toggle :indicator-type :none :initial-value t :title-alignment :right) (lr-corner :title "────┘" :toggle-type :grouped-toggle :value-type :boolean :indicator-type :none :title-alignment :left) ("-") (remove-table :title "Remove all tables" :toggle-type :wide-toggle :next-variable 'start-pnt :push-action (remove-table-from-sheet))) :mutual-exclusion '((ll-corner lr-corner ul-corner ur-corner) (grow-dir-data-ascending grow-dir-data-descending) (header-on-top header-on-bottom)) :ok-action '() :help-action '()) (defun create-inspection-dim-table-on-sheet (&key start-pnt sketch-name row-heights text-style grow-dir-vertical grow-dir-horizontal header-position sort) (let* ( (data (list)) (data-t (list)) (all-inspection-dimensions (get-all-inspection-dimensions-by-dwg)) (data-raw (create-inspection-dimension-table-data all-inspection-dimensions)) (text-style-factor (cond ((eql text-style :large) (/ 5 3.5)) ((eql text-style :smal) (/ 2.5 3.5)) (t 1))) (columns (reverse (list (list :title "Inspection dimension" :width (* 55 text-style-factor)) (list :title "Nominal dimension" :width (* 47 text-style-factor)) (list :title "Dimension type" :width (* 42 text-style-factor)) (list :title "Tolerance type" :width (* 42 text-style-factor)) (list :title "Tolerance value" :width (* 65 text-style-factor)) (list :title "Sheet" :width (* 16 text-style-factor)) (list :title "View" :width (* 35 text-style-factor)))))) (dolist (dim-item data-raw) (push (convert-plist-to-string-list dim-item) data-t)) (dolist (dim-item data-t) (setf (car dim-item) (format nil "~2,'0d" (read-from-string (first dim-item)))) (push dim-item data)) (sd-am-create-table :start-pnt start-pnt :sketch-name sketch-name :row-heights row-heights :text-style text-style :grow-dir-vertical grow-dir-vertical :grow-dir-horizontal grow-dir-horizontal :header-position header-position :sort sort :columns columns :data (reverse data)))) (defun remove-table-from-sheet () (let ( (all-sketches-in-sheet (sd-am-inq-all-sketches (sd-am-inq-curr-sheet)))) (dolist (sketch all-sketches-in-sheet) (let ( (sketch-name (sd-am-inq-name sketch)) (match-pattern (format nil "*~a*" *inspection-dimension-table-sketch-name*))) (when (sd-string-match-pattern-p match-pattern sketch-name) (am_sketch_delete :sketch sketch)))))) (defun create-inspection-dimension-flag (dimension index) (let* ( new-postfix (dim-fixes (sd-am-inq-dim-fix-texts dimension)) (postfix (sd-am-dim-fix-texts-struct-postfix dim-fixes)) (overwrite :yes)) (when (get-inspection-dimension-no dimension) (setq postfix (sd-am-dim-fix-texts-struct-postfix-custom dim-fixes)) (setq overwrite (sd-display-question "Overwrite existing value?" :title "Overwrite"))) (when (eql overwrite :yes) (setq new-postfix (format nil "~a~a~a" postfix *inspection-dimension-delimiter* index)) (sd-call-cmds (am_dim_props :dim_list dimension :text_frame :ballooned :dim_postfix new-postfix))))) (defun get-next-inspection-dimension-index () (let* ( (indexer 1) (all-inspection-dimensions (get-all-inspection-dimensions-by-dwg)) (inspection-dim-data (create-inspection-dimension-table-data all-inspection-dimensions))) (dolist (inspection-dim inspection-dim-data) (unless (= (read-from-string (getf inspection-dim :number)) indexer) (return-from get-next-inspection-dimension-index (format nil "~a" indexer))) (incf indexer)) (format nil "~a" indexer))) (defun remove-inspection-dimension-flag (dimensions) (dolist (dimension dimensions) (when (get-inspection-dimension-no dimension) (let* ( (dim-fixes (sd-am-inq-dim-fix-texts dimension)) (dim-postfix (sd-am-dim-fix-texts-struct-postfix-custom dim-fixes))) (sd-call-cmds (am_dim_props :dim_list dimensions :text_frame :default :dim_postfix dim-postfix)))))) (defun show-inspection-dimension-table () (let* ( (inspection-dim-data-for-table (list)) (all-inspection-dimensions (get-all-inspection-dimensions-by-dwg)) (inspection-dim-data (create-inspection-dimension-table-data all-inspection-dimensions))) (dolist (item inspection-dim-data) (push (convert-plist-to-string-list item) inspection-dim-data-for-table)) (create-inspection-dimension-table inspection-dim-data-for-table))) (defun create-inspection-dimension-table (inspection-dim-data) (sd-create-logical-table "inspection-dimension-logical-table" :columns '(:first :second :third :fifth :sixth :seventh :eigths) :columnNames '("Inspection dimension" "Nominal dimension" "Dimension type" "Tolerance type" "Tolerance value" "Sheet" "View") :keyColumns '(:first) :secured nil :types '(:string :string :untyped :string :string :string :string) :units '(nil nil nil nil nil nil nil ) :contents inspection-dim-data) (sd-create-display-table "inspection-dimension-display-table" :logicalTable "inspection-dimension-logical-table" :tableTitle "Inspection dimensions" :columns '(:first :second :third :fifth :sixth :seventh :eigths) :formatFunctions '(format-index-for-display-table) :columnSortUI t :applyColumns '(:first) :applyAction nil :bottomLine nil :selectionMode :single-row) (sd-set-display-table-colors "inspection-dimension-display-table" :columnSeparators t :columnSeparatorColor t :rowColors t :rowColor2 "#00FFFF") (sd-show-display-table "inspection-dimension-display-table" :position '(nil :mouse_relative 10 10))) (defun create-inspection-dimension-table-data (inspection-dimension-list) (let ( (table-data-rows (list))) (dolist (inspection-dimension-view inspection-dimension-list) (let* ( (view (sd-am-inq-view (getf inspection-dimension-view :view))) (view-name (sd-am-view-struct-name view)) (sheet-name (sd-am-sheet-struct-name (sd-am-inq-sheet (sd-am-view-struct-sheet view))))) (dolist (dimension (getf inspection-dimension-view :inspection-dimension-list)) (let* ( dim-tol-type dim-tol-text (dim-no (get-inspection-dimension-no dimension)) (dim-fixes (sd-am-inq-dim-fix-texts dimension)) (dim-prefix (sd-am-dim-fix-texts-struct-prefix dim-fixes)) (dim-postfix (sd-am-dim-fix-texts-struct-postfix-custom dim-fixes)) (dim-main-value (sd-am-inq-dim-main-value-text dimension)) (dim-tol-values (sd-am-inq-dim-tol-values dimension)) (dim-tol-upper-lower-p (sd-am-dim-upper-lower-tol-struct-p dim-tol-values)) (dim-tol-limit-p (sd-am-dim-limit-tol-struct-p dim-tol-values)) (dim-tol-plus-minus-p (sd-am-dim-plus-minus-tol-struct-p dim-tol-values)) (dim-type (sd-am-inq-dim-type dimension)) (dim-text (format nil "~a~a~a" dim-prefix dim-main-value dim-postfix))) (cond (dim-tol-upper-lower-p (let* ( (upper (sd-am-inq-dim-main-upper-tol-text dimension)) (lower (sd-am-inq-dim-main-lower-tol-text dimension)) (delimiter (if (and (> (length upper) 0) (> (length lower) 0)) "/" ""))) (setq dim-tol-type "Upper/Lower") (setq dim-tol-text (format nil "~a~a~a" upper delimiter lower)))) (dim-tol-limit-p (let* ( (limit1-value (sd-am-dim-limit-tol-struct-limit1 dim-tol-values)) (limit1-negativ-number (minusp limit1-value)) (limit2-value (sd-am-dim-limit-tol-struct-limit2 dim-tol-values)) (limit2-negativ-number (minusp limit2-value))) (setq dim-tol-type "Limit") (setq dim-tol-text (format nil "~a (~:[+~;~]~a)/~a (~:[+~;~]~a)" (sd-am-inq-dim-main-upper-tol-text dimension) limit1-negativ-number (sd-num-to-string limit1-value) (sd-am-inq-dim-main-lower-tol-text dimension) limit2-negativ-number (sd-num-to-string limit2-value))))) (dim-tol-plus-minus-p (progn (setq dim-tol-type "Plus-Minus") (setq dim-tol-text (format nil "±~a" (sd-num-to-string (sd-am-dim-plus-minus-tol-struct-plus-minus dim-tol-values))))))) (push (list :number dim-no :dimension-value dim-text :dimension-type dim-type :dimension-tolerance-type dim-tol-type :dimension-tolerance-value dim-tol-text :sheet sheet-name :view view-name) table-data-rows))))) (sort table-data-rows #'string< :key #'second))) (defun get-all-inspection-dimensions-by-dwg () (let ( (inspection-dimension-list (list)) (all-views-by-dwg (sd-call-cmds (get_selection :focus_type *sd-anno-view-seltype* :select :docu_view :by_drawing_docu_rest)))) (dolist (view all-views-by-dwg) (push (list :view view :inspection-dimension-list (get-all-inspection-dimensions-by-view view)) inspection-dimension-list)) inspection-dimension-list)) (defun get-all-inspection-dimensions-by-view (view) (let* ( (all-inspection-dimensions (list)) (all-dimensions-in-dwg (sd-call-cmds (get_selection :focus_type *sd-anno-dimension-seltype* :select :docu_dimension :by_view_docu_rest view)))) (dolist (dimension all-dimensions-in-dwg) (when (get-inspection-dimension-no dimension) (push dimension all-inspection-dimensions))) all-inspection-dimensions)) (defun get-inspection-dimension-no (dimension) (let ( (dim-postfix (sd-am-dim-fix-texts-struct-postfix (sd-am-inq-dim-fix-texts dimension)))) (when (string/= dim-postfix "") (let ( (invalid-format-msg (format nil "[WARNING] Inspection dimension skipped '~a' is an invalid format." dim-postfix)) (splitted-postfix (sd-string-split dim-postfix *inspection-dimension-delimiter*))) (cond ((= (length splitted-postfix) 1) nil) ((= (length splitted-postfix) 2) (if (and (numberp (read-from-string (second splitted-postfix))) (plusp (read-from-string (second splitted-postfix)))) (second splitted-postfix) (display invalid-format-msg))) ((= (length splitted-postfix) 3) (display invalid-format-msg)) (t nil)))))) (defun sd-am-dim-fix-texts-struct-postfix-custom (dim-fixes) ;; TODO: Just a quick and dirty implementation of inspection dimension postfix inquire. ;; Make code more robust and take the default or no postfix into consideration. (let ( (dim-curr-postfix (sd-am-dim-fix-texts-struct-postfix dim-fixes))) (first (sd-string-split dim-curr-postfix *inspection-dimension-delimiter*)))) (defun convert-plist-to-string-list (plist) (let ( (new-list (list)) (index 0)) (dolist (item plist) (incf index) (when (evenp index) (if item (push (convert-special-character-to-string (format nil "~a" item)) new-list) (push "" new-list)))) (reverse new-list))) (defun convert-special-character-to-string (string-to-convert) (let ( (special-character-list (list (list "" "°") (list "" "Ø") (list "" "±") (list "" "'") (list "" "''") (list "" "□")))) (dolist (special-char-string special-character-list) (setq string-to-convert (sd-string-replace string-to-convert (first special-char-string) (second special-char-string)))) string-to-convert)) (defun format-index-for-display-table (ltab-name value row column) (declare (ignore ltab-name row column)) (format nil "~2,'0d" (read-from-string value))) (defun resort-inspection-dimension-flags () (let ( (index 1) (all-inspection-dimensions (get-all-inspection-dimensions-by-dwg))) (dolist (inspection-dimension-in-view all-inspection-dimensions) (dolist (inspection-dimension (getf inspection-dimension-in-view :inspection-dimension-list)) (remove-inspection-dimension-flag (list inspection-dimension)) (create-inspection-dimension-flag inspection-dimension index) (incf index))))) (defun sd-am-create-table (&key start-pnt ; { Docupoint } sketch-name ; { String } row-heights ; { Number } text-style ; { KEYWORD all valid text styles e.g. :standard } grow-dir-vertical ; { KEYWORD :up, :down } grow-dir-horizontal ; { KEYWORD :right, :left } header-position ; { KEYWORD :top, :bottom } sort ; { KEYWORD :ascending, :descending } columns ; { List of Lists } data) ; { List of Lists } "sd-am-create-table Create a table/spreadsheet on the current drawing sheet. Key parameters: start-pnt { Docupoint } sketch-name { String } row-heights { Number } text-style { KEYWORD all valid text styles e.g. :standard, :large, :medium, ... } grow-dir-vertical { KEYWORD :up, :down } grow-dir-horizontal { KEYWORD :right, :left } header-position { KEYWORD :top, :bottom } sort { KEYWORD :ascending, :descending } columns { List of Lists } data { List of Lists } Example: (sd-am-create-table :start-pnt start-pnt :sketch-name 'my-anno-table' :row-heights 5.5 :text-style :standard :grow-dir-vertical :down :grow-dir-horizontal :right :header-position :top :sort :ascending :descending :columns (list (list :title 'Title-Column-1' :width 50) (list :title 'Title-Column-2' :width 80) (list :title 'Title-Column-3' :width 75)) :data (list (list 'Value Column-1 Row 1' 'Value Column-2 Row 1' 'Value Column-3 Row 1') (list 'Value Column-1 Row 2' 'Value Column-2 Row 2' 'Value Column-3 Row 2'))) Remarks: Number of columns and data content MUST fit. Fill up data content with empty strings if needed. " (let* ( data-and-header sketches-after sketches-current (sketches-before (sd-am-inq-all-sketches (sd-am-inq-curr-sheet))) (x-coord-row-start (oli::gpntdocu_x start-pnt)) (x-coord (oli::gpntdocu_x start-pnt)) (y-coord (oli::gpntdocu_y start-pnt)) (column-title-list (list)) (grow-dir-up (eql grow-dir-vertical :up)) (grow-dir-right (eql grow-dir-horizontal :right))) (sd-am-create-sketch :name sketch-name :position start-pnt :owner_type :current-sheet) (setq sketches-after (sd-am-inq-all-sketches (sd-am-inq-curr-sheet))) (setq sketch-current (first (set-difference sketches-before sketches-after))) (dolist (column-header columns) (push (getf column-header :title) column-title-list)) (cond ((and (eql header-position :top) (eql grow-dir-vertical :down) (eql sort :descending)) (push column-title-list data)) ((and (eql header-position :top) (eql grow-dir-vertical :down) (eql sort :ascending)) (nconc data (list column-title-list))) ((and (eql header-position :top) (eql grow-dir-vertical :up) (eql sort :descending)) (nconc data (list column-title-list))) ((and (eql header-position :top) (eql grow-dir-vertical :up) (eql sort :ascending)) (push column-title-list data)) ((and (eql header-position :bottom) (eql grow-dir-vertical :down) (eql sort :descending)) (nconc data (list column-title-list))) ((and (eql header-position :bottom) (eql grow-dir-vertical :down) (eql sort :ascending)) (push column-title-list data)) ((and (eql header-position :bottom) (eql grow-dir-vertical :up) (eql sort :descending)) (push column-title-list data)) ((and (eql header-position :bottom) (eql grow-dir-vertical :up) (eql sort :ascending)) (nconc data (list column-title-list)))) (dolist (row (if (eql sort :descending) data (reverse data))) (let* ((cell-cnt 0)) (setq x-coord x-coord-row-start) (dolist (cell (if grow-dir-right row (reverse row))) (let* ( (cell-text (if (= (length cell) 0) " " cell)) (cell-width (getf (nth cell-cnt (if grow-dir-right (reverse columns) columns)) :width)) (grow-dir-up-result (if grow-dir-up (+ y-coord row-heights) (- y-coord row-heights))) (grow-dir-up-result-1 (if grow-dir-up (1+ y-coord) (1+ (- y-coord row-heights)))) (grow-dir-right-result (if grow-dir-right (+ x-coord cell-width) (- x-coord cell-width))) (grow-dir-right-result-1 (if grow-dir-right (1+ x-coord) (1+ (- x-coord cell-width)))) (start-pnt (make-gpnt2d :x x-coord :y y-coord)) (end-pnt (make-gpnt2d :x grow-dir-right-result :y grow-dir-up-result))) (sd-am-create-geo-straight :rectangle (list start-pnt end-pnt) :owner_type :sketch :owner sketch-current) (sd-call-cmds (am_create_text :owner sketch-current :docu-text cell-text :style text-style (make-gpnt2d :x grow-dir-right-result-1 :y grow-dir-up-result-1))) ;; (sd-am-create-text ;; :text cell-text ;; :position (make-gpnt2d :x grow-dir-right-result-1 :y grow-dir-up-result-1) ;; :owner_type :sketch ;; :owner sketch-current) (setq x-coord grow-dir-right-result) (incf cell-cnt))) (setq y-coord (if grow-dir-up (+ y-coord row-heights) (- y-coord row-heights)))))))