Author Topic: ---={ Challenge }=--- Selective offset of polygonal pline edges  (Read 2192 times)

0 Members and 1 Guest are viewing this topic.

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Hi all,

I think this is challenge issue, as I think it's pretty hard solvable, and I don't have much experience to play with this, but it would be very useful feature if accomplished... For a start let it be not dynamic, but just like standard offset, you specify distance and side for offset and it'll do just some edges, but be aware that chained edges should be trimmed/extended adequate like it's doing built-in offset command... Maybe I overlooked something, but I don't need pure lisping, I want to say that every method is allowed - using other known and unknown commands, functions etc... If it's not a problem, it's allowed to be used OFFSET built-in command to accomplish similar result, just rename main function name to something like "selectiveoffset" or something... This task should be applicable only for polygonal open/closed pline edges (LWPOLYLINE)... Selected edges should be highlighted or made visible by picking using BLIPMODE = 1, or any other method you think of for creating adequate selection and previewing that selection of edges...

So lets see if it's doable,
I wish you good luck, and happy coding,
Regards, M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2139
  • class keyThumper<T>:ILazy<T>
Re: ---={ Challenge }=--- Selective offset of polygonal pline edges
« Reply #1 on: August 21, 2017, 06:32:40 AM »

If I remember correctly, Gilles has published a routine to do this about 10 years ago.

It Offset and Copied segments of a polyline.

I'd suggest that you won't get much better than that if you can  find it.


added

Try this:
https://www.theswamp.org/index.php?topic=21933.msg266096#msg266096

I'm not sure if it is the latest build.

Regards,
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ---={ Challenge }=--- Selective offset of polygonal pline edges
« Reply #2 on: August 21, 2017, 06:54:42 AM »

If I remember correctly, Gilles has published a routine to do this about 10 years ago.

It Offset and Copied segments of a polyline.

I'd suggest that you won't get much better than that if you can  find it.


added

Try this:
https://www.theswamp.org/index.php?topic=21933.msg266096#msg266096

I'm not sure if it is the latest build.

Regards,

Oh, right, I had that one in my library... It seems that it has grown just enough for me to forget what I have in it... Thanks kdub, somehow now when I look at it I very much agree that I don't think I could find much better than that...

Thanks, Gilles...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ---={ Challenge }=--- Selective offset of polygonal pline edges
« Reply #3 on: August 21, 2017, 07:26:37 AM »
I've just analyzed Gilles's code, and I figured out that we should need something more... For instance, when segments are offset, we need to find a way if it's possible to connect those segments (Gilles's resulting plines) with segments that haven't been offset and make final offset with exactly the same number of segment edges like original pline...

I hope you understand new requirements...
M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ---={ Challenge }=--- Selective offset of polygonal pline edges
« Reply #4 on: August 21, 2017, 10:08:36 AM »
Here is my attempt, basically the same as Gilles's code, but just a little larger... And it may return Invalid command sent as input error, but it does what I meant to do...

