Converting multiple 3D polylines to surfaces

Converting multiple 3D polylines to surfaces

Haider_of_Sweden
Collaborator Collaborator
5,536 Views
21 Replies
Message 1 of 22

Converting multiple 3D polylines to surfaces

Haider_of_Sweden
Collaborator
Collaborator

Hello!

 

I have a large amount of 3d polylines I achieved from a shapefile. Provided, you find a sample of how it could look like.

If I want to turn all polylines to surfaces, a manual workflow would be very tedious.

 

This is how the manual process looks like

 

  • SURFPATCH
  • CU - enter
  • Pick a 3d polyline - enter
  • enter, to accept the patch surface
  • Change the surface U/V isolines to 0

 

The limitation with the current tool is that I cannot select multiple polylines.

Therefore a LISP or equal could run that work-flow mentioned above, individually for every single polyline in a selection.

 

If anyone could help, I would be very grateful.

Thanks in advance!

0 Likes
Accepted solutions (1)
5,537 Views
21 Replies
Replies (21)
Message 2 of 22

DannyNL
Advisor
Advisor

Something like this?

 

I'm not able yet to suppress all output to the textscreen, so you will see a message for each processed polyline. Still working on that, but it should work.

Please be aware that if you select all polylines it will take a very long time before the routine finishes. It's better to select small sets at once, so you can see the result in between and before proceeding to the next one.

 

