Jump to content

Pface routine based a Lee Mac Grsnap


halam

Recommended Posts

Based on the Grsnap function * Lee Mac demonstrated i want to create a better way work with the pface command. Captured this idea in a little demo.

 

 

*

http://www.cadtutor.net/forum/showthread.php?100473-draw-multiple-lines-to-a-central-origin-location&p=683177#post683177

 

 

Now,..I was thinking Grnaps and a list of point can be integrated in this code coming from the help / example page of AutoCAD ADN.

 

 

Any thoughts?

 

 

(vl-load-com)
(defun c:Example_AddPolyfaceMesh()
   ;; This example creates a polyface mesh in model space   
   (setq acadObj (vlax-get-acad-object))
   (setq doc (vla-get-ActiveDocument acadObj))
   ;; Define the vertices for the polyface mesh
   (setq vertexList (vlax-make-safearray vlax-vbDouble '(0 . 17)))
   (vlax-safearray-fill vertexList '(4 7 0
                                     5 7 0
                                     6 7 0
                                     4 6 0  ; <== here: Grsnap draw multiple lines to build list of points
                                     5 6 0
                                     6 6 1
                                    )
   )  
   ;; Define the face order for the polyface mesh
   (setq FaceList (vlax-make-safearray vlax-vbInteger '(0 . 7)))
   (vlax-safearray-fill FaceList '(1
                                   2
                                   5
                                   4
                                   2   ;<== n times the point was defined
                                   3
                                   6
                                   5
                                  )
   )
   (setq modelSpace (vla-get-ModelSpace doc))
   (setq obj (vla-AddPolyfaceMesh modelSpace vertexList FaceList))
   ;; Change the viewing direction of the viewport to
   ;; better see the polyface mesh
   (setq NewDirection (vlax-3d-point -1 -1 1))
   (setq activeViewport (vla-get-ActiveViewport doc))
   (vla-put-Direction activeViewport NewDirection)
   (vla-put-ActiveViewport doc activeViewport)
   (vla-ZoomAll acadObj)
)

Link to comment
Share on other sites

halam, do you know that every polygon can be triangulated, without need for picking points - only thing you have to have is correctly ordered point list - or if you have already drawn polygonal LWPOLYLINE you can do it by just picking it... I don't know if this is helpful, but I'd firstly draw PLINE and then apply routine with triangulation and with above posted code example for pface creation...

Link to comment
Share on other sites

I was thinking using pface to AVOID triangulation. Triangulation lines show up unwanted in cases and pface works in 3d. What's the best method to triangulate a 3d closed pline?

Edited by halam
Link to comment
Share on other sites

I thought pface always build triangulated mesh, am I wrong... Your video also shows Lee's function in action, but it also triangulates area...

Link to comment
Share on other sites

No, pface doesn't triangulate as far I can see. The lm function only builds lines.. It is a idea to build a pface alternatively..

Edited by halam
Link to comment
Share on other sites

Hans, what about this ? :

 

(defun C:test ( / pL->PFACE LM:group-n SS i e enx o L eL )
 
 (defun pL->PFACE ( pL / i )
   (setq i 0)
   (apply 'command 
     (append '("_.PFACE") (apply 'append (mapcar (function (lambda (x) (list "_non" x))) pL))
       '("") (mapcar (function (lambda (x) (itoa (setq i (1+ i))))) pL) '("" "")
     )
   )
 )
 
 ;; Group by Number  -  Lee Mac
 ;; Groups a list 'l' into a list of lists, each of length 'n'
 
 (defun LM:group-n ( l n / r )
   (if l (cons (reverse (repeat n (setq r (cons (car l) r) l (cdr l)) r)) (LM:group-n l n) ) )
 )
 
 (cond 
   ( (not (and (princ "\nSelect closed polylines to draw pfaces: ") (setq SS (ssget "_:L-I" '((0 . "*POLYLINE")))))) )
   (
     (progn
       (repeat (setq i (sslength SS))
         (and
           (setq e (ssname SS (setq i (1- i))))
           (setq enx (entget e))
           (setq o (vlax-ename->vla-object e))
           (vlax-curve-isClosed o)
           (vlax-property-available-p o 'Coordinates)
           (setq L (cons (LM:group-n (vlax-get o 'Coordinates) (cond ((member '(0 . "LWPOLYLINE") enx) 2) (T 3)) ) L ))
           (setq eL (cons e eL))
         ); and
       ); repeat
       (not L)
     ); progn
   )
   (T (mapcar 'pL->PFACE L) (mapcar (function (lambda (x) (redraw x 3))) eL)
     (if (progn (initget "Yes No") (= "Yes" (cond ((getkword "\nErase the polylines? [Yes/No] <Yes>: ")) ("Yes"))))
       (mapcar 'entdel eL)
       (vla-Regen (vla-get-ActiveDocument (vlax-get-acad-object)) acActiveViewport)
     ); if
   ); T
 ); cond
 (princ)
); defun

Link to comment
Share on other sites

This is great mr. Grrr.!

Thanks for creating this code.

It will be usefull, at least for me.. ;-)

 

You're welcome! :)

The hard part was to understand how to define the faces list, also I rarely work in 3d so this command is not familiar to me.

 

Its fun trying to code the subfunction and I'm leaving 2 more failed attempts for anyone interested:

 

Using Activex:

; (pL->PFACE (vla-get-Block (vla-get-ActiveLayout (vla-get-ActiveDocument (vlax-get-acad-object)))) pL)
(defun pL->PFACE ( spc pL / i->L vL fL )
 
 ; _$ (i->L 10) -> (0 1 2 3 4 5 6 7 8 9)
 (defun i->L ( i / L ) (repeat i (setq L (cons (setq i (1- i)) L)) ) )
 
 (if (= 2 (length (car pL))) (setq pL (mapcar (function (lambda (x) (append x '(0.)))) pL))) ; 2d pL to 3d pL
 (cond
   ( (vl-every (function (lambda (x) (and (vl-consp x) (= 3 (length x))))) pL)
     (vlax-safearray-fill ; vertices list
       (setq vL (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length (apply 'append pL))))))
       (apply 'append pL)
     ); vlax-safearray-fill
     (vlax-safearray-fill ; faces list
       (setq fL (vlax-make-safearray vlax-vbInteger (cons 0 (1- (length pL)))))
       (mapcar '1+ (i->L (length pL)))
     ); vlax-safearray-fill
     (vl-catch-all-apply 'vla-AddPolyfaceMesh (list spc vL fL)) ; I'm not sure why it errors on some lwpolylines
   )
 ); cond
); defun pL->PFACE

 

Using Vanilla:

; (pL->PFACE (car (entsel)))
(defun pL->PFACE ( e / collectVertices pL ) ; Not working 
 
 (defun collectVertices ( e / enx L )
   (or 
     (if (= 1 (length (setq L (apply 'append (mapcar (function (lambda (x) (if (= 10 (car x)) (list (cdr x))))) (entget e))))))
       (setq L nil)
     ); if
     (progn ; (setq e (entnext e))
       (while (and (setq e (entnext e)) (setq enx (entget e)) (= (cdr (assoc 0 enx)) "VERTEX")) (setq L (cons (cdr (assoc 10 enx)) L)) )
       L
     ); progn
   ); or 
   L
 ); defun collectVertices
 
 (setq pL (collectVertices e))
 (if (= 2 (length (car pL))) (setq pL (mapcar (function (lambda (x) (append x '(0.)))) pL))) ; 2d pL to 3d pL
 
 (cond
   (pL
     (entmakex
       (list
         '(0 . "POLYLINE") '(100 . "AcDbEntity") '(67 . 0) '(410 . "Model") '(100 . "AcDbPolyFaceMesh") '(66 . 1)
         '(10 0.0 0.0 0.0) '(70 . 64) '(40 . 0.0) '(41 . 0.0) '(210 0.0 0.0 1.0)
         (cons 71 (length pL))  ;; 71 Polygon mesh M vertex count (optional; default = 0)
         (cons 72 (length pL))  ;; 72 Polygon mesh N vertex count (optional; default = 0)
         '(73 . 0)              ;; 73 Smooth surface M density (optional; default = 0)
         '(74 . 0)              ;; 74 Smooth surface N density (optional; default = 0)
         '(75 . 0)              ;; 75 Curves and smooth surface type (optional; default = 0); integer codes, not bit-coded:
                                ;; 0 = No smooth surface fitted
                                ;; 5 = Quadratic B-spline surface
                                ;; 6 = Cubic B-spline surface
                                ;; 8 = Bezier surface  
       ); list
     ); entmakex
     (mapcar 
       (function 
         (lambda (x) 
           (entmakex 
             (append
               '((0 . "VERTEX") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (100 . "AcDbVertex") (100 . "AcDbPolyFaceMeshVertex"))
               (list (cons 10 x))
               '((40 . 0.0) (41 . 0.0) (42 . 0.0) (70 . 192) (50 . 0.0) (71 . 0) (72 . 0) (73 . 0) (74 . 0))
             ); append
           ); entmakex 
         ); lambda
       ); function
       pL
     ); mapcar
     (entmakex '((0 . "SEQEND") (100 . "AcDbEntity") (67 . 0) (410 . "Model")))
   ); pL
 ); cond 
); defun pL->PFACE

Link to comment
Share on other sites

  • 2 years later...

This is an old discussion but i still use pface in some cases.

The pface  command is fooling around with me.

In many cases one corner is ok, but the next is worthless.

Any advice here? Is it a mathmatical bug or shortcomming in the AutoCAD polyface command?

 

Can anyone using BricsCAD test tif the outcome is the same?

 

https://drive.google.com/file/d/1a7Zc6xMIWZeQ1HMcWXH2_rNARda0r1Vy/view?usp=sharing

 

Thanks

 

Knipsel.JPG

Edited by halam
Link to comment
Share on other sites

That is 3DPOLYLINE and is not planar, so converting to LWPOLYLINE is not directly possible... Try to split that 3DPOLY on smaller planar LWPOLYLINES and then just apply REGION command on them finally... Result should be close to what you wanted with Polyface Mesh...

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