Author Topic: Open curve -> Double Offset and cap  (Read 1879 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 812
Open curve -> Double Offset and cap
« on: November 23, 2017, 12:53:11 PM »
Hey guys,

Bla-bla-bla... read this if you want:
There was a question in another forum, where the task was to "cap" two curves (that are most likely offseted, but not always).
So Tharwat did a wonderful job there, to compare the distance between each 'Endpoint and 'Startpoint from the pair of curves to determine the correct 'chain solution', hence he wrote a "quick" capping routine.
My input there was by using a grread toggle (to ask the user if the result is correct), hehe - Unfortunately that thread got 'old' and was buried down in the history (so I'm unable to find it).


However, one most likely would perform offset at first and then would cap.. so I came up with this variation (written as subfunction) :
Code - Auto/Visual Lisp: [Select]
  1. ; c - open curve
  2. ; d - cap size
  3. ; Returns: The cap'ped polyline
  4. ; Example: (OpenCurve->DoubleOffsetNcap (car (entsel)) 60)
  5. (defun OpenCurve->DoubleOffsetNcap ( c d / *error* oL spc vL IsLineSpline UseLwPoly o )
  6.  
  7.   (defun *error* ( m )
  8.     (and oL (mapcar 'vla-Delete oL))
  9.     (and m (princ m)) (princ)
  10.   ); defun *error*
  11.  
  12.   ; Point list to safearray
  13.   (defun pL->SafeArray ( pL )
  14.     (if (vl-every 'numberp (setq pL (apply 'append pL)))
  15.       (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length pL)))) pL)
  16.     )
  17.   ); defun pL->SafeArray
  18.  
  19.   ; Basic function to get the point list from ename/vla-object
  20.   (defun GetCoords ( e )
  21.     (if (or (eq 'ENAME (type e)) (eq 'ENAME (type (setq e (vlax-vla-object->ename e)))))
  22.       (apply 'append (mapcar '(lambda (x) (if (member (car x) '(10 11)) (list (cdr x)))) (entget e)))
  23.     )
  24.   ); defun GetCoords
  25.  
  26.   (and (eq 'ENAME (type c)) (setq c (vlax-ename->vla-object c)))
  27.   (cond
  28.     ( (and (numberp d) c (eq 'VLA-OBJECT (type c)) (not (vlax-curve-isClosed c)) (vlax-method-applicable-p c 'Offset) ) ; Offset method is not supported for 3d polys
  29.       (setq d (/ d 2.))
  30.       (setq oL (apply 'append (mapcar '(lambda (x) (vlax-invoke c 'Offset x)) (list d (- d))))) ; list of vla-objects, with the same objectname as 'c'
  31.       (setq vL (append (GetCoords (car oL)) (reverse (GetCoords (cadr oL))))) ; clockwise or not, aslong we reverse the 2nd pointlist will work
  32.       (and
  33.         (setq IsLineSpline (member (vla-get-ObjectName c) '("AcDbLine" "AcDbSpline")))
  34.         (setq UseLwPoly (vl-every '(lambda (x) (zerop (last x))) vL))
  35.         (setq vL (mapcar '(lambda (x) (list (car x) (cadr x))) vL)) ; remove z-coords
  36.       ); and
  37.       (setq vL (pL->SafeArray vL))
  38.       (and
  39.         (setq o
  40.           (if IsLineSpline
  41.             ((if UseLwPoly vla-AddLightWeightPolyline vla-Add3Dpoly) spc vL)
  42.             (vla-AddLightWeightPolyline spc vL)
  43.           )
  44.         ); setq o
  45.         (vlax-put o 'Closed -1)
  46.       ); and
  47.     )
  48.   ); cond
  49.   (*error* nil) o ; so if 'c' was a 3D line, then it will return 3DPoly, else LightWeightPoly
  50. ); defun OpenCurve->DoubleOffsetNcap

This is just an idea for a potentially useful subfunction.  :idea:
But I'd like to see your shots at this (since I think my code is sloppy, and doesn't work with arcs).
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg