Author Topic: Close a spline?  (Read 5031 times)

0 Members and 1 Guest are viewing this topic.

CHulse

  • Swamp Rat
  • Posts: 504
Close a spline?
« on: July 09, 2015, 04:28:07 PM »
I'm working on a lisp to create a set of closed splines to represent tree canopies measured from the cardinal points (N-S-E-W, for asymmetrical tree canopies).  So I've found some examples and been able to get a program to make a spline from 4 supplied points, but I have not been able to get it to close. Help??

I found the code below here:
http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/defining-points-for-spline-command/td-p/3399551

Code: [Select]
(setq mySplineObj
  (vla-addSpline *ModelSpace* FitPointsData StartTan EndTan)
  )

I just don't understand the parameters used - the tangent points?

I was surprised to find that there seems to be no simple property to set to close it. I expected (vlax-put-property mySplineObj 'Closed :vlax-true) to work but it doesn't.

Any help would be much appreciated.
Thanks
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Close a spline?
« Reply #1 on: July 09, 2015, 04:40:03 PM »
Try this:
Code - Auto/Visual Lisp: [Select]
  1. (vlax-put mySplineObj 'Closed2 -1)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CHulse

  • Swamp Rat
  • Posts: 504
Re: Close a spline?
« Reply #2 on: July 10, 2015, 06:50:24 AM »
Try this:
Code - Auto/Visual Lisp: [Select]
  1. (vlax-put mySplineObj 'Closed2 -1)

Bingo  8-)

Thanks!!
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

CHulse

  • Swamp Rat
  • Posts: 504
Re: Close a spline?
« Reply #3 on: July 10, 2015, 06:54:39 AM »
So my next question then is where can you find that info? Is there a reference?
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

ChrisCarlson

  • Guest
Re: Close a spline?
« Reply #4 on: July 10, 2015, 08:19:42 AM »
Code - Auto/Visual Lisp: [Select]
  1. (vlax-dump-object (vlax-ename->vla-object (car (entsel))) t)

Will dump all the properties of an object

Code: [Select]
Command: DUMP-OBJECT
Select object: ; IAcadSpline: AutoCAD Spline Interface
; Property values:
;   Application (RO) = Exception occurred
;   Area (RO) = 2.15625e+007
;   Closed (RO) = 0
;   Closed2 = 0 <---------------
;   ControlPoints = (13992.0 1892.69 0.0 14331.0 2848.65 0.0 ... )
;   Degree (RO) = 3
;   Degree2 = 3
;   Document (RO) = #<VLA-OBJECT IAcadDocument 0000004073afe598>
;   EndTangent = (0.0 0.0 0.0)
;   EntityTransparency = "ByLayer"
;   FitPoints = (13992.0 1892.69 0.0 15547.5 4580.44 0.0 ... )
;   FitTolerance = 1.0e-006
;   Handle (RO) = "4E236"
;   HasExtensionDictionary (RO) = 0
;   Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 00000040695a2678>
;   IsPeriodic (RO) = 0
;   IsPlanar (RO) = -1
;   IsRational (RO) = 0
;   KnotParameterization = 0
;   Knots = (0.0 0.0 0.0 0.0 3105.46 7862.9 ... )
;   Layer = "0"
;   Linetype = "BYLAYER"
;   LinetypeScale = 1.0
;   Lineweight = -1
;   Material = "ByLayer"
;   NumberOfControlPoints (RO) = 7
;   NumberOfFitPoints (RO) = 5
;   ObjectID (RO) = 295
;   ObjectName (RO) = "AcDbSpline"
;   OwnerID (RO) = 294
;   PlotStyleName = "ByLayer"
;   SplineFrame = 1
;   SplineMethod = 0
;   StartTangent = (0.0 0.0 0.0)
;   TrueColor = #<VLA-OBJECT IAcadAcCmColor 00000040695a2310>
;   Visible = -1
;   Weights = AutoCAD.Application: No weights available for polynomial spline
; Methods supported:
;   AddFitPoint (2)
;   ArrayPolar (3)
;   ArrayRectangular (6)
;   Copy ()
;   Delete ()
;   DeleteFitPoint (1)
;   ElevateOrder (1)
;   GetBoundingBox (2)
;   GetControlPoint (1)
;   GetExtensionDictionary ()
;   GetFitPoint (1)
;   GetWeight (1)
;   GetXData (3)
;   Highlight (1)
;   IntersectWith (2)
;   Mirror (2)
;   Mirror3D (3)
;   Move (2)
;   Offset (1)
;   PurgeFitData ()
;   Reverse ()
;   Rotate (2)
;   Rotate3D (3)
;   ScaleEntity (2)
;   SetControlPoint (2)
;   SetFitPoint (2)
;   SetWeight (2)
;   SetXData (2)
;   TransformBy (1)
;   Update ()

It seems odd that a closed spline has a property of -1, one would think its a 1?

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Close a spline?
« Reply #5 on: July 10, 2015, 09:18:55 AM »
Try this:
Code - Auto/Visual Lisp: [Select]
  1. (vlax-put mySplineObj 'Closed2 -1)

Bingo  8)

Thanks!!
Glad to help  :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Close a spline?
« Reply #6 on: July 10, 2015, 10:42:57 AM »
It seems odd that a closed spline has a property of -1, one would think its a 1?
I used to think that too. But look:
Code: [Select]
(KGA_Math_Dec_To_Bin32 -1) => "11111111111111111111111111111111"

Pad

  • Bull Frog
  • Posts: 342
Re: Close a spline?
« Reply #7 on: July 16, 2015, 03:41:44 PM »
Hi Cary,

Would you mind posting the working code here please?

Thanks
P

CHulse

  • Swamp Rat
  • Posts: 504
Re: Close a spline?
« Reply #8 on: July 17, 2015, 07:14:32 AM »
I'm not much of a programmer, but I've been able to make things work by combining other folks' efforts for my own unique purposes. So I take no real credit for this, but rather give the credit to LeeMac, CAB, ronjonp and others here who have helped me. Thanks to everyone here.

That said, this is the final (?) version. Open to suggestions for improvement of course :)

Code: [Select]
;; Tree Canopy Splines (plines)
;; compiled by Cary Hulse 7/10/15
;;
;; create closed spline from 4 points to represent tree canopy
;; input from CSV - format Tree#,canopy radii(n,e,s,w),E(X),N(Y)
;; assumes elevation of 0 for all points
;; converts splines to plines
;; creates objects on "LJ-PLNT-TREE-CNPY" layer
;;
;;original main code from http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/defining-points-for-spline-command/td-p/3399551
;;with help from the swamp here: http://www.theswamp.org/index.php?topic=49729.0
;; and here: http://www.theswamp.org/index.php?topic=1804.0
;; Thanks to LeeMac, CAB and ronjonp
;;
;;

(defun c:TREECAN (/  acadapp DOC *lst* *error* *ModelSpace* ptStartTan ptEndTan
    ptFit1 ptFit2 ptFit3 ptFit4 FitPoints ptlstlen
    FitPointsDataA FitPointsData StartTanA StartTan EndTanA EndTan mySplineObj
StrBrk BNME DDEL FILE LNAME NL OFILE PT SPC TAG UFLAG VALLST X CRZ CRD CANOPY LAY CRZ2 STAT VIZ xc yc
nr er sr wr)
 
  (vl-load-com)
  (setq DOC (vla-get-ActiveDocument (vlax-get-acad-object)))
(setq *ModelSpace* (vla-get-ModelSpace DOC))
 
  ;; --{  Error Handler Function by Lee Mac }--

  (defun *error* (msg)     
    (and ofile (close ofile))   
    (and uflag (vla-EndUndoMark doc))
   
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")       
        (princ (strcat "\n** Error: " msg " **")))   
    (princ)) 
   
  ;; --{  StrBrk Function  }-- By Lee Mac

  (defun StrBrk (str chrc / pos lst)
    (while (setq pos (vl-string-position chrc str))
      (setq lst (cons (substr str 1 pos) lst)
            str (substr str (+ pos 2))))
    (reverse (cons str lst)))
 
  ;;
  ;;----set layer and input data----
  ;;
  (setq lname "LJ-PLNT-TREE-CNPY") ;; Layer Name
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;         
 ;;;***********spline to pline converter subfunctions **************
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;from here: http://www.theswamp.org/index.php?topic=1804.0
 ;; by CAB
 
  (defun spl2pl(spline / usrlay usrosm usrplw ent pdist idx ss pl plist pentlst)
  (setq pdist 1) ; distance between points on new pline
  (setq pentlst '((0 . "LWPOLYLINE")
     (100 . "AcDbEntity")
     (67 . 0)
     (8 . "0")
     (100 . "AcDbPolyline")
     (90 . 7)
     (70 . 1);closed = 1
     (43 . 0.0)
     (38 . 0.0)
     (39 . 0.0)
    )
   )
  (setq end '(210 0.0 0.0 1.0));define polyline group codes
 
    (progn
     
        (setq ent spline
              pl pentlst)
        (if (setq plist (Spline->Pline ent pdist))
          (progn
            (foreach x plist
              (setq pl (append pl
                        (list (cons 10 (list (car x)(cadr x)))
                              (cons 40 0.0)
                              (cons 41 0.0)
                              (cons 42 0.0))))
            )
            ;;set number of points in polyline
            (setq pl (append
                       (subst (cons 90 (length plist)) (assoc 90 pl) pl)
                       pl
                       (list end))
            )
            ;;  update layer
            (setq pl (subst (assoc 8 (entget ent)) (assoc 8 pl) pl))
            (entmake pl);make polyline
            ;(entdel ent)
          ) ; progn
        ); endif
    ) ; progn
  (princ)
);defun

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;         
 ;;;***********spline -> pline subfunction**************
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;http://www.theswamp.org/index.php?topic=1804.0

(defun Spline->Pline (oSpline tol / 1stPoint dist fullLength lastPoint plinePoints point)
  (setq 1stPoint (vlax-curve-getPointAtParam oSpline (vlax-curve-getStartParam oSpline))
        lastPoint (vlax-curve-getPointAtParam oSpline (vlax-curve-getEndParam oSpline))
        fullLength (vlax-curve-getdistatparam oSpline (vlax-curve-getendparam oSpline))
        dist 0
        plinePoints (list 1stPoint)
  )
  (while (< (setq dist (+ dist tol)) fullLength)   
    (if (setq point (vlax-curve-getPointAtDist oSpline dist))
      (setq plinePoints (append plinePoints (list point)))
    )
  )
  (setq plinePoints (append plinePoints (list lastpoint)))
;;; Use the variable plinePoints (which is a list of vertex points)
);_end defun
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;         
 ;;;***********MAIN FINCTIONS**************
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;COUNTER FUNCTION and input data
 
 
  (if (and *lst* (not (initget "Start Continue")))
  (setq *lst* (if (= "Start" (getkword "\n[S]tart of File or [C]ontinue? <Continue> : ")) nil *lst*)))

  (if (or  *lst* (setq file (getfiled "Select Input File" (cond (*load_file*)  ("")) "csv;txt" 16)))

    (progn
      (setq uflag (not (vla-StartUndoMark doc))

            spc   (if (zerop (vla-get-activespace doc))
                    (if (= (vla-get-mspace doc) :vlax-true)
                      (vla-get-modelspace doc)
                      (vla-get-paperspace doc))
                    (vla-get-modelspace doc)))
     
     
      (if (not *lst*)
        (progn
          (setq dDel (if (eq ".CSV" (strcase (vl-filename-extension file))) 44 32)

                 *load_file* file ofile (open file "r"))

          (while (setq nl (read-line ofile))
            (setq *lst* (cons (StrBrk nl dDel) *lst*)))

          (setq ofile (close ofile) *lst* (reverse *lst*))))
 

 ;;begin spline creation for each entry in point list
  (while (setq x  (car *lst*))
           (setq
            xc (atof (nth 5 x))
            yc (ATOF (nth 6 x))
          );;_end setq       

;(setq PT (LIST xc yc 0))


  ;;set radius variables
   (setq nr (atof (nth 1 x)) ;north
         er (atof (nth 2 x)) ;east
         sr (atof (nth 3 x)) ;south
         wr (atof (nth 4 x)) ;west
    )

  ;;set fit point values =======
  (setq ptFit1 (list xc (+ yc nr) 0.0) ;north
        ptFit2 (list (+ xc er) yc 0.0) ;east
        ptFit3 (list xc (- yc sr) 0.0) ;south
        ptFit4 (list (- xc wr) yc 0.0) ;west
  )

    ;;set start & end tangent values
  (setq ptStartTan (list 0.0 0.0 0.0)
ptEndTan   (list 0.0 0.0 0.0))
  ;;create list of the fit point values
  (setq FitPoints
  (apply 'append (list ptFit1 ptFit2 ptFit3 ptFit4)))
 
  ;;create a safearray to hold the fit points
  (setq ptlstlen (length FitPoints))
   (setq FitPointsDataA (vlax-make-safearray vlax-vbDouble (cons 0 (1- ptlstlen))))
 
  ;;populate the safearray
  (vlax-safearray-fill FitPointsDataA FitPoints)
 
  ;;assign the safearray to a variant
  (setq FitPointsData
  (vlax-make-variant FitPointsDataA (logior vlax-vbarray vlax-vbDouble)))
 
  ;;create a safearray to hold the start tangent points
  (setq StartTanA
  (vlax-make-safearray vlax-vbDouble (cons 0 2)))
 
  ;;populate the safearray
  (vlax-safearray-fill StartTanA ptStartTan)
 
  ;;assign the safearray to a variant
  (setq StartTan
      (vlax-make-variant StartTanA (logior vlax-vbarray vlax-vbDouble)))
 
  ;;create a safearray to hold the end tangent points
  (setq EndTanA
  (vlax-make-safearray vlax-vbDouble(cons 0 2)))
 
  ;;populate the safearray
  (vlax-safearray-fill EndTanA ptEndTan)
 
  ;;assign the safearray to a variant
  (setq EndTan (vlax-make-variant EndTanA (logior vlax-vbarray vlax-vbDouble )))
 
  ;;create the spline object
  (setq mySplineObj
  (vla-addSpline *ModelSpace* FitPointsData StartTan EndTan))
 
  ;;close spline
  (vlax-put mySplineObj 'Closed2 -1)
 
 
  ;;change the color of the spline
  ;;(vla-Put-Color mySplineObj acBlue)
 
  ;;; CHECK FOR LAYER AND ADD IF NOT EXIST
            (or (tblsearch "LAYER" Lname)
            (vla-add (vla-get-layers doc) Lname))
            ;put obj on correct layer
            (vla-put-layer mySplineObj LName)
 
  (vla-Update mySplineObj)
  ;; convert to pline
 
  (spl2pl (vlax-vla-object->ename mySplineObj))

    (entdel (vlax-vla-object->ename mySplineObj))
   
   (setq *lst* (cdr *lst*))
  );_end while
 
   (setq uFlag (vla-EndUndoMark doc))
   );_end progn
   );_end if
  (princ)
 
);_end defun

;;------------------------------------------------------------;;


(princ)

(princ
  (strcat
    "\n:: TreeCanopySplines.lsp | C. Hulse::"
    "\n:: Type \"TREECAN\" to Invoke ::"
  )
)
(princ)

;;------------------------------------------------------------;;
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

Pad

  • Bull Frog
  • Posts: 342
Re: Close a spline?
« Reply #9 on: July 17, 2015, 08:39:10 AM »
Thanks Cary.

I have some asymmetric spreads to do today.

What format does the csv file need to be?

Cheers
P

ah sorry just seen
input from CSV - format Tree#,canopy radii(n,e,s,w),E(X),N(Y)

 :-)

CHulse

  • Swamp Rat
  • Posts: 504
Re: Close a spline?
« Reply #10 on: July 17, 2015, 09:26:29 AM »
Let me know how it works for you - I have not tested it heavily.

Are you doing tree canopies also? if so, out of curiosity - what state are you in?
« Last Edit: July 17, 2015, 09:41:18 AM by CHulse »
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Close a spline?
« Reply #11 on: July 17, 2015, 09:34:06 AM »
So what does this do? Trace a group of blocks?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CHulse

  • Swamp Rat
  • Posts: 504
Re: Close a spline?
« Reply #12 on: July 17, 2015, 09:40:56 AM »
So what does this do? Trace a group of blocks?

Nope - this allows me to collect tree data in excel (canopy dimensions in this case) and draw those canopies in plan view around a survey point (the northing/easting in the CSV). My data is all correlated by tree number in the master spreadsheet and data collection tool, that is why the CSV includes a tree number that is not actually used by the LISP.

As automated a process as I could come up with. I give Lee Mac all the credit for the original concept of taking excel data and creating cad graphics directly from it via a CSV. Brilliant and totally key to my typical workflow.
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Close a spline?
« Reply #13 on: July 17, 2015, 09:42:58 AM »
Cool .. you have a drawing\CSV to share? I'd like to see the input and result drawing. :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

AIberto

  • Guest
Re: Close a spline?
« Reply #14 on: July 17, 2015, 09:49:25 AM »
Cool .. you have a drawing\CSV to share? I'd like to see the input and result drawing. :)

+1  :lmao:

No demo. No CSV file  ,I don't know what's the use of this lisp?

CHulse

  • Swamp Rat
  • Posts: 504
Re: Close a spline?
« Reply #15 on: July 17, 2015, 10:56:39 AM »
Frankly didn’t expect to see so much interest in this.
This is a test data set.
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Close a spline?
« Reply #16 on: July 17, 2015, 11:07:48 AM »
Cool .. was just curious.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Pad

  • Bull Frog
  • Posts: 342
Re: Close a spline?
« Reply #17 on: July 20, 2015, 04:23:02 AM »
Let me know how it works for you - I have not tested it heavily.

Are you doing tree canopies also? if so, out of curiosity - what state are you in?

It looks to work well Cary.  I didn't use it this time, because I had a sub-contractor carry out the topo.  I popped back to measure the spreads and added them manually.  Next time I have a job with asymmetric spreads I will hopefully be making use of this.

Thanks P

CHulse

  • Swamp Rat
  • Posts: 504
Re: Close a spline?
« Reply #18 on: July 20, 2015, 06:50:16 AM »
Let me know how it works for you - I have not tested it heavily.

Are you doing tree canopies also? if so, out of curiosity - what state are you in?

It looks to work well Cary.  I didn't use it this time, because I had a sub-contractor carry out the topo.  I popped back to measure the spreads and added them manually.  Next time I have a job with asymmetric spreads I will hopefully be making use of this.

Thanks P

Glad to hear you can make use of it.
This code could be modified fairly easily to allow you to pick the point (i.e. tree trunk center) on screen from a topo survey vs. Pulling the points form the csv. I have a similar one I use for basic tree symbology.

This is a snippet from my other tool where it gets the point from user input instead of the csv.

Code: [Select]
     (while (and (setq x  (car *lst*))
                  (setq pt (getpoint "\nSpecify Point for Block: ")))
       
(if (vl-catch-all-error-p
              (setq OBJ
                (vl-catch-all-apply (function vla-InsertBlock)
                  (list spc (vlax-3D-point (trans pt 1 0)) bNme 1. 1. 1. *ROT*))))

          (princ "\n** Error Inserting Block **")
Cary Hulse
Urban Forestry Manager
Wetland Studies and Solutions

Civil 3D 2020 & 2023