Jump to content

Recommended Posts

Posted (edited)

Hi all,

 

This has probably had numerous programs written for it but see the drawing file of what I was hoping to do. Can't for the life of me find one that suits my needs.

 

  • The horizontal line is the section I require.
  • The other lines are 3d Polylines with z values.
  • I was looking for a lisp to do a section through the horizontal line of the crossing 3d polylines.
     

Example.dwg

Edited by 3dwannab
Posted

Sorry, in this case I have one that would work but can't send it out.... I think BIgAl has a link for paid for software - quite cheap by all accounts - that will do this (cheap: cost you less to buy it than develop a LISP I think).

 

Alternatively you could look for 'Long Sections' online, see if there is anything suitable out there?

Posted

Just from curiosity : why do you have contours as 3DPOLY(s), when contours should be LWPOLYLINE(s) at different elevations...

Posted (edited)

Hi Marko. No the road lines, ditches, footpaths and other features are all topo surveyed and they are as 3d polys. The cross-section is to get the profile across a road.

 

I'm working on (trying) to get this done atm.

 

A LWPOLYLINE. Can it have different Z values for its verts? What I'm trying to do is draw a line connecting the apparent intersections and then rotate it on the z-axis to appear correct in the top view.

Edited by 3dwannab
Posted

I told you what contours are - LWPOLYLINE, or SPLINE as isohypses with unique Z elevation... Each one have unique one all the length it spreads along terrain...

Anyway, you could try (ssget "_F") - fence option and collect points of interes after which you just connect them with 3DPOLY command... But what I've found during my testings, fence option may be quirky depending of CAD you are using... BricsCAD was better than AutoCAD IMHO and in my past experiences...

Posted

@3dwannab

What I can offer you...
I tried with your drawing and it seems to work.
Initially my COUPE_TN routine only works with 3Dfaces from a natural terrain mesh.
So I made 3Faces with your 3Dpoly (to see if it worked) with the 3dpolTO3dface routine
I exploded your cut polyline to just get a line
Then routine COUPE_TN is launched, I select your line representing the line of cut.
The profile number is then requested, then the scale of the cut (the default value of 100 is very suitable for your example)
The curvilinear abscissa of the profile is requested.
And there; the TN section is drawn with the dimensions of distance and altitude.
The axis is supposed to be the midpoint of the initially selected line.
These routines are in French but should work anyway.
Is this a good start for you?

3dpolTO3dface.lsp coupe_tn.lsp

  • Like 1
Posted (edited)

Here's what I have so far. Thanks @Tsuky for the programs but I was trying to avoid creating surfaces.

 

Don't mind the points, they're just placeholders for now 😬

 

 

2023.06.23 (23-20-25).gif

Edited by 3dwannab
Posted

The correct answer is get some civil software, like CIV3D or Civil Site Design, others out there, your trying to do civil road design on the cheap.

 

To quote you "features are all topo surveyed" that is it what civil software is designed to do take field data and process it. 

 

To take a field survey from a total station make a strung plan, create a surface, create an alignment and produce cross sections can be as quick as say 10 minutes, plus it makes all the layouts ready for plotting. I had 12 streets in a grid, result 88 sheets. What a nightmare to try and do something from just 3D strings. 

Posted

External company does the topo and hands it off to us. We're mainly an architectural company and dabble in minor upgrades to roads. Add cycle lanes etc. 

Posted (edited)

Thanks for the link @drdownload18 but David's code hung my ACAD.

 

I found a fn to use a trim method and get the apparent intersection that way. The benefit at least for my limited knowledge is that it will work for lines, 2d polylines and 3d polylines too.

 

Here's the GIF and code. Thanks to Kh.mbkh for the trim intersection function which I've shoehorned into this.

 

I sorted the points by x values to draw them correctly. As always, not pretty code but best I can do.

 

 

(vl-load-com)

;; -------------------------=={ Section_Profile }==---------------------------
;; -----------------------------------------------------------------------

;; AUTHOR & ADDITIONAL CODE
;; Author 3dwannab, 2023

;; Thanks to Kh.mbkhs' for the apparent intersection code found at the link below:
;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/projected-intersection-between-a-line-and-3dPolyline/m-p/9435434#M398330

;; ABOUT / NOTES
;; - Takes lines, 2d Poylines and 3d Polylines and allows the user to select a
;;   section line to create a profile in 2d.
;; - This profile will get the Z value of the intersection and create a polyline
;;   profile. And 3d rotate it and move it to where the Z value is now the Y value.
;;   So a point 100,1000,333 will be now 100,333,0.
;; - Points are also created at this location, that match that of the profile
;;   lines. This means they are easily identifiable, should you have them in
;;   layers.

