### Author Topic: Triangulation (re-visited)  (Read 329227 times)

0 Members and 2 Guests are viewing this topic.

#### squirreldip

• Newt
• Posts: 114
##### Re: Triangulation (re-visited)
« Reply #615 on: April 28, 2016, 01:49:31 PM »
Okay, found the issue...  The list has to be sorted prior to removing duplicates (guess I shouldn't skim so much when reading notes...)

Also, Made TIN:SORTXY a global function

Here's the update:

Edit - Latest here:
https://www.theswamp.org/index.php?topic=9042.msg564613#msg564613
« Last Edit: April 29, 2016, 01:34:55 PM by squirreldip »

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #616 on: April 29, 2016, 07:58:04 AM »
squirreldip,

Using FUZZ 0.001 for REMDUPPOINT is too small with TIN:SECTIONPOINTTOPOINT.

If P1 and P2 have elevations, then the REMDUPPOINT doesn't work on the initial point in the list...

Typical set with P1 & P2 @ elevations
(chose points by snapping to TIN)
(
(0.0 655.039)
(0.0 655.039)
(5.86765 653.97)
(7.69841 653.776)
(11.0488 653.818)
)

(another by snapping to TIN)
(
(0.0 654.68)
(1.81899e-012 654.68)
(1.19423 654.517)
(11.2871 653.697)
(12.5041 653.709)
)

(another by snapping to TIN)
(
(0.0 652.71)
(2.03369e-012 652.71)
(7.47364 652.762)
(24.7252 652.254)
(30.5482 652.05)
)

Typical set with P1 & P2 without elevations
(chose points in open space beyond TIN)
One byproduct is to not have a 0.0 point
(
(25.929 652.712)
(33.341 652.814)
(46.9912 652.499)
)

The "No Elevation" would always produce a similar list... as did the "With Elevation."

This is probably an issue that has always existed with REMDUPPOINT, but the larger FUZZ value had eliminated it.

Rick
« Last Edit: April 29, 2016, 08:02:10 AM by rw2691 »
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #617 on: April 29, 2016, 11:27:16 AM »
YMG,

I found this code at www.augi.com. It deletes entities outside a closed polyline, and trims objects that cross the polyline. I thought it could be tweaked and used for the Boundary routine.

Code: [Select]
`; Required Express tools; OutSide Contour Delete with Extrim; Found at http://forums.augi.com/showthread.php?t=55056(defun C:OCD (  / en ss lst ssall bbox)(vl-load-com)  (if (and (setq en (car(entsel "\nSelect contour (polyline): ")))           (wcmatch (cdr(assoc 0 (entget en))) "*POLYLINE"))    (progn      (setq bbox (ACET-ENT-GEOMEXTENTS en))      (setq bbox (mapcar '(lambda(x)(trans x 0 1)) bbox))      (setq lst (ACET-GEOM-OBJECT-POINT-LIST en 1e-3))      (ACET-SS-ZOOM-EXTENTS (ACET-LIST-TO-SS (list en)))      (command "_.Zoom" "0.95x")      (if (null etrim)(load "extrim.lsp"))      (etrim en (polar                  (car bbox)                  (angle (car bbox)(cadr bbox))                  (* (distance (car bbox)(cadr bbox)) 1.1)))      (if (and            (setq ss (ssget "_CP" lst))            (setq ssall (ssget "_X" (list (assoc 410 (entget en)))))           )        (progn          (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))          (foreach e1 lst (ssdel e1 ssall))          (ACET-SS-ENTDEL ssall)          )        )      )    )  )(princ "\nType OCD to start")(princ)`
Rick
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### squirreldip

• Newt
• Posts: 114
##### Re: Triangulation (re-visited)
« Reply #618 on: April 29, 2016, 01:33:18 PM »
YMG, Rick:

I think I may have found a bug in remduppoint...

Shouldn't the line:
Code: [Select]
`(if (> (distance (butlast p) (cadr l)) fuzz)`
Actually be:
Code: [Select]
`(if (> (distance (butlast p) (butlast (cadr l))) fuzz)`
If p is a 3D point then (butlast p) is a 2D...  (cadr l) is a 3D point so shouldn't it need to be converted to 2D?

Code seems to work with this change:

Edit - Latest here:
https://www.theswamp.org/index.php?topic=9042.msg564730#msg564730
« Last Edit: May 02, 2016, 01:02:41 PM by squirreldip »

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #619 on: April 29, 2016, 01:58:43 PM »
YMG,

As to the Boundary filtering, I have modified the code I presented and it has worked to perfection. I removed all the EXTRIM code, and changed the SS selections to _WP and _X.

Code: [Select]
`; Required Express tools; OutSide Contour Delete with Extrim; Found at http://forums.augi.com/showthread.php?t=55056(defun C:OCD (  / en ss lst ssall bbox)(vl-load-com)  (if (and (setq en (car(entsel "\nSelect contour (polyline): ")))           (wcmatch (cdr(assoc 0 (entget en))) "*POLYLINE"))    (progn      ;; *** commented out ***      ;;(setq bbox (ACET-ENT-GEOMEXTENTS en))      ;;(setq bbox (mapcar '(lambda(x)(trans x 0 1)) bbox))            (setq lst (ACET-GEOM-OBJECT-POINT-LIST en 1e-3))      (ACET-SS-ZOOM-EXTENTS (ACET-LIST-TO-SS (list en)))      (command "_.Zoom" "0.95x")            ;; *** commented out ***      ; (if (null etrim)(load "extrim.lsp"))      ; (etrim en (polar                  ; (car bbox)                  ; (angle (car bbox)(cadr bbox))                  ; (* (distance (car bbox)(cadr bbox)) 1.1))                  ; )       ;; changed selections to _WP and _X,  and added 3DFACE filtering                 (if (and                (setq ss (ssget "_WP" lst '((0 . "3DFACE")))) ;; select TINs inside polygon            (setq ssall (ssget "_X" (list (cons 0 "3DFACE")))) ;; select all TINs in drawing           )        (progn          (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))          (foreach e1 lst (ssdel e1 ssall))          (ACET-SS-ENTDEL ssall)          )        ) ; end if      ) ; end progn    )  )`
Afterward however, I had to modify the Boundary Polyline to a 2d Polyline. Then I used the OFFSET function to expand the Poly by 0.01 feet. When I activated OCD it cleaned out all 3dFaces that were outside my selected area... with no fault.

I imagine that the manual parts can be automated by creating a copied Polyline, as a new entity, and reducing it to a 2dPoly. Then its first point can be used to inverse to the second and last points.

Since the Boundary was created in a clockwise direction, those angles (added by right-perpendicular to the first, and left-perpendicular to the second) can be averaged, then their result may be reversed to create a selection point that is outside the Boundary. I don't remember if LISP will allow this, but the averaged angle could be used "as-is" with the distance being negative (-0.01).

Then use the OFFSET function, give it the 2dPoly and the point that was created. Then the 2dPoly can be erased and the OFFSET poly can be selected for the OCD routine.

Lastly, the OFFSET poly can be erased... the original Boundary line is still intact.

This method works better than selecting by FENCE, because it deletes the detached external 3dFaces as well as the Fenced.

Rick
« Last Edit: April 29, 2016, 04:35:22 PM by rw2691 »
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #620 on: April 29, 2016, 02:23:34 PM »
squirreldip,

I made your change and did not get your results... first and second with elevation snapped are duplications.

(
(0.0 654.65)
(9.09495e-013 654.65)
(9.58188 654.45)
(20.1528 654.003)
(23.2885 653.668)
)

I don't think you need to do your change. When using the DISTANCE function it defaults to the lowest denominator, which is a 2d solution because only one element is 2d. Both have to be 3d to get sloped distances.

Rick
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #621 on: April 29, 2016, 03:48:52 PM »
YMG,

This doesn't appear to be reliable in my opinion, but there is a "human nature" method for determining the outside of a closed polyline...

I read this from a book, Autocad Developer's  Guide to Visual LISP: When using the EntSel function a person normally selects the object by its outside position... due to the box-aperture by the mouse. So you might assume its click point as outside, and in particular if its elevation is 0.0.

For instance (setq es1 (entsel "Select object: ")) returns (Entity name: 14a9960>(301.791 138.438 0.0))

The name can be retrieved from the list with the CAR function, and its coordinates provide your outside element.

Just the same it can be resolved by asking the user to select the Boundary line, and then again, select a position outside the Boundary.

Rick
« Last Edit: April 29, 2016, 03:52:41 PM by rw2691 »
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### ymg

• Guest
##### Re: Triangulation (re-visited)
« Reply #622 on: April 30, 2016, 04:01:18 AM »
Squirreldip,

Quote
(distance '(10 10) '(10 15 100)) -->  5.0
(distance '(10 10 100) '(10 15)) --> 5.0

So 2d point with 3d point results with plane distance.

As for the discussion on fuzz,  We are talking about topographic survey
accuracy is on the order of centimeters not millimeters.

The fact that modern instruments returns a resolution of mm does
not make it accurate to mm.  Resolution and accuracy are two different thing.

For the vertical wall workaround offsetting 4 mm will hardly make a difference.

But it is a workaround.  Should you be taking point from a cliff, the point on the
face would not be ok.  You have to treat them separately on a different UCS

ymg
« Last Edit: April 30, 2016, 04:18:50 AM by ymg »

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #623 on: April 30, 2016, 09:59:14 AM »
YMG,

I have worked out the Boundary and extraneous TIN's code...

After the (setq *bounden* (entlast)) code line within C:BOUND function, paste the following patch...

Code: [Select]
`              (mk_3dp plst)                            (setq *bounden* (entlast));;==========start patch                            ;; *bounden* (3dPloyline) is used as a TIN limit and a BREAKLINE              ;; *limiten* (2dPloyline) is created to facilitate deletion of extraneous TIN's              ;; *limiten* is built at an outside offset of 0.0003 to *bounden*              (mk_lwp plst)  ;(mk_2dp plst)              (setq tmpen (entlast))              (setq tmppt (list (- 0 99999999) (- 0 99999999) 0)) ;; a negative 100 million feet away              (command "_offset" 0.0003 tmpen tmppt "") ; 0.0003                           (setq *limiten* (entlast))                           (entdel tmpen);;==========close patch                              (redraw)              )`
Within the C:TIN function you replace the Boundary Deletion code with a call to OCD as follows, (AUGI:OCD *limiten*).

AUGI:OCD (now modified) is defined as follows...

Code: [Select]
`; Required Express tools; OutSide Contour Delete; Found at http://forums.augi.com/showthread.php?t=55056; modified by RW2691 (aka. Rick)(defun AUGI:OCD (TIN-LIMIT / ss lst ssall e1 lst)(vl-load-com)  (if TIN-LIMIT    (progn      (setq lst (ACET-GEOM-OBJECT-POINT-LIST TIN-LIMIT 1e-3))      (ACET-SS-ZOOM-EXTENTS (ACET-LIST-TO-SS (list TIN-LIMIT)))      (command "_.Zoom" "0.95x")                       (if (and            (setq ss (ssget "_WP" lst '((0 . "3DFACE")))) ;; select TINs inside polygon            (setq ssall (ssget "_X" (list (cons 0 "3DFACE")))) ;; select all TINs in drawing           )        (progn          (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))          (foreach e1 lst (ssdel e1 ssall))          (ACET-SS-ENTDEL ssall)          )        ) ; end if      ) ; end progn    )  )`
I have tested this arrangement by using the BOUND function, then moving the BOUNDEN and LIMITEN lines away from the Topo area, and building a TIN network (without them) with extraneous TIN's. Then I moved the BOUNDEN and LIMITEN lines back to their proper place, and made the following call from the keyboard commandline... (AUGI:OCD *limiten*). It worked without any fault.

Unfortunately, at this point, I do not know what sections within the C:TIN code should be replaced by the (AUGI:OCD *limiten*) call. I am also debating whether the LIMITEN line should then be deleted as well.

Perhaps you can help me with that?

Rick
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### ymg

• Guest
##### Re: Triangulation (re-visited)
« Reply #624 on: April 30, 2016, 03:31:36 PM »
Rick,

I had OCD in the code in prior version but never used it.

Right now, I am processing the outside boundary as well as
the holes with the following code:

Code - Auto/Visual Lisp: [Select]
1.  ;;                                                             ;
2.                ;; Erasing Triangles in Holes of Triangulation, and those      ;
3.                ;; Outside of the boundary. Adjusting Triangle List.           ;
4.                ;;                                                             ;
5.                ;; Notes: This is a fast hack where we select 3Dfaces with a   ;
6.                ;;        Crossing Polygon then Computes their Centroid and    ;
7.                ;;        remove those whose centroid is inside the poly.      ;
8.                ;;                                                             ;
9.                ;;        Will change it eventually to offset the polyline     ;
10.                ;;        to the outside by a few millimeters, and make the    ;
11.                ;;        Selection by Window Polygon.                         ;
12.                ;;                                                             ;
13.                ;; Modified to handle external boundary   November 2015        ;
14.                ;;                                                             ;
15.
16.                (vl-cmdf "_ZOOM" "_E")
17.                (if *bounden*
18.                   (setq bp (distinct (mapcar '(lambda (a) (list (car a) (cadr a))) (listpol *bounden*))))
19.                )
20.                (foreach wp wpl
21.                   (setq  ss (ssget "_CP" wp '((0 . "3DFACE"))))
22.                   (repeat (setq i (sslength ss))
23.                      (setq  en (ssname ss (setq i (1- i)))
24.                            ent (entget en)
25.                             tp (list (cdr (assoc 11 ent))
26.                                      (cdr (assoc 12 ent))
27.                                      (cdr (assoc 13 ent))
28.                                )
29.                             ct (centroid tp)
30.                             in (ptinpoly_p ct (cons (last wp) wp))
31.                      )
32.                      (if (or
33.                              (and in (not (equal wp bp)))
34.                              (and (not in) (equal wp bp))
35.                           )
36.                          (setq tr (list (vl-position  (car   tp) pl)
39.                                   )
40.                                tl (vl-remove tr tl)
41.                              3dfl (vl-remove en 3dfl)
42.                                ** (entdel en)
43.                          )
44.                      )
45.                   )
46.
47.
« Last Edit: April 30, 2016, 04:16:43 PM by ymg »

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #625 on: April 30, 2016, 03:51:07 PM »
YMG,

I would like you to look at how I modified the OCD code. It virtually clips all 3dfaces that are outside the Boundary. Nothing is missed. It also is not using a Centroid model, which can fall outside the body of the Boundary. It is work your examination. Please test it.

Rick
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### ymg

• Guest
##### Re: Triangulation (re-visited)
« Reply #626 on: April 30, 2016, 04:21:48 PM »
Rick,

I will look at it.  But the centroid of a triangle
is guaranteed to be inside.

The routine to check if that centroid is in the
polyline is ptinpoly_p and I've checked it quite
extensively.

A simplification of this would be to check if the
biggest polyline in bp contains all the point of the
triangulation. If so we would trim the exterior,
else if it has no point within we trim the inside.

This way we remove the necessity to assign the
outside boundary to a layer in order to recognize it.

Now I look at your modification.  To make it work with TIN
you simply need to update tl by removing any triangle that you
are deleting.  You do the same with 3dfl removing the ENAME
of  any 3DFACES you delete.

This snippet does it:

Code - Auto/Visual Lisp: [Select]
1. (setq tr (list
2.                    (vl-position  (car   tp) pl)
5.             )
6.          tl (vl-remove tr tl)
7.       3dfl (vl-remove en 3dfl)
8.        ** (entdel en)
9. )
10.

ymg
« Last Edit: April 30, 2016, 04:59:18 PM by ymg »

#### rw2691

• Newt
• Posts: 133
##### Re: Triangulation (re-visited)
« Reply #627 on: April 30, 2016, 05:13:52 PM »
YMG,

When I use your current Centroid routine it does not delete external TIN's that have only one corner touching the Boundary, and it does not delete any TIN's that are detached and beyond the Boundary. Leaving the user to manually delete them one by one.

The OCD does delete them. It doesn't miss any TIN that is outside, and it protects all that are inside.

Rick
Hippocrates (400BC), "Life is short, craft long, opportunity fleeting, experiment treacherous, judgment difficult."

#### ymg

• Guest
##### Re: Triangulation (re-visited)
« Reply #628 on: April 30, 2016, 05:20:52 PM »
Rick,

Could be a bug as this was put together quite fast.

But as I told you, I am only using centroid of triangles
and ptinpoly_p to check if the centroid is inside the polyline

I will have a look at it.

ymg

#### ymg

• Guest
##### Re: Triangulation (re-visited)
« Reply #629 on: April 30, 2016, 06:40:46 PM »
Rick,

I did a few test and I could not replicate the behaviour
you are experiencing.

However if your boundary is not exactly on the nodes
you will have something like what you describe.

As it is the bound function is not too good, the following is
a little better.

Code - Auto/Visual Lisp: [Select]
1. (defun c:bound (/ sp tmp)
2.    (setq oldosm (getvar 'OSMODE))
3.    (if (not csurf) (setq csurf "Natural Ground"))
4.    (if (/= "" (setq tmp (getstring (strcat "\nCreates a Boundary for TIN <" csurf ">: "))))
5.      (setq csurf tmp)
6.    )
7.    (mk_layer (list "Boundary" 2))
8.
9.    (setvar 'OSMODE 8)
10.    (prompt "\nSelect Points on Boundary: ")
11.    (command "_3DPOLY"  pause )
12.      (while (command pause))
13.    (setq *bounden* (entlast))
14.    (setvar 'OSMODE oldosm)
15.    (princ)
16. )
17.