; PXYCSV.lsp
; Export polyline vertex coordinates to a CSV file.
; Output coordinate system: WCS
; CSV format without header:
; 123.456000,789.012000

(vl-load-com)

(defun PXY:_NumberToString (value precision)
  ;; جلوگیری از تداخل ممیز اعشاری با جداکننده CSV
  (vl-string-translate "," "." (rtos value 2 precision))
)

(defun PXY:_GetLWPolylineVertices (entity / data elevation item points)
  (setq data      (entget entity)
        elevation (cond ((cdr (assoc 38 data))) (0.0))
        points    nil)

  (foreach item data
    (if (= (car item) 10)
      (setq points
        (cons
          ;; تبدیل مختصات OCS پلی‌لاین به WCS
          (trans
            (list (cadr item) (caddr item) elevation)
            entity
            0)
          points))))

  (reverse points)
)

(defun PXY:_Get2DPolylineVertices (entity / data flags nextEntity vertexData point points)
  (setq data   (entget entity)
        flags  (cdr (assoc 70 data))
        points nil)

  ;; Mesh و Polyface در این دستور پشتیبانی نمی‌شوند
  (if (or (/= 0 (logand flags 16))
          (/= 0 (logand flags 64)))
    nil
    (progn
      (setq nextEntity (entnext entity))

      (while nextEntity
        (setq vertexData (entget nextEntity))

        (cond
          ((= (cdr (assoc 0 vertexData)) "SEQEND")
           (setq nextEntity nil))

          ((= (cdr (assoc 0 vertexData)) "VERTEX")
           (setq point (cdr (assoc 10 vertexData)))

           ;; برای 3D Polyline مختصات از قبل WCS است
           (if (= 0 (logand flags 8))
             (setq point (trans point entity 0)))

           (setq points (cons point points))
           (setq nextEntity (entnext nextEntity)))

          (T
           (setq nextEntity (entnext nextEntity)))
        )
      )

      (reverse points)
    )
  )
)

(defun c:PXYCSV (/ selection entity entityType vertices filePath fileHandle point precision)
  (setq precision 6)

  (prompt "\nSelect a polygon/polyline to export vertex coordinates.")

  (if (setq selection (entsel "\nSelect polyline: "))
    (progn
      (setq entity     (car selection)
            entityType (cdr (assoc 0 (entget entity))))

      (cond
        ((= entityType "LWPOLYLINE")
         (setq vertices (PXY:_GetLWPolylineVertices entity)))

        ((= entityType "POLYLINE")
         (setq vertices (PXY:_Get2DPolylineVertices entity)))

        (T
         (prompt "\nSelected object is not a supported polyline.")
         (setq vertices nil))
      )

      (if vertices
        (progn
          (setq filePath
            (getfiled
              "Save polygon coordinates as CSV"
              (strcat (getvar "DWGPREFIX") "polygon_vertices.csv")
              "csv"
              1))

          (if filePath
            (progn
              (setq fileHandle (open filePath "w"))

              (if fileHandle
                (progn
                  (foreach point vertices
                    (write-line
                      (strcat
                        (PXY:_NumberToString (car point) precision)
                        ","
                        (PXY:_NumberToString (cadr point) precision))
                      fileHandle))

                  (close fileHandle)

                  (prompt
                    (strcat
                      "\n"
                      (itoa (length vertices))
                      " vertices exported to: "
                      filePath))
                )
                (prompt "\nCould not create the output file.")
              )
            )
            (prompt "\nExport canceled.")
          )
        )
        (prompt "\nNo valid vertices were found.")
      )
    )
    (prompt "\nNothing selected.")
  )

  (princ)
)

(princ "\nPXYCSV loaded. Type PXYCSV to export polyline vertices.")
(princ)
