LISP that converts 3D polyline to solid

LISP that converts 3D polyline to solid

LukasA-HAK
Enthusiast Enthusiast
4,692 Views
48 Replies
Message 1 of 49

LISP that converts 3D polyline to solid

LukasA-HAK
Enthusiast
Enthusiast

Hi,
I am a surveyor at a pipe construction company.
The preliminary design requires data from pipeline traces of other companies that are already in the ground with their pipeline traces
Test trenches must be dug for this purpose.
The engineering firm wants this data to be supplied in autocad solids 3D. With the pipe data in the layer name.
The work process for this is now:
Create layer name. Place circle with diameter pipe on 3D polyline. Apply command sweep along path. Then I still have to move the solid because the top of the pipes have been measured.
This must be done manually for each pipe. Sometimes I'm busy for days.

Isn't there an autocad lisp routine that can automate this work??
It would be nice if this lisp could retrieve the diameter from, say, the layer name.

0 Likes
Accepted solutions (3)
4,693 Views
48 Replies
Replies (48)
Message 2 of 49

ВeekeeCZ
Consultant
Consultant

Seems possible. But post a sample dwg, before and after.

0 Likes
Message 3 of 49

Kent1Cooper
Consultant
Consultant

Something similar to >this<, perhaps?

Kent Cooper, AIA
0 Likes
Message 4 of 49

LukasA-HAK
Enthusiast
Enthusiast

Hello,

Attached are the example files of the test trenches.
With the GPS measurement in the start file. And with the end file the end result.

 

I hope everything is clear for you.

0 Likes
Message 5 of 49

LukasA-HAK
Enthusiast
Enthusiast

Hello thank you , but I am just starting to learn LISP.

Should the code not begin with defun followed with the name of the routine?

0 Likes
Message 6 of 49

ВeekeeCZ
Consultant
Consultant

The start drawing does not include any 3dpolylines. Do you draw them manually (it could be part of the routine), or do you have list of points that are part of one pipeline?

 

0 Likes
Message 7 of 49

LukasA-HAK
Enthusiast
Enthusiast

This is how I receive the data from the GPS device.
I have to draw the 3d polyline manually.

0 Likes
Message 8 of 49

Kent1Cooper
Consultant
Consultant

@LukasA-HAK wrote:

Hello thank you , but I am just starting to learn LISP.

Should the code not begin with defun followed with the name of the routine?


To be defined into a command name, yes -- it's the steps involved to do what they were asking, which can be done independent of "wrapping" them into a command name.  That's easily added, when the steps are determined to be what's wanted.  BUT FIRST:

 

Is your idea that a routine would find all the appropriate pairs to stretch pipes between?  Or would you go around and pick them?  If the routine is supposed to find them, how would it know which ones go together?

 

And what about the objects that do not extend between two Blocks as most do [what I changed to red here, viewing in 3D]?

Kent1Cooper_0-1679666565529.png

What determines their lengths, and the directions they run?

 

You also have some that have a Block at only one end [magenta here]:

Kent1Cooper_1-1679666995182.png

Again, what determines their lengths, and the directions they run?

 

And most are single-run pieces between two Blocks, but then there's at least one multi-segment one [yellow]:

Kent1Cooper_2-1679667186797.png

What determines that situation, rather than [for example] two singles without the middle segment?

 

I don't see anything reliable about Attribute values to distinguish things that are handled differently, but maybe there's something I'm not noticing.

Kent Cooper, AIA
0 Likes
Message 9 of 49

LukasA-HAK
Enthusiast
Enthusiast

I will provide a drawing

0 Likes
Message 10 of 49

LukasA-HAK
Enthusiast
Enthusiast

Yes, it is my idea that the program itself searches for the relevant points in order. I just thought it would be easiest to do this with point numbering. That the program recognizes consecutive points. For example from 110,111,112. And a new series: 120,121,122,123.
It could also be possible by running a 3d polyline over the relevant points. But it is difficult to name the layer name in the field of work.
But if this is difficult to program then the user has to select these points himself