(defun c:Test (/ varlist oldvars ss obj)
   (setq varlist '("CMDECHO" "NOMUTT"))
   (setq oldvars (mapcar 'getvar varlist))
   (mapcar 'setvar varlist '(0 1))
   (if
      (setq ss (ssget '((0 . "POLYLINE"))))
      (progn
         (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
         (princ (strcat "\nProcessing " (itoa (sslength ss)) " polylines. Please wait...."))
         (foreach item (mapcar 'cadr (ssnamex ss))
            (if
               (= (type item) 'ENAME)
               (progn
                  (vl-cmdf "SURFPATCH" "CU" item "" "")
                  (setq obj (vlax-ename->vla-object (entlast)))                  
                  (vla-put-UIsolineDensity obj 0)
                  (vla-put-VIsolineDensity obj 0)
               )
            )
         )
         (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
      )
   )
   (mapcar 'setvar varlist oldvars)
   (princ)
)
Message 3 of 22

Haider_of_Sweden
Collaborator
Collaborator

Hey Danny!

 

Who cares about the output when it works like a charm?

Could you please add support to regular polylines as well? I have them too in my scene.


Thanks!

 

edit: something happened (not necessarily bad) with the command. When I press the Patch-button or type in the SURFPATCH command, it looks like it has the values preset?

Can you tell me a little more about that?

0 Likes
Message 4 of 22

DannyNL
Advisor
Advisor
Accepted solution

Hi Haider,

 

Support for regular polylines is just one small change from POLYLINE to *POLYLINE.

 

(defun c:Test (/ varlist oldvars ss obj)
   (setq varlist '("CMDECHO" "NOMUTT"))
   (setq oldvars (mapcar 'getvar varlist))
   (mapcar 'setvar varlist '(0 1))
   (if
      (setq ss (ssget '((0 . "*POLYLINE"))))
      (progn
         (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
         (princ (strcat "\nProcessing " (itoa (sslength ss)) " polylines. Please wait...."))
         (foreach item (mapcar 'cadr (ssnamex ss))
            (if
               (= (type item) 'ENAME)
               (progn
                  (vl-cmdf "SURFPATCH" "CU" item "" "")
                  (setq obj (vlax-ename->vla-object (entlast)))                  
                  (vla-put-UIsolineDensity obj 0)
                  (vla-put-VIsolineDensity obj 0)
               )
            )
         )
         (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
      )
   )
   (mapcar 'setvar varlist oldvars)
   (princ)
)

I'm not sure what values from SURFPATCH are preset. Do you mean after you run the routine?

But it's probably some settings that are remembered in system variables after running the command. Can you point out which settings you are referring to? It shouldn't be to difficult to add some code to retain and reset the original values after the routine has finished.

Message 5 of 22

Haider_of_Sweden
Collaborator
Collaborator

This is so relaxing, seeing the whole city getting built up 🙂

 

Out of curiosity, what would I need to type to make this work on Polylines only, not 3D Polylines?

 

As for the SURFPATCH command issue.

Usually, when I run the command, it asks me "Select edges to patch or", then I need to press enter, etc.

It appears that this issue occurs when I cancel the process. My guess is that you altered the variables, and the script had never time to reset to the original value.

You see, I am not complaining, but rather seeing a potential. I believe this might be something I have been looking for quite some time.

Did you somehow alter the variables so that the command behaves in a given way, instead of typing in the options, enter, options and so on?

 

 

Also, is it possible to always override the isoline to 0/0 upon surface creation (in any other context), eg a script that always runs in the background?

0 Likes
Message 6 of 22

DannyNL
Advisor
Advisor

If you only want to process 'normal' polylines, just change the '*POLYLINE" in the SSGET to "LWPOLYLINE".

 

But keeping checking if it builds like you want it to build. I've found that some of the polylines cannot be 'patched' to a surface (you'll notice an error in between al the text output) and this will give you one or more holes in your building(s).

 

I didn't change any variables upfront running the routine nor am I resetting any at the end of it. So I'm thinking SURFPATCH just remembers the last used settings by itself. But as far as I can tell a lot of system variables exist that are related to surfaces. I'm not that familiar with surfaces so not sure which one influences which command.

 

However, to control the number isolines before creating the surface, you can set both SURFU and SURFV to 0.

 

See also this link for other variables regarding isolines. Hope this helps.

 

http://help.autodesk.com/view/ACD/2018/ENU/?query=isolines&contentType=System%20Variable

 

0 Likes
Message 7 of 22

Haider_of_Sweden
Collaborator
Collaborator

@DannyNL wrote:

 

However, to control the number isolines before creating the surface, you can set both SURFU and SURFV to 0.

 

 


Thanks, this actually worked great.

Since this variable is saved in drawings individually, I wonder if there is any "autostart" thing where you can set variables for new drawings or even override for example this variable in opened drawings.

 


@DannyNL wrote:

I didn't change any variables upfront running the routine nor am I resetting any at the end of it. So I'm thinking SURFPATCH just remembers the last used settings by itself. But as far as I can tell a lot of system variables exist that are related to surfaces. I'm not that familiar with surfaces so not sure which one influences which command. 


Back to this matter, let me clarify what I had in mind.

Often in AutoCAD, you have to go through a tree of options until the desired command is been executed, ie you type Y/N or values and so on.

I was thinking of there was a way to create "custom" commands with the help of variables (yes I know, if I am about to create a command, so why not simply preset the Y/N, values and whatsoever) so that I set a bunch of variables, and then the command acts in one certain way. Is that even possible?

I am asking since I thought this was what you did and thought it had potential.

0 Likes
Message 8 of 22

DannyNL
Advisor
Advisor

In the newer AutoCAD version you have the Sytem Variable Monitor which you can use to set a whole bunch of variables to the needed value. If one or more of the variables has or gets another value, the monitor will alert you and you can choose to reset the values to what they need to be.

 

Other options are setting the right values in your template drawings (only useful for new drawings) or create a generic acaddoc.lsp which will reset the defined variables to their needed values each time you open a drawing or creating a custom command that can be invoked by the user/you.

 

In my routine I do set a couple of variables but none that have any influence on the generated surfaces. I'm just suppressing some command output to the textscreen, so you will not see each and every question/setting that has been activated or set.

But it would definitely be possible to create custom commands with setting and restoring the needed variables.

0 Likes
Message 9 of 22

Haider_of_Sweden
Collaborator
Collaborator

@DannyNL wrote:

I'm just suppressing some command output to the textscreen, so you will not see each and every question/setting that has been activated or set.

But it would definitely be possible to create custom commands with setting and restoring the needed variables.


Yes, it is precisely the suppressing thing I am wondering about.

Can you guide me into the right direction to speed up a command like this?

0 Likes
Message 10 of 22

244311
Participant
Participant

ı have same problem. ı have to much 3d polylines. and ı wil create seperate surfaces. how can ı do it?

0 Likes
Message 11 of 22

Sea-Haven
Mentor
Mentor

Simplest way is explode all plines then use the 3d lines to create a TIN surface. This is an option in CIV3D.

 

Likewise there are make TIN lisps. 

0 Likes
Message 12 of 22

Haider_of_Sweden
Collaborator
Collaborator

Did you try the script that DannyNL provided?

If you like, attach a sample file with polylines so you can get better feedback on  your question.

0 Likes
Message 13 of 22

244311
Participant
Participant

lisp bot working. ı get syntax error

0 Likes
Message 14 of 22

Haider_of_Sweden
Collaborator
Collaborator

Attach a sample DWG file and it can get easier to understand the cause of the syntax error.

0 Likes
Message 15 of 22

244311
Participant
Participant

when ı load lisp ı get error. 

0 Likes
Message 16 of 22

Sea-Haven
Mentor
Mentor

This took about 2 minutes have a look at image using CIV3d but other freebies out there.

 

 

0 Likes
Message 17 of 22

244311
Participant
Participant

this is one surface. I want seperate surface for each 3dpoly

0 Likes
Message 18 of 22

Haider_of_Sweden
Collaborator
Collaborator

This is what I did:

  • Drag-drop the lisp-file into Civil 3D (I could not open the file in AutoCAD) > in my case, I named the command "3DPLINE2SURFACE"
  • I selected some of the feature lines and exploded them > they turned into 3D Polylines
  • I selected the 3D Polylines > 3DPLINE2SURFACE (the LISP-command)

 

Surface out of 3D Polylines (ie exploded Feature Lines)Surface out of 3D Polylines (ie exploded Feature Lines)

 

 

0 Likes
Message 19 of 22

Anonymous
Not applicable

Hi Danny,

I need your help, can you write me a lisp code to explode all blocks except border block with name "TitleBorder". After this it will also explode all polylines in the drawing. Thanks in advance.

0 Likes
Message 20 of 22

DANIELE.BUCCOLIERI
Community Visitor
Community Visitor

Great work... 

I have several 3dpoly very near each other (like PV modules). The lisp routine works something weird... It converts exactly half the 3dpoly selected, in a random way. 

Anyone could please help ?

BESTS

 

0 Likes