Jump to content

tube bending lisp or??


Jack_O'neill

Recommended Posts

Updated version (below and attached). This version will miter corners without a bend. If the CSV contains no bend radius information the user is now prompted for a radius. Code tested on BricsCAD V18.

(vl-load-com)

(defun KGA_Conv_EnameList_To_Pickset (lst / ret)
  (setq ret (ssadd))
  (foreach enm lst (if (not (vlax-erased-p enm)) (ssadd enm ret)))
  (if (/= 0 (sslength ret)) ret)
)

(defun KGA_Conv_Pickset_To_EnameList (ss / i ret)
  (if ss
    (repeat (setq i (sslength ss))
      (setq ret (cons (ssname ss (setq i (1- i))) ret))
    )
  )
)

(defun KGA_Data_FileRead (fnm / lst ptr str)
  (if (setq ptr (open fnm "r"))
    (progn
      (while (setq str (read-line ptr))
        (setq lst (cons str lst))
      )
      (close ptr)
      (reverse lst)
    )
  )
)

; Every record in the CSV has to have 3 or 4 numerical fields: X,Y,Z[,Radius].
(defun CsvToSweep_ReadCsv (fnm)
  (mapcar
    '(lambda (str / lst)
      (setq lst (read (strcat "(" (vl-string-translate "," " " str) ")")))
      (cond
        ((not (vl-every 'numberp lst))
          nil
        )
        ((= 4 (length lst))
          (list (list (car lst) (cadr lst) (caddr lst)) (cadddr lst))
        )
        ((= 3 (length lst))
          (list lst)
        )
      )
    )
    (KGA_Data_FileRead fnm)
  )
)

; Return value: List of lines, (3D) polylines and arcs as enames. The enames are in a random order.
(defun CsvToSweep_CreatePath (spc datLst userRad / linLst lst oldClayer oldFilletrad tmpLyr tmpLyrNme)
  ;; Create a temp layer for the path entities:
  (while (tblsearch "layer" (setq tmpLyrNme (strcat "CsvToSweep_" (rtos (getvar 'cdate) 2 8))))
  )
  (setq tmpLyr (vla-add (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) tmpLyrNme))
  (setq oldClayer (getvar 'clayer))
  (setvar 'clayer tmpLyrNme)
  ;; Create the lines:
  (setq linLst
    (mapcar
      '(lambda (subA subB)
        (vlax-vla-object->ename
          (vla-addline spc (vlax-3d-point (car subA)) (vlax-3d-point (car subB)))
        )
      )
      datLst
      (cdr datLst)
    )
  )
  ;; Create the arcs:
  (setq oldFilletrad (getvar 'filletrad))
  (mapcar
    '(lambda (linA linB datRad / enm)
      (setvar 'filletrad (cond (datRad) (userRad) (0.0)))
      (command "_.fillet" linA linB)
    )
    linLst
    (cdr linLst)
    (mapcar 'cadr (cdr datLst))
  )
  (setvar 'filletrad oldFilletrad)
  ;; Try to join the lines:
  (princ "\nTrying to join the lines in the path (will fail at bends): ")
  (command "_.join" (KGA_Conv_EnameList_To_Pickset linLst) "")
  ;; Cleanup and return value:
  (setq lst (KGA_Conv_Pickset_To_EnameList (ssget "_X" (list (cons 8 tmpLyrNme)))))
  (mapcar
    '(lambda (enm) (vla-put-layer (vlax-ename->vla-object enm) oldClayer))
    lst
  )
  (setvar 'clayer oldClayer)
  (vla-delete tmpLyr)
  lst
)

(defun CsvToSweep_CreateSolid (spc pathLst rad / lst oldDelobj prof)
  (setq prof (vlax-vla-object->ename (vla-addcircle spc (vlax-3d-point 0.0 0.0 0.0) rad)))
  (setq oldDelobj (getvar 'delobj))
  (setvar 'delobj 0)
  (setq lst
    (vl-remove
      nil
      (mapcar
        '(lambda (path / enm)
          (setq enm (entlast))
          (command "_.sweep" prof "" path)
          (if (not (equal enm (entlast)))
            (entlast)
          )
        )
        pathLst
      )
    )
  )
  (setvar 'delobj oldDelobj)
  (entdel prof)
  (if (< 1 (length lst))
    (command "_.union" (KGA_Conv_EnameList_To_Pickset lst) "")
  )
  (vl-remove-if 'vlax-erased-p lst)
)

(defun c:CsvToSweep ( / bendRad datLst profDiam doc fnm pathLst spc)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (vla-endundomark doc)
  (vla-startundomark doc)
  (setvar 'cmdecho 0)
  (if
    (and
      (setq fnm (getfiled "Select CSV file" "" "csv" 4))
      (setq datLst (CsvToSweep_ReadCsv fnm))
      (or
        (not (vl-position nil datLst))
        (prompt "\nError: invalid data ")
      )
      (or
        (not (vl-every '(lambda (sub) (= 1 (length sub))) datLst))
        (setq bendRad (getdist "\nBend radius: "))
      )
      (setq profDiam (getdist "\nProfile diameter: "))
    )
    (progn
      (setq spc ((if (= 1 (getvar 'cvport)) vla-get-paperspace vla-get-modelspace) doc))
      (setq pathLst (CsvToSweep_CreatePath spc datLst bendRad))
      (if (= 1 (length (CsvToSweep_CreateSolid spc pathLst (/ profDiam 2.0))))
        (princ "\nSweep successfully created ")
        (princ "\nAn unxpected error occured ")
      )
      (mapcar 'entdel pathLst)
    )
  )
  (setvar 'cmdecho 1)
  (vla-endundomark doc)
  (princ)
)

 

 

 

CsvToSweep_20200104.zip

Edited by Roy_043
Added: (vl-load-com).
  • Like 1
Link to comment
Share on other sites

It may just be something I'm doing wrong, but when I run this the following error pops up:

 

Command: CSVTOSWEEP
; error: bad function: #<SUBR @000001eada6cade0 -lambda->

 

 

I had it load the application, and when it asks for the csv to load i picked one of the ones you sent Roy.   In fact I tried all three, and one of my own and this is what happens immediately after picking the file.  I have no idea what this means.  Its been 20 years since I wrote a line of lisp.

 

I'm running Autocad 2020 on Windows 10 pro.

Link to comment
Share on other sites

I forgot to quote a lambda on line 32 of the Lisp file (BricsCAD does not stumble over this). I have updated my previous post. Please download again.

Link to comment
Share on other sites

Thanks Roy!

 

I used to could find my way through stuff like this, but it has been so long.  Like I said earlier, it's been 20 years since I tried to write anything new in lisp.  When I first started at this job, I dug out some of my old stuff and discovered it didn't work anymore and found myself at a loss as to how to fix it.   Thats to be expected I guess when you step away for a good number of years.  At any rate...thanks for  your help.  I'll try it out in a bit.

Link to comment
Share on other sites

it WORKS!  it works perfectly.  That will save so much time.    Thanks Roy and everyone else who contributed!!

Edited by Jack_O'neill
Link to comment
Share on other sites

@BIGAL

$0.02 not sure Bricscad 

 

command: sweep

(vla-AddExtrudedSolidAlongPath mspace region path) 

 

command: union

(vla-boolean 0 solid)

;0= AcUnion

;1= AcIntersection

;2= acSubtraction

 

 

Link to comment
Share on other sites

BricsCAD has these functions. But not using command calls would require a lot more code and be more challenging. But if you feel up to creating such a version: just go for it!

Edited by Roy_043
  • Like 1
Link to comment
Share on other sites

  • 2 months later...

Howdy folks....I'm back.   

 

Anybody up for a challenge?   Remember the code Roy_043 built for me in this thread?  It works perfectly and I use it all the time.  But now, I have a need for a lisp that does just the opposite.  I have a customer sending me solid models, with no dimensions.  What I need to do now is take that model, draw a lines from the end of the tube down the center to the tangent of the bend, then tangent to tangent for however many and then stop at the opposite end of the tube.  Then I need to zero fillet all those line segments, and create the bend data table as it appears earlier in this thread. 

 

Is that a doable thing?  I suppose it would be necessary to move the center of one end of the tube to 0,0,0 and orient at least the first bend to the ucs...that's no problem.  I can do that.

 

I'd be willing to trade some drafting as payment if needed.  I have Autocad 2020 and am pretty good with mechanical drawing, not too bad on architectural stuff but don't know the first thing about civil. Would be happy to do an equitable amount of redline markups or whatever you needed.

 

Thanks!

Link to comment
Share on other sites

Sorry guys...been up to my ears in alligators all day.  I'll get a drawing uploaded here in a few minutes

 

Link to comment
Share on other sites

For such a 3DSOLID, I guess it would be very difficult if even possible. What I mean is that while working, avoid creating 3DSOLIDS TUBES that don't belong to SWEEPS - it seems that you lost important info ab path... Even with path, tubes are very difficult and IMHO, path can be only approximation especially if curve is spline like... I see that you are working with only tubes, so I can't be of much help, but if your cross section curve has a vertex (not circle), and you created SWEEP, you can try trick like this :

Copy sweep on other place, then stretch vertex of shape to centroid - should be like grip at start of sweep... Then your isolines of 3DSOLID will follow path...

Then only way I see is to manually SOLIDEDIT and copy edges of solid that are following path...

Finally - also manually you join copied edges to single curve - path with JOIN command...

Then you copybase path with 0,0,0... Do UNDO until original cross section shape... pasteclip to 0,0,0 and finally you copy path from vertex point of copy of 3DSOLID - SWEEP to original 3DSOLID...

With TUBES it's different - you don't have that vertex on cross section shape - so my intention was - extract isolines - leave only cross sections (circles) - then you connect centers of circles - if it's spline like path that's a problem - you have to have many circles... Routine could be made for connecting regions centroids obtained from circles that are next to each other... Finally you join lines to 3DPOLY with JOIN and then also you can convert 3DPOLY to SPLINE if necessary...

For extracting isolines from 3DSOLIDS or SURFACES, look into topic by Kean Walmsley - with the same problem at through-the-interface-typepad.com

Edited by marko_ribar
Link to comment
Share on other sites

1 hour ago, marko_ribar said:

For such a 3DSOLID, I guess it would be very difficult if even possible. What I mean is that while working, avoid creating 3DSOLIDS TUBES that don't belong to SWEEPS - it seems that you lost important info ab path... Even with path, tubes are very difficult and IMHO, path can be only approximation especially if curve is spline like... I see that you are working with only tubes, so I can't be of much help, but if your cross section curve has a vertex (not circle), and you created SWEEP, you can try trick like this :

Copy sweep on other place, then stretch vertex of shape to centroid - should be like grip at start of sweep... Then your isolines of 3DSOLID will follow path...

Then only way I see is to manually SOLIDEDIT and copy edges of solid that are following path...

Finally - also manually you join copied edges to single curve - path with JOIN command...

Then you copybase path with 0,0,0... Do UNDO until original cross section shape... pasteclip to 0,0,0 and finally you copy path from vertex point of copy of 3DSOLID - SWEEP to original 3DSOLID...

With TUBES it's different - you don't have that vertex on cross section shape - so my intention was - extract isolines - leave only cross sections (circles) - then you connect centers of circles - if it's spline like path that's a problem - you have to have many circles... Routine could be made for connecting regions centroids obtained from circles that are next to each other... Finally you join lines to 3DPOLY with JOIN and then also you can convert 3DPOLY to SPLINE if necessary...

For extracting isolines from 3DSOLIDS or SURFACES, look into topic by Kean Walmsley - with the same problem at through-the-interface-typepad.com

Well, you see, that's the problem.  I didn't create the solids, my customer did.  On top of that he uses Catia and exports them as a ".prt " file, which i import into Fusion to convert to an iges file, then into autocad to make a dwg (because trying to use Fusion for much else makes me want to run blindfolded into the traffic).   This sounds like a joke, but sadly it's not.   I can and have been doing this manually, so it's no big deal.  Later tonight I'll post some drawings of the process I'm going through to make it easier to understand.   May still not be possible, but I appreciate everyone's help and input.

 

And they are not really tubes, just solids.  They are not hollow, and for what we are doing they don't have to be. I dont know how Catia creates these things.  In autocad, i would sweep a circle along a path and retain the path.   They don't do that.   I get what you see in the drawing.

 

 

Edited by Jack_O'neill
Link to comment
Share on other sites

If you explode the solid you get 2 regions (1 for each end cap) and several surfaces. Exploding these entities one by on gives you 1 or, for the surfaces, 2 circles. If the 2 circles derived from a surface have the same normal, we can probably (in this context at least) assume the surface was cylindrical and use their centers to draw a center line... Etc.

It seems to me that creating Lisp code for this is doable.

 

But creating the center lines manually should also be relatively easy: Osnap center, draw lines, fillet...

 

Note 1: I am using BricsCAD.

Note 2: I am not going to write the Lisp code.

Link to comment
Share on other sites

10 hours ago, Roy_043 said:

If you explode the solid you get 2 regions (1 for each end cap) and several surfaces. Exploding these entities one by on gives you 1 or, for the surfaces, 2 circles. If the 2 circles derived from a surface have the same normal, we can probably (in this context at least) assume the surface was cylindrical and use their centers to draw a center line... Etc.

It seems to me that creating Lisp code for this is doable.

 

But creating the center lines manually should also be relatively easy: Osnap center, draw lines, fillet...

 

Note 1: I am using BricsCAD.

Note 2: I am not going to write the Lisp code.

 

As I said, I do it manually now.   I simply switch the shading to wire frame.  It shows a circle at the end of each straight, i draw a line from circle to circle at each straight, then zero fillet them to get the intersection points.  No biggie, but if we win this package there will be hundreds of them to do.

 

I appreciate everything everyone has offered on this. 

 

Note 1:  I wasn't looking for a freebee, I asked if it was possible.

Note 2: I offered to trade drafting work for any effort anyone put in.  If someone don't want to do that...that's fine, all ya gotta do is say so. Or for that matter, say nothing.  It's all good.

 

See you guys later.   Gotta get back to drawing stuff.

Link to comment
Share on other sites

No idea need your dwg, Made this but ended up exploding a few times could look at circle angle and then next if same a straight if not a radius but then my brain started to hurt.

 

image.thumb.png.ee15073f2866c8b6b84a4785659cac6d.png

Link to comment
Share on other sites

Here is how I reconstructed tube path... Segmentation per segment is 64 vertices...

But unfortunately I can't post my used routines and beside that one is dll (extracting isolines)...

Of course, you can convert 3dpoly to 3dspline if you want, that's not such a big deal...

P.S. If you have 3DSPLINED TUBE, I can try my method on them as well...

Regards...

test-tubes.dwg

Edited by marko_ribar
Link to comment
Share on other sites

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...