0 Likes
Message 11 of 49

LukasA-HAK
Enthusiast
Enthusiast

It would be a better idea that the program itself finds the relevant points in order. I just thought it would be easiest to do this with point numbering. That the program recognizes consecutive points. For example from 110,111,112. And a new series: 120,121,122,123.
It could also be possible by running a 3d polyline over the relevant points. But it is difficult to name the layer name in the field of work.
But if this is difficult to program then the user has to select these points himself

0 Likes
Message 12 of 49

LukasA-HAK
Enthusiast
Enthusiast

I should explain this.

Sometimes the direction of a cable trace is known because they run parallel to the road. But we don't know where it is. Because it is sometimes difficult to measure multiple points on a pipe or cable, you sometimes only have 1 point. But this can be solved by measuring at least 2 points by using a trick while measuring.

0 Likes
Message 13 of 49

ВeekeeCZ
Consultant
Consultant

I would probably tend to do two routines.

 

The first will draw a 3dpolylines following point numbering and break by (layer/pipe)types.

Then must the user step in and fix it - break it where two different pipes of same type are in sequence.. and other things mentioned by Kent.

 

The second  routine simply converts 3dpylies to solids.

0 Likes
Message 14 of 49

LukasA-HAK
Enthusiast
Enthusiast

I think this is a good idea

0 Likes
Message 15 of 49

LukasA-HAK
Enthusiast
Enthusiast

I have 2 days of now. I may nog be able to reply this weekend. I have two little kids.

But thank you already

0 Likes
Message 16 of 49

Kent1Cooper
Consultant
Consultant

@LukasA-HAK wrote:

.... That the program recognizes consecutive points. For example from 110,111,112. And a new series: 120,121,122,123.....


More criteria would be needed.  You have, for example, an area of Blocks with green Attribute values lb2023-01-09-143 through 154 inclusive.  151 through 154 are a three-segment result [yellow in my previous Reply], but the rest are all one-segment pairs.  How could a routine differentiate?  Why are not 151-152 a pair, and 153-154 another pair?  If there were gaps in the numbers, and only adjacent numbers would be connected, I could kind of imagine a way to do it.

 

The single-run pairs in that area all go from one with a red Attribute value ending in -d50mm to one ending in -d50mmmof, but in the case of the 3-segment one, from -d50mm through -d50mmmf and -d50mmmof and ending on another -d50mm.  What's a routine to think, if -d50mm is the start for most, but both the start and end of this one, and -d50mmmof is the end for most, but an intermediate within this one?

 

And the question remains about lengths and directions of those connected to only one Block, with the additional question of why some have their one Block in the middle of their length, and some at one end.

 

Etc., etc.

Kent Cooper, AIA
0 Likes
Message 17 of 49

ВeekeeCZ
Consultant
Consultant
Accepted solution

The first part. It draws polylines.

 

(vl-load-com)

