qevghdfcu 发表于 2024-4-18 09:25:19

找大神编个一键分别计算道路断面面种的插件

找大神编个一键分别计算道路断面面种的插件

Atsai 发表于 2024-4-23 22:17:32

https://www.theswamp.org/index.php?topic=45305.15
原帖第29楼,有ymg大神贴的源码可下载。
下面为转贴的源码,楼主可以依需求修改。

;;; Cut & Fill      by ymg                                                    ;
;;;                                                                           ;



(defun c:cf (/ ** *acdoc* a are b bnd c cutcol d dir dl1 dl2 e fillcol hcol
               intl len1 len2 p p0 p1 p2 pm pol1 pol2 sp1 sp2 spe ss1
               ss2 totcut totfill txt txtlayer varl)
               
   (vl-load-com)

   (defun *error* (msg)
      (mapcar 'eval varl)
      (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")))
         (princ (strcat "\nError: " msg))
      )
      (and *acdoc* (vla-endundomark *acdoc*))
      (princ)
   )

   (setq varl '("OSMODE" "CMDECHO" "DIMZIN" "PEDITACCEPT")
         varl (mapcar (function (lambda (a) (list 'setvar a (getvar a)))) varl)
   )

   (or *acdoc* (setq *acdoc* (vla-get-activedocument (vlax-get-acad-object))))

   (vla-startundomark *acdoc*)

   (setvar 'CMDECHO 0)
   (setvar 'DIMZIN0)
   (setvar 'OSMODE0)


   (setq cutcol 1fillcol 3; Cut is Red, Fill is Green                     ;
         totcut 0totfill 0; Total Cut and Total Fill                      ;
         txtlayer "Text"    ; Name of Layer for Cut and Fill Values         ;

   )
   (while (not (setq **(princ "\nSelect Reference Polyline:")
                     ss1 (ssget "_+.:L:S" '((0 . "LWPOLYLINE")))
               )
          )
      (princ "\nYou Must Select a Polyline:")
   )                  
   (while (not (setq **(princ "\nSelect Proposed Polyline:")
                     ss2 (ssget "_+.:L:S" '((0 . "LWPOLYLINE")))
               )
          )
      (princ "\nYou Must Select a Polyline:")
   )

   
   (setq pol1 (ssname ss1 0)
         len1 (vlax-curve-getDistAtParam pol1 (vlax-curve-getEndParam pol1))
         pol2 (ssname ss2 0)
         len2 (vlax-curve-getDistAtParam pol2 (vlax-curve-getEndParam pol2))
         sp1(vlax-curve-getstartpoint pol1)
         spe(vlax-curve-getendpoint pol1)
         sp2(if (vlax-curve-isClosed pol2)
               (setq lst2 (listpol pol2)
                     disl (mapcar '(lambda (a) (distance sp1 a)) lst2)
                     **   (plineorg pol2 (nth (vl-position (apply 'min disl) disl) lst2))
               )
               (vlax-curve-getstartpoint pol2)
               )
         dir(if (< (/ pi 2) (angle sp1 spe) (/ (* 3 pi) 2)) -1 1)
   )      
   

   ; Getting all the intersections between poly.                              ;

   (setq intl (intersections pol1 pol2))

   (if (> (length intl) 1)
      (progn
   
   ; Computing distance of intersections on each polyline                     ;
   
         (setq dl1(mapcar '(lambda (a) (getdistoncurve pol1 a)) intl)
               dl2(mapcar '(lambda (a) (getdistoncurve pol2 a)) intl)
         )
   
   ; If both polyline are closed add first Intersection to end of list      ;
   ; We also add a distance to each distances list                            ;

         (if (and (vlax-curve-isClosed pol1) (vlax-curve-isClosed pol2))
            (setq dl1(append dl1 (list (+ (car dl1) len1)))
                  dl2(append dl2 (list (+ (car dl2) len2)))
                  intl (append intl (list (car intl)))
                  dir(if (iscw_p (listpol pol1)) -1 1)   
            )      
         )
   

   ; Finding points at mid-distance between intersections on each polyline    ;
   ; Calculating midpoint between mid-distance points to get an internal point;
   ; Creating a list of all these points plus the intersection points         ;
   
         (setq pm
            (mapcar
                '(lambda (a b c d e)
                  (list (midpoint
                              (setq p1 (getptoncurve pol1 (rem (* (+ a b) 0.5) len1)))
                              (setq p2 (getptoncurve pol2 (rem (* (+ c d) 0.5) len2)))
                           )
                           p1 p2 e            
                     )
                  )
                  dl1 (cdr dl1) dl2 (cdr dl2) intl
             )
         )      

   
   
         (foreach i pm
            (setqp (car    i); Midpoint between p1 p2                           ;
                  p0 (cadddr i); Intersection Point                               ;
                  p1 (cadr   i); Midpoint of Intersections on Reference Polyline;
                  p2 (caddri); Midpoint of Intersections on Proposed Polyline   ;
            )
            (if (> (abs (onside p2 p0 p1)) 1e-3) ; Not Colinear                     ;
               (progn
                  (vl-cmdf "._-BOUNDARY" p "")
                  (setq are (vla-get-area (vlax-ename->vla-object (entlast)))
                        bnd (entlast)
                  )
            
                  (if (minusp (* (onside p2 p0 p1) dir))               
                     (setq totfill (+ totfill are) hcol fillcol)
                     (setq totcut(+ totcutare) hcolcutcol)
                  )
               
                  (vl-cmdf "._-HATCH" "_CO" hcol "." "_P" "SOLID" "_S" bnd "" "")
                  (entdel bnd)
               )
            )
         )
         (setq   p (cadr (grread nil 13 0))
               txt (strcat "{\\C3;Fill: " (rtos totfill 2 2) " m2\\P\\C1;Cut: " (rtos totcut2 2) " m2}")
         )      
         (entmakex (list
                      (cons 0 "MTEXT")
                      (cons 100 "AcDbEntity")
                      (cons 8 txtlayer)
                      (cons 100 "AcDbMText")
                      (cons 10 p)               
                      (cons 40 3.0)
                      (cons 1 txt)
                  )
         )         

         (command "_MOVE" (entlast) "" p pause)
      )
      (Alert "Not Enough Intersections To Process !")
)

(*error* nil)

)

(princ "\nCalculates Cut & Fill Between Two Intersecting Polylines")
(princ "\nCF to start...")



(defun midpoint (p1 p2)
   (mapcar '(lambda (a b) (* (+ a b) 0.5)) p1 p2)
)

; onside      by ymg                                                      ;
; Negative return, point is on left of v1->v2                                 ;
; Positive return, point is on right of v1->v2                              ;
;      0 return, point is smack on the vector.                              ;
;                                                                           ;

(defun onside (p v1 v2 / x y)
    (setq x (car p) y (cadr p))
    (- (* (- (cadr v1) y) (-(car v2) x)) (* (- (carv1) x) (- (cadr v2) y)))
)

;                                                                           ;
; Is Polyline Clockwise                      by LeeMac                        ;
;                                                                           ;
; Argument:   l,Point List                                                ;
; Returns:    t, Polyline is ClockWise                                        ;
;         nil, Polyline is CounterClockWise                                 ;
;                                                                           ;

(defun iscw_p (l)
    (if (equal (car l) (last l) 1e-8) (setq l (cdr l)))
    (minusp
      (apply '+
            (mapcar
                (function
                  (lambda (a b) (- (* (car b) (cadr a)) (* (car a) (cadr b))))
                )
                l (cons (last l) l)
            )
      )
    )
)

;;                                                                            ;
;; Return list of intersection(s) between two VLA-Object or two ENAME         ;
;; obj1 - first VLA-Object                                                    ;
;; obj2 - second VLA-Object                                                   ;
;; mode - intersection mode (acExtendNone acExtendThisEntity                  ;
;;                              acExtendOtherEntity acExtendBoth)         ;
;; Requires triplet                                                         ;
;;                                                                            ;

(defun Intersections (obj1 obj2)
   (or (= (type obj1) 'VLA-OBJECT) (setq obj1 (vlax-ename->vla-object obj1)))
   (or (= (type obj2) 'VLA-OBJECT) (setq obj2 (vlax-ename->vla-object obj2)))
         
   (triplet (vlax-invoke obj1 'intersectwith obj2 acExtendNone))
)

;;                                                                            ;
;; triplet, Separates a list into triplets of items.                        ;
;;                                                                            ;

(defun triplet (l)
   (if l (cons (list (car l) (cadr l) (caddr l))(triplet (cdddr l))))
)


(defun getdistoncurve (e p)
   (vlax-curve-getDistatParam e
      (vlax-curve-getparamatpoint e
             (vlax-curve-getclosestpointto e p)
      )   
   )         
)

(defun getptoncurve (e d)
   (vlax-curve-getpointatparam e (vlax-curve-getparamatdist e d))
)

;;                                                                            ;
;; listpol   by ymg    (Simplified a Routine by Gile Chanteau               ;
;;                                                                            ;
;; Parameter:en,Entity Name or Object Name of Any Type of Polyline      ;
;;                                                                            ;
;; Returns:    List of Points in Current UCS                                  ;
;;                                                                            ;
;; Notes:      On Closed Polyline the Last Vertex is Same as First)         ;
;;                                                                            ;

(defun listpol (en / i l)
   (repeat (setq i (fix (1+ (vlax-curve-getEndParam en))))
      (setq l (cons (trans (vlax-curve-getPointAtParam en (setq i (1- i))) 0 1) l))
   )
)


;; plineorg   by (gile) (Modified into a function by ymg)                     ;
;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/          ;
;;            change-polyline-start-point/td-p/2154331                        ;
;;                                                                            ;
;; Function to modify origin of a closed polyline                           ;
;;                                                                            ;
;; Arguments:                                                               ;
;;   en : Ename or VLA-Object of a Closed Polyline.                           ;
;;   pt : Point                                                               ;
;;                                                                            ;
;; Returns: Point of Origin if successful, else nil.                        ;
;;                                                                            ;

(defun plineorg (en pt / blst d1 d2 d3 n norm obj pa plst)
   (if (= (type en) 'ENAME)
      (setq obj (vlax-ename->vla-objecten))
      (setq obj en   en (vlax-vla-object->ename obj))
   )
   
    ;; bulgratio   by (gile)                                 ;
    ;; Returns a bulge which is proportional to a reference;
    ;; Arguments :                                           ;
    ;; b : the reference bulge                               ;
    ;; k : the ratio (between angles or arcs length)         ;

   (defun bulgratio (b k / a)
      (setq a (atan b))
      (/ (sin (* k a)) (cos (* k a)))
   )

    ;; Sublistby (gile)                                    ;
    ;; Returns a sublist similar to substr function.         ;
    ;; lst : List from which sublist is to be extracted      ;
    ;; idx : Index of Item at Start of sublist               ;
    ;; len : Length of sublist or nil to return all items.   ;

   (defun sublist (lst n len / rtn)
      (if (or (not len) (< (- (length lst) n) len))
         (setq len (- (length lst) n))
      )
      (setq n (+ n len))
      (repeat len
         (setq rtn (cons (nth (setq n (1- n)) lst) rtn))
      )
   )

   (if (and (= (vla-get-closed obj) :vlax-true)
            (= (vla-get-objectname obj) "AcDbPolyline")
       )   
      (progn
         (setq plst (vlax-get obj 'coordinates)
               norm (vlax-get obj 'normal)
               pt   (vlax-curve-getClosestPointTo en (trans pt 1 0))
               pa   (vlax-curve-getparamatpoint obj pt)
               n    (/ (length plst) 2)         
         )
         (repeat n
            (setq blst (cons (vla-getbulge obj (setq n (1- n))) blst))
         )
         (if (= pa (fix pa))
            (setq n    (fix pa)
                  plst (append (sublist plst (* 2 n) nil)
                               (sublist plst 0 (* 2 n))
                     )
                  blst (append (sublist blst n nil) (sublist blst 0 n))
            )
            (setq n    (1+ (fix pa))
                  d3   (vlax-curve-getdistatparam en n)
                  d2   (- d3 (vlax-curve-getdistatpoint en pt))
                  d3   (- d3 (vlax-curve-getdistatparam en (1- n)))
                  d1   (- d3 d2)
                  pt   (trans pt 0 (vlax-get obj 'normal))
                  plst (append (list (car pt) (cadr pt))
                               (sublist plst (* 2 n) nil)
                               (sublist plst 0 (* 2 n))
                     )
                  blst (append (list (bulgratio (nth (1- n) blst) (/ d2 d3)))
                               (sublist blst n nil)
                               (sublist blst 0 (1- n))
                               (list (bulgratio (nth (1- n) blst) (/ d1 d3)))
                     )
            )
         )
         (vlax-put obj 'coordinates plst)
         (repeat (setq n (length blst))
            (vla-setbulge obj (setq n (1- n)) (nth n blst))
         )
         (trans pt 0 1)
      )
      nil
   )
)

479274135 发表于 2024-4-18 17:23:37

橡皮 发表于 2024-4-18 15:55
你把大概需求写一下最好配个示意图,然后大伙看看有没有能解决的.

对对应该详细说明意图,要不谁也不知道你要做什么

橡皮 发表于 2024-4-22 16:05:35

qevghdfcu 发表于 2024-4-22 09:11
对,主要就是清表,挖方,填方

解决了吗,没有的话我看看可以不

liuhe 发表于 2024-4-18 09:46:24

可以找我
试试啊

qevghdfcu 发表于 2024-4-18 09:58:45

liuhe 发表于 2024-4-18 09:46
可以找我
试试啊

加你微信了

liuhe 发表于 2024-4-18 15:18:37

我解决不了,需要大佬继续解决

橡皮 发表于 2024-4-18 15:55:29

你把大概需求写一下最好配个示意图,然后大伙看看有没有能解决的.

spp_wall 发表于 2024-4-18 16:14:49

什么是道路断面面种?

hao3ren 发表于 2024-4-18 18:52:52

断面面积吧?清废、挖方、填方?

qevghdfcu 发表于 2024-4-22 09:11:06

hao3ren 发表于 2024-4-18 18:52
断面面积吧?清废、挖方、填方?

对,主要就是清表,挖方,填方
页: [1] 2
查看完整版本: 找大神编个一键分别计算道路断面面种的插件