Code - Auto/Visual Lisp: [Select]
  1. ;; OFSEGS -Gilles Chanteau- 2008/03/26
  2. ;; Offsets the selected segments of lwpolyline
  3. ;; Joined segments are offseted in a single lwpolyline
  4. ;; Keeps arcs and widthes
  5. ;; Works whatever the current UCS and the pline OCS and elevation
  6.  
  7. ;; Modified by M.R. -Marko Ribar, d.i.a.- 2017/08/21
  8. ;; Changed name of command function to "segsoffset"
  9. ;; If possible joines offset segments with unoffset segments
  10. ;; forming new pline with exactly the same number of segments like original pline
  11.  
  12. (defun c:segsoffset ( / *acdoc* ofdist ent pline normal elevat params points side closest par bulge p1 p2 arc_data k paramsall paramsr el ell ss pea li1 li2 )
  13.  
  14.  
  15.   (initget 6 "Through")
  16.   (if (setq ofdist
  17.              (getdist (strcat "\nSpecify offset distance or [Through] <"
  18.                               (if (< (getvar "OFFSETDIST") 0)
  19.                                 "Through"
  20.                                 (rtos (getvar "OFFSETDIST"))
  21.                               )
  22.                               "> : "
  23.                       )
  24.              )
  25.       )
  26.     (if (= ofdist "Through")
  27.       (setvar "OFFSETDIST" -1)
  28.       (setvar "OFFSETDIST" ofdist)
  29.     )
  30.     (setq ofdist (getvar "OFFSETDIST"))
  31.   )
  32.   (if (and (setq ent (entsel "\nSelect a segment to offset : "))
  33.            (setq pline (vlax-ename->vla-object (car ent)))
  34.            (= (vla-get-ObjectName pline) "AcDbPolyline")
  35.            (setq normal (vlax-get pline 'Normal))
  36.            (setq elevat (vla-get-Elevation pline))
  37.       )
  38.     (progn
  39.       (setq k -1)
  40.       (repeat (fix (vlax-curve-getendparam pline))
  41.         (setq paramsall (cons (setq k (1+ k)) paramsall))
  42.       )
  43.       (setq paramsall (reverse paramsall))
  44.                                 pline
  45.                                 (vlax-curve-getclosestpointto pline (trans (cadr ent) 1 0))
  46.                               )
  47.                          )
  48.                          params
  49.                    )
  50.       )
  51.       (HighlightSegment pline (car params))
  52.       (while (and (not (initget "X")) (/= (setq ent (entsel "\nSelect next segment or [eXit] : ")) "X"))
  53.         (if (and ent (equal (vlax-ename->vla-object (car ent)) pline))
  54.           (progn (setq par    (fix (vlax-curve-getParamAtPoint
  55.                                      pline
  56.                                      (vlax-curve-getclosestpointto pline (trans (cadr ent) 1 0))
  57.                                    )
  58.                               )
  59.                        params (if (member par params)
  60.                                 (vl-remove par params)
  61.                                 (cons par params)
  62.                               )
  63.                  )
  64.                  (redraw)
  65.                  (foreach p params (HighlightSegment pline p))
  66.           )
  67.         )
  68.       )
  69.       (if (setq side (getpoint (if (minusp (getvar "OFFSETDIST"))
  70.                                  "\nSpecify through point : "
  71.                                  "\nSpecify point on side to offset : "
  72.                                )
  73.                      )
  74.           )
  75.         (progn
  76.           (redraw)
  77.           (vla-StartUndoMark *acdoc*)
  78.           (setq side    (ilp (trans side 1 0)
  79.                              ((lambda (p)
  80.                                 (trans (list (car p) (cadr p) (1+ (caddr p)))
  81.                                        2
  82.                                        0
  83.                                 )
  84.                               )
  85.                                (trans side 1 2)
  86.                              )
  87.                              (trans (list 0 0 elevat) normal 0)
  88.                              normal
  89.                         )
  90.                 closest (vlax-curve-getClosestPointTo pline side T)
  91.                 par     (vlax-curve-getParamAtPoint pline closest)
  92.           )
  93.           (if (minusp (getvar "OFFSETDIST"))
  94.             (setq ofdist (distance side closest))
  95.           )
  96.           (cond ((equal closest (vlax-curve-getStartPoint pline) 1e-9)
  97.                  (setq side (trans side 0 normal))
  98.                 )
  99.                 ((equal closest (vlax-curve-getEndPoint pline) 1e-9)
  100.                  (setq par  (- par 1)
  101.                        side (trans side 0 normal)
  102.                  )
  103.                 )
  104.                 ((= (fix par) par)
  105.                  (setq
  106.                    side (polar
  107.                           (trans closest 0 normal)
  108.                           ((if (clockwise-p
  109.                                  (trans (vlax-curve-getPointAtParam
  110.                                           pline
  111.                                           (- par 0.1)
  112.                                         )
  113.                                         0
  114.                                         normal
  115.                                  )
  116.                                  (trans closest 0 normal)
  117.                                  (trans (vlax-curve-getPointAtParam
  118.                                           pline
  119.                                           (+ par 0.1)
  120.                                         )
  121.                                         0
  122.                                         normal
  123.                                  )
  124.                                )
  125.                              +
  126.                              -
  127.                            )
  128.                             (angle
  129.                               '(0 0 0)
  130.                               (trans (vlax-curve-getFirstDeriv pline par)
  131.                                      0
  132.                                      normal
  133.                                      T
  134.                               )
  135.                             )
  136.                             (/ pi 2)
  137.                           )
  138.                           ofdist
  139.                         )
  140.                  )
  141.                 )
  142.                 (T
  143.                  (setq par  (fix par)
  144.                        side (trans side 0 normal)
  145.                  )
  146.                 )
  147.           )
  148.           (setq bulge (vla-getBulge pline (fix par))
  149.                 p1    (trans (vlax-curve-getPointAtParam pline (fix par))
  150.                              0
  151.                              normal
  152.                       )
  153.                 p2    (trans (vlax-curve-getPointAtParam pline (1+ (fix par)))
  154.                              0
  155.                              normal
  156.                       )
  157.           )
  158.           (if (zerop bulge)
  159.             (if (clockwise-p side p2 p1)
  160.               (setq ofdist (- ofdist))
  161.             )
  162.             (progn
  163.               (setq arc_data (PolyArc-data bulge p1 p2))
  164.               (if (minusp bulge)
  165.                 (if (< (cadr arc_data) (distance (car arc_data) side))
  166.                   (setq ofdist (- ofdist))
  167.                 )
  168.                 (if (< (distance (car arc_data) side) (cadr arc_data))
  169.                   (setq ofdist (- ofdist))
  170.                 )
  171.               )
  172.             )
  173.           )
  174.           (setq el (entlast) ell el)
  175.           (mapcar
  176.             (function (lambda (p)
  177.                         (vl-catch-all-apply 'vla-Offset (list p ofdist))
  178.                         (vla-delete p)
  179.                       )
  180.             )
  181.             (Copysegments pline params)
  182.           )
  183.           (setq paramsr (vl-remove-if (function (lambda (x) (vl-position x params))) paramsall))
  184.           (foreach par paramsr
  185.             (Copysegments pline (list par))
  186.           )
  187.           (setq ss (ssadd))
  188.           (while (setq el (entnext el))
  189.             (ssadd el ss)
  190.           )
  191.           (setq pea (getvar 'peditaccept))
  192.           (setvar 'peditaccept 1)
  193.           (vl-cmdf "_.PEDIT" "_M" ss "" "_J" "_J" "_E" 1e+6)
  194.           (while (< 0 (getvar 'cmdactive)) (vl-cmdf ""))
  195.           (setvar 'peditaccept pea)
  196.           (setq el (entlast))
  197.           (if (/= (vlax-curve-getendparam pline) (vlax-curve-getendparam el))
  198.             (while (setq ell (entnext ell))
  199.               (entdel ell)
  200.             )
  201.           )
  202.           (if (and el (not (vlax-erased-p el)) (= (vla-get-closed pline) :vlax-false))
  203.             (progn
  204.               (entdel (setq pline (vlax-vla-object->ename pline)))
  205.               (if (vlax-curve-getpointatparam el (+ (vlax-curve-getparamatpoint el (vlax-curve-getclosestpointto el (cdr (assoc 11 (entget li2))))) 0.1))
  206.                 (vl-cmdf "_.TRIM" li1 li2 "" "_non" (trans (vlax-curve-getpointatparam el (+ (vlax-curve-getparamatpoint el (vlax-curve-getclosestpointto el (cdr (assoc 11 (entget li2))))) 0.1)) 0 1) "")
  207.               )
  208.               (entdel pline)
  209.               (if (/= (vlax-curve-getendparam pline) (vlax-curve-getendparam el))
  210.                 (progn
  211.                   (entdel pline)
  212.                   (if (vlax-curve-getpointatparam el (- (vlax-curve-getparamatpoint el (vlax-curve-getclosestpointto el (cdr (assoc 11 (entget li2))))) 0.1))
  213.                     (vl-cmdf "_.TRIM" li1 li2 "" "_non" (trans (vlax-curve-getpointatparam el (- (vlax-curve-getparamatpoint el (vlax-curve-getclosestpointto el (cdr (assoc 11 (entget li2))))) 0.1)) 0 1) "")
  214.                   )
  215.                   (entdel pline)
  216.                 )
  217.               )
  218.               (entdel li1)
  219.               (entdel li2)
  220.               (if (/= (vlax-curve-getendparam pline) (vlax-curve-getendparam el))
  221.                 (while (setq ell (entnext ell))
  222.                   (entdel ell)
  223.                 )
  224.               )
  225.             )
  226.           )
  227.           (vla-EndUndoMark *acdoc*)
  228.         )
  229.       )
  230.     )
  231.     (princ "\nInvalid entity.")
  232.   )
  233.   (princ)
  234. )
  235.  
  236. ;; CopySegments
  237. ;; Duplicates polyline segments at the same location
  238. ;; Consecutive selected segments are joined
  239. ;;
  240. ;; Arguments
  241. ;; pline : the source polyline (vla-object)
  242. ;; params ; the index list of segment to be copied
  243. ;;
  244. ;; Return
  245. ;; the list of created polylines
  246.  
  247. (defun CopySegments (pline params / nor space tmp copy ret)
  248.   (or *acdoc*
  249.   )
  250.   (setq params (vl-sort params '<)
  251.         nor    (vlax-get pline 'Normal)
  252.         space  (vla-ObjectIDToObject *acdoc* (vla-get-OwnerID pline))
  253.   )
  254.   (while params
  255.     (setq tmp    (cons (car params) tmp)
  256.           params (cdr params)
  257.     )
  258.     (if (and (zerop (car tmp))
  259.              (= (- (vlax-curve-getEndParam pline) 1) (last params))
  260.              (equal (vlax-curve-getStartPoint pline)
  261.                     (vlax-curve-getEndPoint pline)
  262.                     1e-9
  263.              )
  264.         )
  265.       (progn (setq params (reverse params)
  266.                    tmp    (cons (car params) tmp)
  267.                    params (cdr params)
  268.              )
  269.              (while (= (car params) (1- (car tmp)))
  270.                (setq tmp    (cons (car params) tmp)
  271.                      params (cdr params)
  272.                )
  273.              )
  274.              (setq tmp    (reverse tmp)
  275.                    params (reverse params)
  276.              )
  277.       )
  278.     )
  279.     (while (= (car params) (1+ (car tmp)))
  280.       (setq tmp    (cons (car params) tmp)
  281.             params (cdr params)
  282.       )
  283.     )
  284.     (setq tmp (reverse (cons (1+ (car tmp)) tmp)))
  285.     (setq
  286.       pts (vl-remove
  287.             nil
  288.             (mapcar
  289.               (function
  290.                 (lambda (pa / pt)
  291.                   (if (setq pt (vlax-curve-getPointAtParam pline pa))
  292.                     ((lambda (p) (list (car p) (cadr p)))
  293.                       (trans pt 0 nor)
  294.                     )
  295.                   )
  296.                 )
  297.               )
  298.               tmp
  299.             )
  300.           )
  301.     )
  302.     (setq copy (vlax-invoke
  303.                  space
  304.                  'addLightWeightPolyline
  305.                  (apply 'append pts)
  306.                )
  307.     )
  308.     (foreach p (cdr (reverse tmp))
  309.       (vla-setBulge
  310.         copy
  311.         (vl-position p tmp)
  312.         (vla-getBulge pline p)
  313.       )
  314.       (vla-getWidth pline p 'swid 'ewid)
  315.       (vla-setWidth copy (vl-position p tmp) swid ewid)
  316.     )
  317.     (foreach prop '(Elevation       Layer           Linetype
  318.                     LinetypeGeneration              LinetypeScale
  319.                     Lineweight      Normal          Thickness
  320.                     TrueColor
  321.                    )
  322.       (if (vlax-property-available-p pline prop)
  323.         (vlax-put copy prop (vlax-get pline prop))
  324.       )
  325.     )
  326.     (setq tmp nil
  327.           ret (cons copy ret)
  328.     )
  329.   )
  330. )
  331.  
  332. ;;======================================================;;
  333. ;; HighlightSegment
  334. ;; Highlight a polyline segment
  335. ;;
  336. ;; Arguments
  337. ;; pl : the polyline (vla-object)
  338. ;; par : the segment index
  339.  
  340. (defun HighlightSegment (pl par / p1 p2 n lst)
  341.   (and
  342.     (setq p1 (vlax-curve-getPointAtParam pl par))
  343.     (setq p1 (trans p1 0 1))
  344.     (setq p2 (vlax-curve-getPointAtParam pl (+ par 1)))
  345.     (setq p2 (trans p2 0 1))
  346.     (if (zerop (vla-getBulge pl par))
  347.       (grvecs (list -1 p1 p2))
  348.       (progn (setq n 0)
  349.              (repeat 100
  350.                (setq lst (cons
  351.                            (trans (vlax-curve-getPointAtParam pl (+ n par)) 0 1)
  352.                            lst
  353.                          )
  354.                      n   (+ n 0.01)
  355.                )
  356.              )
  357.              (grvecs
  358.                (cons -1 (apply 'append (mapcar 'list lst (cdr lst))))
  359.              )
  360.       )
  361.     )
  362.   )
  363. )
  364.  
  365. ;;=====================================================;;
  366. ;;; Clockwise-p
  367. ;;; Returns T if p1 p2 and p3 are clockwise
  368.  
  369. (defun clockwise-p (p1 p2 p3)
  370.   (< (sin (- (angle p1 p3) (angle p1 p2))) -1e-14)
  371. )
  372.  
  373. ;;========================================================;;
  374. ;;; Polyarc-data
  375. ;;; Returns a list of the center, radius and angle of a 'polyarc'.
  376.  
  377. (defun polyarc-data (bu p1 p2 / ang rad cen area cg)
  378.   (setq ang (* 2 (atan bu))
  379.         rad (/ (distance p1 p2) (* 2 (sin ang)))
  380.         cen (polar p1 (+ (angle p1 p2) (- (/ pi 2) ang)) rad)
  381.   )
  382.   (list cen (abs rad) ang)
  383. )
  384.  
  385. ;;====================================================;;
  386. ;;; VXV Returns the dot product of two vectors
  387.  
  388. (defun vxv (v1 v2) (apply '+ (mapcar '* v1 v2)))
  389.  
  390. ;;===================================================;;
  391. ;;; ILP
  392. ;;; Returns the intersection point between a line (extended) and a plane
  393. ;;;
  394. ;;; Arguments
  395. ;;; p1 and p2 : two points defining the line
  396. ;;; org : a point on the plane
  397. ;;; nor : the plane normal
  398.  
  399. (defun ilp (p1 p2 org nor / scl)
  400.   (setq
  401.     scl (/ (vxv nor (mapcar '- p1 org)) (vxv nor (mapcar '- p2 p1)))
  402.   )
  403.   (mapcar (function (lambda (x1 x2) (+ (* scl (- x1 x2)) x1)))
  404.           p1
  405.           p2
  406.   )
  407. )
  408.  

M.R.
« Last Edit: August 27, 2017, 06:34:05 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: ---={ Challenge }=--- Selective offset of polygonal pline edges
« Reply #5 on: August 21, 2017, 10:42:33 AM »
Hi,

Here's the last version published on this page.
It defines 2 commands: OFSEGS (OFfset SEGmentS) and COPSEGS (COPy SEGmentS)

You should have to learn some French...

Code - Auto/Visual Lisp: [Select]
  1. ;;; OFSEGS (gile) 26/08/08
  2. ;;; Décale les segments de polyligne sélectionnés.
  3.  
  4. (defun c:ofsegs (/ ofdist   ent      pline    normal   elevat   params
  5.                    points   side     closest  par      bulge    p1
  6.                    p2       arc_data
  7.                   )
  8.   (or *acdoc*
  9.   )
  10.   (initget 6 "Par")
  11.   (if (setq
  12.         ofdist (getdist
  13.                  (strcat "\nSpécifiez la distance de décalage ou [Par] <"
  14.                          (if (< (getvar "OFFSETDIST") 0)
  15.                            "par"
  16.                            (rtos (getvar "OFFSETDIST"))
  17.                          )
  18.                          ">: "
  19.                  )
  20.                )
  21.       )
  22.     (if (= ofdist "Par")
  23.       (setvar "OFFSETDIST" -1)
  24.       (setvar "OFFSETDIST" ofdist)
  25.     )
  26.     (setq ofdist (getvar "OFFSETDIST"))
  27.   )
  28.   (if (and (setq ent (entsel "\nSélectionnez un segment à décaler: "))
  29.            (setq pline (vlax-ename->vla-object (car ent)))
  30.            (= (vla-get-ObjectName pline) "AcDbPolyline")
  31.            (setq normal (vlax-get pline 'Normal))
  32.            (setq elevat (vla-get-Elevation pline))
  33.       )
  34.     (progn
  35.                                 pline
  36.                                 (trans (osnap (cadr ent) "_nea") 1 0)
  37.                               )
  38.                          )
  39.                          params
  40.                    )
  41.       )
  42.       (HighlightSegment pline (car params))
  43.       (while
  44.         (setq ent (entsel "\nSélectionnez le segment suivant ou <Quitter>: "))
  45.          (if (equal (vlax-ename->vla-object (car ent)) pline)
  46.            (progn
  47.              (setq par (fix (vlax-curve-getParamAtPoint
  48.                               pline
  49.                               (trans (osnap (cadr ent) "_nea") 1 0)
  50.                             )
  51.                        )
  52.                    params (if (member par params)
  53.                             (vl-remove par params)
  54.                             (cons par params)
  55.                             )
  56.              )
  57.              (redraw)
  58.              (foreach p params (HighlightSegment pline p))
  59.            )
  60.          )
  61.       )
  62.       (if (setq side (GetPointAboutPlane
  63.                        normal
  64.                        (trans (list 0 0 elevat) normal 0)
  65.                        (if (minusp (getvar "OFFSETDIST"))
  66.                          "\nSpécifiez une valeur pour \"Par le point\": "
  67.                          "\nSpécifiez un point sur le côté à décaler: "
  68.                        )
  69.                      )
  70.           )
  71.         (progn
  72.           (redraw)
  73.           (vla-StartUndoMark *acdoc*)
  74.           (setq closest (vlax-curve-getClosestPointTo pline side T)
  75.                 par     (vlax-curve-getParamAtPoint pline closest)
  76.           )
  77.           (if (minusp (getvar "OFFSETDIST"))
  78.             (setq ofdist (distance side closest))
  79.           )
  80.           (cond
  81.             ((equal closest (vlax-curve-getStartPoint pline) 1e-9)
  82.              (setq side (trans side 0 normal))
  83.             )
  84.             ((equal closest (vlax-curve-getEndPoint pline) 1e-9)
  85.              (setq par  (- par 1)
  86.                    side (trans side 0 normal)
  87.              )
  88.             )
  89.             ((= (fix par) par)
  90.              (setq side
  91.                     (polar
  92.                       (trans closest 0 normal)
  93.                       ((if
  94.                          (clockwise-p
  95.                            (trans
  96.                              (vlax-curve-getPointAtParam pline (- par 0.1))
  97.                              0
  98.                              normal
  99.                            )
  100.                            (trans closest 0 normal)
  101.                            (trans
  102.                              (vlax-curve-getPointAtParam pline (+ par 0.1))
  103.                              0
  104.                              normal
  105.                            )
  106.                          )
  107.                           +
  108.                           -
  109.                        )
  110.                         (angle '(0 0 0)
  111.                                (trans (vlax-curve-getFirstDeriv pline par)
  112.                                       0
  113.                                       normal
  114.                                       T
  115.                                )
  116.                         )
  117.                         (/ pi 2)
  118.                       )
  119.                       ofdist
  120.                     )
  121.              )
  122.             )
  123.             (T
  124.              (setq par  (fix par)
  125.                    side (trans side 0 normal)
  126.              )
  127.             )
  128.           )
  129.           (setq bulge (vla-getBulge pline (fix par))
  130.                 p1    (trans (vlax-curve-getPointAtParam pline (fix par))
  131.                              0
  132.                              normal
  133.                       )
  134.                 p2    (trans (vlax-curve-getPointAtParam pline (1+ (fix par)))
  135.                              0
  136.                              normal
  137.                       )
  138.           )
  139.           (if (zerop bulge)
  140.             (if (clockwise-p side p2 p1)
  141.               (setq ofdist (- ofdist))
  142.             )
  143.             (progn
  144.               (setq arc_data (PolyArc-data bulge p1 p2))
  145.               (if (minusp bulge)
  146.                 (if (< (cadr arc_data)
  147.                        (distance (car arc_data) side)
  148.                     )
  149.                   (setq ofdist (- ofdist))
  150.                 )
  151.                 (if (< (distance (car arc_data) side)
  152.                        (cadr arc_data)
  153.                     )
  154.                   (setq ofdist (- ofdist))
  155.                 )
  156.               )
  157.             )
  158.           )
  159.           (mapcar
  160.             (function
  161.               (lambda (p)
  162.                 (vl-catch-all-apply 'vla-Offset (list p ofdist))
  163.                 (vla-delete p)
  164.               )
  165.             )
  166.             (Copysegments pline params)
  167.           )
  168.           (vla-EndUndoMark *acdoc*)
  169.         )
  170.       )
  171.     )
  172.     (princ "\nEntité non valide.")
  173.   )
  174.   (princ)
  175. )
  176.  
  177. ;;================================================================;;
  178.  
  179. ;; COPSEGS (gile) 26/03/08
  180. ;; Copie les segments de polyligne sélectionnés.
  181.  
  182. (defun c:copsegs (/ ent pl par lst)
  183.   (if (and (setq ent (entsel "\nSélectionnez un segment à copier: "))
  184.            (setq pl (vlax-ename->vla-object (car ent)))
  185.            (= (vla-get-ObjectName pl) "AcDbPolyline")
  186.       )
  187.     (progn
  188.                        pl
  189.                        (trans (osnap (cadr ent) "_nea") 1 0)
  190.                      )
  191.                 )
  192.             lst (cons par lst)
  193.       )
  194.       (HighlightSegment pl par)
  195.       (while
  196.         (setq ent (entsel "\nSélectionnez le segment suivant ou <Quitter>: "))
  197.          (if (equal (vlax-ename->vla-object (car ent)) pl)
  198.            (progn
  199.              (setq par (fix (vlax-curve-getParamAtPoint
  200.                               pl
  201.                               (trans (osnap (cadr ent) "_nea") 1 0)
  202.                             )
  203.                        )
  204.                    lst (if (member par lst)
  205.                          (vl-remove par lst)
  206.                          (cons par lst)
  207.                          )
  208.              )
  209.              (redraw)
  210.              (foreach p lst (HighlightSegment pl p))
  211.            )
  212.          )
  213.       )
  214.       (setq lst (vl-sort lst '<))
  215.       (if (setq from (getpoint "\nSpécifiez le point de base: "))
  216.         (while (and
  217.                  (setq to (vl-catch-all-apply
  218.                             'getpoint
  219.                             (list from "\nSpécifiez le deuxième point: ")
  220.                           )
  221.                  )
  222.                  (listp to)
  223.                )
  224.           (mapcar (function (lambda (p)
  225.                               (vla-move p
  226.                                         (vlax-3d-point (trans from 1 0))
  227.                                         (vlax-3d-point (trans to 1 0))
  228.                               )
  229.                             )
  230.                   )
  231.                   (CopySegments pl lst)
  232.           )
  233.         )
  234.       )
  235.       (redraw)
  236.     )
  237.     (princ "\nEntité non valide.")
  238.   )
  239.   (princ)
  240. )
  241.  
  242. ;;================================================================;;
  243.  
  244.  
  245. ;; CopySegments
  246. ;; Copie des segments de polyligne
  247. ;; Les segments sont copiés à la même place et conservent leurs propriétés
  248. ;; Les segments jointifs sont unis en une polyligne unique
  249. ;;
  250. ;; Arguments
  251. ;; pline : la polyligne source (vla-object)
  252. ;; params ; la liste des indices des segment à copier
  253. ;;
  254. ;; Retour
  255. ;; la liste des polylignes créées
  256.  
  257. (defun CopySegments (pline params / nor space tmp copy ret)
  258.   (or *acdoc*
  259.   )
  260.   (setq params (vl-sort params '<)
  261.         nor    (vlax-get pline 'Normal)
  262.         space  (vla-ObjectIDToObject *acdoc* (vla-get-OwnerID pline))
  263.   )
  264.   (while params  
  265.     (setq tmp    (cons (car params) tmp)
  266.           params (cdr params)
  267.     )
  268.     (if (and (zerop (car tmp))
  269.              (= (- (vlax-curve-getEndParam pline) 1) (last params))
  270.              (equal (vlax-curve-getStartPoint pline)
  271.                     (vlax-curve-getEndPoint pline)
  272.                     1e-9
  273.              )
  274.         )
  275.       (progn
  276.         (setq params (reverse params)
  277.               tmp    (cons (car params) tmp)
  278.               params (cdr params)
  279.         )
  280.         (while (= (car params) (1- (car tmp)))
  281.           (setq tmp    (cons (car params) tmp)
  282.                 params (cdr params)
  283.           )
  284.         )
  285.         (setq tmp    (reverse tmp)
  286.               params (reverse params)
  287.         )
  288.       )
  289.     )
  290.     (while (= (car params) (1+ (car tmp)))
  291.       (setq tmp    (cons (car params) tmp)
  292.             params (cdr params)
  293.       )
  294.     )
  295.     (setq tmp (reverse (cons (1+ (car tmp)) tmp)))
  296.     (setq
  297.       pts
  298.        (vl-remove nil
  299.                   (mapcar
  300.                     (function
  301.                       (lambda (pa / pt)
  302.                         (if (setq pt (vlax-curve-getPointAtParam pline pa))
  303.                           ((lambda (p)
  304.                              (list (car p) (cadr p))
  305.                            )
  306.                             (trans pt 0 nor)
  307.                           )
  308.                         )
  309.                       )
  310.                     )
  311.                     tmp
  312.                   )
  313.        )
  314.     )
  315.     (setq copy
  316.            (vlax-invoke
  317.              space
  318.              'addLightWeightPolyline
  319.              (apply 'append pts)
  320.            )
  321.     )
  322.     (foreach p (cdr (reverse tmp))
  323.       (vla-setBulge
  324.         copy
  325.         (vl-position p tmp)
  326.         (vla-getBulge pline p)
  327.       )
  328.       (vla-getWidth pline p 'swid 'ewid)
  329.       (vla-setWidth copy (vl-position p tmp) swid ewid)
  330.     )
  331.     (foreach prop '(Elevation       Layer           Linetype
  332.                     LinetypeGeneration              LinetypeScale
  333.                     Lineweight      Normal          Thickness
  334.                     TrueColor
  335.                    )
  336.       (if (vlax-property-available-p pline prop)
  337.         (vlax-put copy prop (vlax-get pline prop))
  338.       )
  339.     )
  340.     (setq tmp nil
  341.           ret (cons copy ret)
  342.     )
  343.   )
  344. )
  345.  
  346. ;;================================================================;;
  347.  
  348. ;; HighlightSegment
  349. ;; Met un segment de polyligne en surbrillance
  350. ;;
  351. ;; Arguments
  352. ;; pl : la polyligne (vla-object)
  353. ;; par : l'indice du segment
  354.  
  355. (defun HighlightSegment (pl par / p1 p2 n lst)
  356.   (and
  357.     (setq p1 (vlax-curve-getPointAtParam pl par))
  358.     (setq p1 (trans p1 0 1))
  359.     (setq p2 (vlax-curve-getPointAtParam pl (+ par 1)))
  360.     (setq p2 (trans p2 0 1))
  361.     (if (zerop (vla-getBulge pl par))
  362.       (grvecs (list -255 p1 p2))
  363.       (progn
  364.         (setq n 0)
  365.         (repeat 100
  366.           (setq lst (cons (trans (vlax-curve-getPointAtParam pl (+ n par)) 0 1)
  367.                           lst
  368.                     )
  369.                 n   (+ n 0.01)
  370.           )
  371.         )
  372.         (grvecs
  373.           (cons -255 (apply 'append (mapcar 'list lst (cdr lst))))
  374.         )
  375.       )
  376.     )
  377.   )
  378. )
  379.  
  380. ;;================================================================;;
  381.  
  382. ;;; Clockwise-p
  383. ;;; Retourne T si les points p1 p2 et p3 tournent dans le sens horaire
  384.  
  385. (defun clockwise-p (p1 p2 p3)
  386.   (< (sin (- (angle p1 p3) (angle p1 p2))) -1e-14)
  387. )
  388.  
  389. ;;================================================================;;
  390.  
  391. ;;; Polyarc-data
  392. ;;; Retourne la liste des données d'un arc de polyligne (centre rayon angle).
  393.  
  394. (defun polyarc-data (bu p1 p2 / ang rad cen area cg)
  395.   (setq ang (* 2 (atan bu))
  396.         rad (/ (distance p1 p2)
  397.                (* 2 (sin ang))
  398.             )
  399.         cen (polar p1
  400.                    (+ (angle p1 p2) (- (/ pi 2) ang))
  401.                    rad
  402.             )
  403.   )
  404.   (list cen (abs rad) ang)
  405. )
  406.  
  407. ;;================================================================;;
  408.  
  409. ;; GETPOINTABOUTPLANE
  410. ;; Retourne le point d'intersection de la perpendiculaire à la vue courante passant
  411. ;; par le point saisi par l'utilsateur et le plan défini par sa normale et un point.
  412. ;;
  413. ;; Arguments
  414. ;; nor : le vecteur normal du plan d'intersection
  415. ;; org : un point sur le plan d'intersection (SCG)
  416. ;; msg : le message d'invite ou ""
  417. ;;
  418. ;; Retour : les coordonnées (SCG) du point d'intersection ou nil
  419.  
  420. (defun GetPointAboutPlane (nor org msg / p1 p2 sc)
  421.   (if (and (setq p1 (getpoint msg))
  422.            (setq p1 (trans p1 1 0))
  423.            (setq p2 (trans p1 0 2))
  424.            (setq p2 (trans (list (car p2) (cadr p2) (1+ (caddr p2))) 2 0))
  425.            (/= 0
  426.                (setq sc (apply '+ (mapcar '* nor (mapcar '- p2 p1))))
  427.            )
  428.       )
  429.     (mapcar
  430.       (function
  431.         (lambda (x1 x2)
  432.           (+ (* (/ (apply '+ (mapcar '* nor (mapcar '- p1 org))) sc)
  433.                 (- x1 x2)
  434.              )
  435.              x1
  436.           )
  437.         )
  438.       )
  439.       p1
  440.       p2
  441.     )
  442.   )
  443. )
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: ---={ Challenge }=--- Selective offset of polygonal pline edges
« Reply #6 on: August 21, 2017, 01:01:14 PM »
This may also be of interest: Offset Polyline Section - the program will allow you to offset a section of a selected polyline between any two selected points, therefore the user is not restricted to full segments.