(defun c:connectpoints ( / *error* lay col doc e l k x y p LM:GetInsideAngle)
  
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (if col (setvar 'cecolor col))
    (if lay (setvar 'clayer lay))
    (setvar 'cmdecho 1)
    (vla-endundomark doc)
    (princ))
  
  (defun LM:GetInsideAngle ( p1 p2 p3 ) ;; Lee Mac
    ((lambda ( a ) (min a (- (+ pi pi) a))) (rem (+ pi pi (- (angle p2 p1) (angle p2 p3))) (+ pi pi))))
  
  
  ;; ---------------------------------------------------------------------------------------------------------------------------------------------
  
  (setq lay (getvar 'clayer)
	col (getvar 'cecolor)
	doc (vla-get-activedocument (vlax-get-acad-object)))
  
  (if (and (setq e (car (entsel "\nSelect point block: ")))
	   (setq l (ssget "_X" (list (assoc 2 (entget e)))))
	   (setq l (vl-remove 'nil (mapcar '(lambda (e / x)
					      (if (and (not (vl-catch-all-error-p (setq x (vl-catch-all-apply 'getpropertyvalue (list e "PT#")))))
						       (not (vl-catch-all-error-p (vl-catch-all-apply 'getpropertyvalue (list e "DESC2"))))
						       (not (vl-catch-all-error-p (vl-catch-all-apply 'getpropertyvalue (list e "Position"))))
						       )
						(list x
						      (atoi (substr x (1+ (strlen (vl-string-right-trim "0123456789" x)))))
						      (getpropertyvalue e "DESC2")
						      (getpropertyvalue e "Position"))))
					   (vl-remove-if 'listp (mapcar 'cadr (ssnamex l))))))
	   (setq l (vl-sort l '(lambda (e1 e2) (< (car e1) (car e2)))))
	   (foreach e l
	     (setq k (if (and (setq p (caar k))
			      (= (1+ (cadr p)) (cadr e))
			      (wcmatch (caddr e) (strcat (caddr (last (car k))) "*"))
			      (or (= 1 (length (car k)))
				  (> (LM:GetInsideAngle (last e) (last p) (last (cadr (car k)))) (/ pi 2.2))))
		       (cons (cons e (car k)) (cdr k))
		       (cons (list e) k))))
	   (not (vla-startundomark doc))
	   (setvar 'cmdecho 0)
	   )
    
    (foreach e k
      
      (setq e (reverse e)
	    y (caddr (car e))
	    p (mapcar 'last e))
      
      (while (vl-string-search " " y) (setq y (vl-string-subst "" " " y)))
      (if (snvalid y 0)
	(progn
	  (or (tblsearch "layer" y) (vla-add (vla-get-layers doc) y))
	  (setvar 'clayer y))
	(setvar 'clayer "0"))
      
      (if (= 1 (length p))
	(progn
	  (setq p (list (car p) (mapcar '+ (car p) '(0.02 0.02 0))))
	  (setvar 'cecolor "4"))
	(setvar 'cecolor "256"))
      
      (command "_.3dpoly")
      (foreach x p (command "_non" x))
      (command "")))
  
  (*error* "end")
  )

 

Message 18 of 49

Sea-Haven
Mentor
Mentor

Being involved in road design yes located lots of stuff under the ground, dug swimming pools on occasion looking for stuff.

 

So you have jumped to step 2 and skipped step 1, if you read your data in correct it could be strung and 3d plines made, this is a std function of a civil package, join points based on a code library.

 

I have spoken about this many times have been doing this since the 80's, John U where are you, it would be better to start by looking at your GPS file. If its straight forward may be able to string all the points.

 

A typical pt file would be ptnum,X,Y,Z,code & description, one of the things you can do is join a "STRING" of common coded points by using a string number 01PIPEGREEN will not join with 02PIPEGREEN. So post a sample gps file.

 

Re 2nd part draw pipe in 3D yes use extrude path, you can draw a circle based on the top quadrant as this must match the actual top of pipe level as this is what is normally measured, if you want real accurate using rotate3d can align at 90 to a sloping 3d pline. 

 

Lastly a concrete 300 dia pipe is not 300 in size its more like 380 as the walls are 40mm thick so that should be taken into account when extruding along path. So need is it plastic concrete steel etc ? We have slid pipes in between services so knowing the last mm was needed. That 80 mm may have been our clearance.

 

One other thing the add on civil packages draw drainage and some may export out 3d tubes. Only thing is they work to invert.

0 Likes
Message 19 of 49

LukasA-HAK
Enthusiast
Enthusiast

I understand the problem now.
But perhaps it is better to look at it from another angle.
How and in what form should I supply a measurement file so that a LISP routine can be written as simply as possible to achieve a good end result?
Or maybe there are already existing routines that I can adapt my work to?
From the software I work with I can export different file formats.
But I would prefer to continue working with autocad blocks.

0 Likes
Message 20 of 49

LukasA-HAK
Enthusiast
Enthusiast

This works great. How did you do this??

0 Likes