;; FUNCTION SYNTAX
;; Short-cut        SECP
;; Long-cut         Section_Profile

;; VERSION          DATE            INFO
;; Version 1.0      2023.06.25      Initial

;; TO-DO LIST
;; - Try to fix bugs below.

;; BUGS
;; (command "_.matchprop" ...) Outputs to the commandline even though cmdecho is 0.
;; (command "_.rotate3d" ...) Outputs to the commandline even though cmdecho is 0.

;; -----------------------------------------------------------------------
;; -------------------=={ Section_Profile START }==-----------------------

(defun c:SECP () (C:Section_Profile))

(defun C:Section_Profile (/ *error* 3dPolObj acDoc basept idx lastEnt lstPts newPos pfpline proLines ptFinal ptInterSec secLine ssSel var_angbase var_angdir var_cmdecho var_peditaccept)

  (defun *error* (errmsg)
    (and acDoc (vla-EndUndoMark acDoc))
    (and errmsg
         (not (wcmatch (strcase errmsg) "*CANCEL*,*EXIT*"))
         (princ (strcat "\n<< Error: " errmsg " >>\n"))
    )
    (setvar 'cmdecho var_cmdecho)
    (setvar 'peditaccept var_peditaccept)
    (setvar 'angbase var_angbase)
    (setvar 'angdir var_angdir) 
    (princ)
  )

  (setq acDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (or (vla-EndUndoMark acDoc) (vla-StartUndoMark acDoc))

  (setq var_angbase (getvar 'angbase))
  (setq var_angdir (getvar 'angdir))
  (setq var_cmdecho (getvar 'cmdecho))
  (setq var_peditaccept (getvar 'peditaccept))

  (setvar 'angbase 0)
  (setvar 'angdir 0)
  (setvar 'cmdecho 0)
  (setvar 'peditaccept 1)

  if
  (and
    (setq secLine (car (entsel "\nSelect Section Line (Line or Polyline)...")))
    (princ "\nSelect Lines or Polylines (2D or 3D)...")
    (setq proLines (ssget '((0 . "LINE,*POLYLINE"))))
  )

  (progn

    (repeat (setq idx (sslength proLines))
      (setq idx (1- idx)
            ent (ssname proLines idx)
      )

      ;; Code to get the apparent intersection of the section line and profile line
      (setq ptFinal (vlax-curve-getEndPoint secLine)) ; end point of the pline
      (command "_trim" ent "" ptFinal "")

      (setq 3dPolObj (vlax-ename->vla-object ent))
      (setq pfpline (vlax-curve-getEndPoint secLine))
      (setq ptInterSec (vlax-curve-getclosestpointtoprojection 3dPolObj pfpline '(0 0 1)))

      (command "_.point" ptInterSec)
      (command "_.matchprop" "_non" ent "_non" (entlast) "")

      (setq newPos (list (car ptInterSec) (caddr ptInterSec) 0))
      (command "_.move" (entlast) "" "_NONE" ptInterSec "_NONE" newPos)

      (setq lstPts (cons ptInterSec lstPts))
    )
  )

  (if lstPts
    (progn

      ;; Sort the list by the X value. Means the lines are drawn correctly along the X axis
      (setq lstPts (vl-sort lstPts '(lambda (x y) (if (= (car x) (car y)) (< (cadr x) (cadr y)) (< (car x) (car y))))))

      ; Get the last entity created. This helps to get the newly created objects
      (setq lastEnt (entlast))

      ;; Draw the lines
      (if (> (length lstPts) 1)
        (mapcar '(lambda (a b) (entmakex (list '(0 . "line") (cons 10 a) (cons 11 b)))) lstPts (cdr lstPts))
      )

      ;; Select all entities created in function code above
      (setq ssSel (ssadd))
      (while (setq lastEnt (entnext lastEnt))
        (ssadd lastEnt ssSel)
      )

      ;; Rotate the selection so it appears correct in the top view
      (command "_.rotate3d" ssSel "" "_X" (car lstPts) "270")

      ;; Sample of the lstPts variable (For testing)
      ;; (setq lstPts '((-11246.5 34919.5 550.0) (-8782.5 34919.5 150.0) (-6782.5 34919.5 150.0) (-6716.0 34919.5 0.05) (-3716.0 34919.5 100.0) (-716.0 34919.5 0.05) (-649.5 34919.5 150.0) (1350.5 34919.5 150.0) (3814.5 34919.5 550.0)))

      ;; Set basePt and newPos. Sets the new profile from its Z values to according Y values.
      (setq basept (car lstPts))
      (setq newPos (list (car basept) (caddr basept) 0))
      (command "_.move" ssSel "" "_NONE" basept "_NONE" newPos)

      ;; Flatten the new objects for good measure
      (vl-cmdf "move" ssSel "" "0,0,0" "0,0,1e99")
      (vl-cmdf "move" ssSel "" "0,0,0" "0,0,-1e99")

      ;; Join the new profile lines together to create a polyline
      (command "_.pedit" "_M" ssSel "" "_J" "" "")

      ; (command "_.zoom" "_o" (ssget "_L") "") ;; Optional to zoom to created objects

      (sssetfirst nil (ssget "_L"))

      (princ "\nA profile has been created and selected.. Message me if problemo. Signed: 3dwannab.")

      (princ)
    )
  )

  (vla-EndUndoMark acDoc)

  (*error* nil)
) ;; end Section_Profile

(princ "\n: ------------------------------\n\"3dwannab_Section_Profile.lsp\" locked and loaded | Version 1.0 by 3dwannab. Type \"Section_Profile\" OR \"SECP\" to run.\n: ------------------------------\n")
(princ)

;; -----------------------------------------------------------------------
;; ------------------=={ Section_Profile END }==--------------------------
;; EOL

;;(C:Section_Profile) ;; Unblock for testing in VSCode

 

2023.06.25 (22-38-03).gif

Road Profile 3d Polys, 2d Polys And Lines.dwg

Edited by 3dwannab
Added sample drawing
  • Like 1
Posted
 Here's what I have so far. Thanks @Tsuky for the programs but I was trying to avoid creating surfaces.

Hi,
I adapted the previous lisp (trying to translate it as well as possible) to work with curvilinear entities.
The command is CROSS_SECT.
It only accepts a line to define the section (explode if polyline)
As before it will ask you to select the section (as a line, considering that the middle of the line will represent the axis of the section)
Answer the questions
The section will be draw and you will have the choice to accept it or not.
Following this another command called: SELECT_PROFILE is available
It allows to redisplay a defined section and to change scale for the representation if you update the profile.
In addition, you can draw other polylines on this section by forcing the colors to 1 4 5 or 6.
If those are drawn then a new call to SELECT_PROFILE with an update will automatically dimension those polylines into a completed title block.

cross_sect.lsp

  • Like 1
Posted

Cool @Tsuky. Thanks very much. I was wanting to work on this yesterday evening but didn't get a chance. I noticed mine was a little buggy but this is some nice learning material 😄

 

I'll try to get mine working properly in the meantime. Thanks again.

  • 2 weeks later...
Posted
On 6/27/2023 at 12:50 PM, 3dwannab said:

Cool @Tsuky. Thanks very much. I was wanting to work on this yesterday evening but didn't get a chance. I noticed mine was a little buggy but this is some nice learning material 😄

 

I'll try to get mine working properly in the meantime. Thanks again.

Your Lisp will be excellent. Please share it with us once you enhance it. You can add lisp to annotate cross section elevations like this: 

(defun c:ypt ( / i p s )
   (if (setq s (ssget '((0 . "POINT"))))
       (repeat (setq i (sslength s))
           (setq p (assoc 10 (entget (ssname s (setq i (1- i))))))
           (entmake
               (list
                  '(000 . "MTEXT")
                  '(100 . "AcDbEntity")
                  '(100 . "AcDbMText")
                   (cons 1 (strcat (rtos (caddr p))))
                   p
                )
            )
       )
   )
   (princ)
)

 

  • 3 weeks later...
Posted

There's really no need to.

 

This'll do it a lot better than I ever would. Use the Profile 3D Polyline command in CadTools. My script will need to be modified to create a 3d polyline and not rotate it. Then this tool can do what you want.

 

If I ever need this again I will modify my program to create 3d polys and then use this afterwards.

 

The program is defiantly something you should have in your toolbox.

 

https://www.glamsen.se/CadTools.htm

 

 

2023.07.22 (22-44-29).gif

  • Like 1
Posted (edited)

@3dwannab

Hi.

here is a lisp that do the same as Profile 3D Polyline command,

that for me works better...

aridzv.

long_section_3dp.lsp

Edited by aridzv
  • Thanks 1
Posted
13 hours ago, aridzv said:

@3dwannab

Hi.

here is a lisp that do the same as Profile 3D Polyline command

Really needs undo marks given the number of line commands there is.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...