Solved: Contour Layout for Building Site

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
emills2
Posts: 866
Joined: Tue Apr 28, 2015 11:23 pm

Re: Contour Layout for Building Site

Post by emills2 »

ok i have something to start. it's not a smooth contour plot, but it'll give you an idea.
this explanation will go in reverse. final result > back to the data

i got a bunch of contours by applying 200 cross sections to a shell object (single GUI operation) with 1 unit separation
roo_contour_1.png
roo_contour_1.png (196.93 KiB) Viewed 1791 times
if you look at it from the top, it is a contour map. it's ugly because it is only as good as the shell being cut

i got the shell by joining a bunch of triangular faces (this was a TON of work. i picked point pairs for each line and line triples for each face)
roo_contour_3.png
roo_contour_3.png (55.54 KiB) Viewed 1791 times
you need to keep the triangles small and as equal sided as possible.

lots and lots of lines radiating from a single point is a bad sign in a triangular mesh, it indicate the result won't be very realistic. i did my best to make the triangles not too skinny by choosing the right groups of three, but you can see there are spots i didn't have much of a choice. for any quadrangle, there are two ways to cut it into two triangles. sometimes one is clearly better, sometimes not, can't spend forever on it. more points, well spread out, helps a lot.

i drew the triangles on top of your data, after i had rotated and aligned it.
roo_contour_4.png
roo_contour_4.png (37.02 KiB) Viewed 1791 times
the colors match your set.
each data point has a circle at 0 elev, and a line going from the center of the circle to the data point elevation.

data set 1 and 3 each have a triangle for connecting datasets, dataset 2 has a single line for connecting datasets. (dataset 3 is basically just the triangle). this was really annoying to track, i had to count the data points a few times to match 3, 5,17, and 34. since it all fits, i think this is right. not sure. for the skae of this exercise, it's not super important

to move the points as a group, i made a compound object out of all the circles and lines in each group.
roo_contour_5.png
roo_contour_5.png (38.47 KiB) Viewed 1791 times
i moved the yellow triangle to the green dataset by matching the red circles using Draft Move. then i used Draft Rotate to spin it. only one side of the triangles was even close in length, so lined up that side.
same thing with the orange line, there was only one place it would fit. Draft move, Draft Rotate.

you can use the Draft Point tool and enter x,y,z directly one at a time. i did it with a script, to draw the ground circle and the vertical lines, because i wanted those to help me align things.

i created the objects one set at a time like so:

Code: Select all

import FreeCAD, Part, math
from FreeCAD import Base
from FreeCAD import Gui

#put raw data in here
roo_raw_set_1 = [[5818,-10495,100],
			[-4294,7909,100],
			[1890,-3146,142],
			[1169,-1733,143.7],
			[-88,431,135.3],
			[240,163,141.3],
			[530,883,136.5],
			[126,1595,141.5],
			[779,450,142.2],
			[1106,664,137],
			[1983,1145,121.2],
			[2221,1272,117.7],
			[2864,1640,112],
			[3751,2122,105.1],
			[4613,2610,90.7],
			[0,1250,144.1],
			[4874,2758,97]]

roo_elev_set_1 = [Base.Vector(0,0,0)]*len(roo_raw_set_1)
roo_ground_set_1 = [Base.Vector(0,0,0)]*len(roo_raw_set_1)

for i in range(0,len(roo_elev_set_1)):
	roo_elev_set_1[i] = Base.Vector(roo_raw_set_1[i][0],roo_raw_set_1[i][1],roo_raw_set_1[i][2])

for i in range(0,len(roo_ground_set_1)):
	roo_ground_set_1[i] = Base.Vector(roo_raw_set_1[i][0],roo_raw_set_1[i][1],0)

for i in range(0,len(roo_ground_set_1)):
	Part.show(Part.Circle(roo_ground_set_1[i], Base.Vector(0,0,1), 50).toShape())

for i in range(0,len(roo_ground_set_1)):
	Part.show(Part.LineSegment(roo_ground_set_1[i], roo_elev_set_1[i]).toShape())

#ref triangle for set 1 <3,5,17> = [2],[4],[16]
Part.show(Part.LineSegment(roo_ground_set_1[2], roo_ground_set_1[4]).toShape())
Part.show(Part.LineSegment(roo_ground_set_1[4], roo_ground_set_1[16]).toShape())
Part.show(Part.LineSegment(roo_ground_set_1[16], roo_ground_set_1[2]).toShape())
i slapped all these objects in a folder and made them green.

then i ran the next data set

Code: Select all

roo_raw_set_2 = [[1500,0,97],
				[757,386,108.8],
				[1085,-803,79.9],
				[891,-1483,53.1],
				[1231,-1860,7.2],
				[84,-1207,66.7],
				[-1300,-2990,44.4],
				[-571,-2884,36.4],
				[-550,-3284,-199.1],
				[-527,-2842,10.2],
				[-1778,-2317,75.2],
				[-1220,-1404,61.2],
				[-268,80,76.2],
				[-1698,89,72.4],
				[-1223,1181,94.7],
				[-2021,1820,128.3],
				[-2167,1490,100.5]]


roo_elev_set_2 = [Base.Vector(0,0,0)]*len(roo_raw_set_2)
roo_ground_set_2 = [Base.Vector(0,0,0)]*len(roo_raw_set_2)

for i in range(0,len(roo_elev_set_2)):
	roo_elev_set_2[i] = Base.Vector(roo_raw_set_2[i][0],roo_raw_set_2[i][1],roo_raw_set_2[i][2])

for i in range(0,len(roo_ground_set_2)):
	roo_ground_set_2[i] = Base.Vector(roo_raw_set_2[i][0],roo_raw_set_2[i][1],0)

for i in range(0,len(roo_ground_set_2)):
	Part.show(Part.Circle(roo_ground_set_2[i], Base.Vector(0,0,1), 50).toShape())

for i in range(0,len(roo_ground_set_2)):
	Part.show(Part.LineSegment(roo_ground_set_2[i], roo_elev_set_2[i]).toShape())
	
#ref line for set 2 <17,34> = [0],[16]
Part.show(Part.LineSegment(roo_ground_set_2[0], roo_ground_set_2[16]).toShape())
and the 3rd set

Code: Select all

roo_raw_set_3 = [[0,-3200,100.5],
				[-258,29,141.3],
				[3801,-266,134.1]]
				
roo_elev_set_3 = [Base.Vector(0,0,0)]*len(roo_raw_set_3)
roo_ground_set_3 = [Base.Vector(0,0,0)]*len(roo_raw_set_3)


for i in range(0,len(roo_elev_set_3)):
	roo_elev_set_3[i] = Base.Vector(roo_raw_set_3[i][0],roo_raw_set_3[i][1],roo_raw_set_3[i][2])

for i in range(0,len(roo_ground_set_3)):
	roo_ground_set_3[i] = Base.Vector(roo_raw_set_3[i][0],roo_raw_set_3[i][1],0)

for i in range(0,len(roo_ground_set_3)):
	Part.show(Part.Circle(roo_ground_set_3[i], Base.Vector(0,0,1), 50).toShape())

for i in range(0,len(roo_ground_set_3)):
	Part.show(Part.LineSegment(roo_ground_set_3[i], roo_elev_set_3[i]).toShape())

#ref triangle for set 1 <3,5,17> = [2],[4],[16]
Part.show(Part.LineSegment(roo_ground_set_3[0], roo_ground_set_3[1]).toShape())
Part.show(Part.LineSegment(roo_ground_set_3[1], roo_ground_set_3[2]).toShape())
Part.show(Part.LineSegment(roo_ground_set_3[2], roo_ground_set_3[0]).toShape())
you only need to run the import statements once within the same session.
emills2
Posts: 866
Joined: Tue Apr 28, 2015 11:23 pm

Re: Contour Layout for Building Site

Post by emills2 »

looks a little better with majors and minors. they don't meet up exactly, but i didn't try very hard
roo_contour_6.png
roo_contour_6.png (103.18 KiB) Viewed 1787 times
if you know the site, you should be able to do a better job choosing the triangles, and you might even....'remember' a judicious datapoint to break up a zone with bad cluster on a single point
User avatar
roo
Posts: 49
Joined: Sat Jul 29, 2017 9:24 am
Location: oz

Re: Contour Layout for Building Site

Post by roo »

emills2 wrote: Sun Jul 30, 2017 11:54 am ... if you know the site ...
Yes I know the site very well and I am impressed by what you have achieved. The major 3D contours are very realistic within the property boundaries.

The survey is fairly crappy because the site is covered by buildings and vegetation making it difficult to get survey lines. The buildings also affect the heights. One point down the southern end is through dense vegetation that drops off into water. Despite the minimal change in elevation over the site the southern end gets inundated by local flooding.

The only real improvements I could make to the data are two points along a shed on the western side and find another dataset with the water line. I look forward to being able to upload this sort of point data directly from a database without going into code in the future. Is there an easier way to create the triangles (tins?) in other software?
User avatar
Kunda1
Veteran
Posts: 13447
Joined: Thu Jan 05, 2017 9:03 pm

Re: Contour Layout for Building Site

Post by Kunda1 »

Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
emills2
Posts: 866
Joined: Tue Apr 28, 2015 11:23 pm

Re: Contour Layout for Building Site

Post by emills2 »

roo wrote: Sun Jul 30, 2017 1:42 pm being able to upload this sort of point data directly from a database without going into code in the future. Is there an easier way to create the triangles (tins?) in other software?
it's possible there is something in the thread Kunda1 linked that matches your needs. I'm not a surveyor or civil engineer and i don't really have time to read all 17 pages of that thread personally.

I looked at your original spreadsheet, figured i could do it with the limited amount of data that was there, so i just did it.

I just tried importing your csv directly into a spreadsheet in FreeCAD and it worked fine. you could select a data range to create a point cloud for each station. The script to do that is probably fairly simple, and would not need to be rewritten all the time. you can give it a button and it works just like a native function. i put all the data in the text file because that's what's confortable for me.

rotating and aligning the stations can be automated too, but that's a lot of work. moving things on screen with Draft Move/Rotate id easy if there aren't too many stations.

I bet you there is a decent triangulation algorithm already in FreeCAD to do the triangulation from the point cloud, but i don't know where it is.

The Curves workbench addon can make a smooth surface from a point cloud, so we could format our survey cloud maker to be compatible with that. it don't know if a smooth surface will work with sparse data though. A triangle option is always good.

So as you can see, all the parts are there...some assembly required!
emills2
Posts: 866
Joined: Tue Apr 28, 2015 11:23 pm

Re: Contour Layout for Building Site

Post by emills2 »

here's something cool: the Points Workbench will import ascii point files.

the surveying jargon is a bit confusing to me, but i think it works like this:
point_number, y, x, z
emills2
Posts: 866
Joined: Tue Apr 28, 2015 11:23 pm

Re: Contour Layout for Building Site

Post by emills2 »

can someone check this model? there is a point cloud object in the tree, but i see nothing in model view.

FreeCAD took my .asc point file without giving me errors, but i don't know if the format is really right

i did
point_number, Y, X, Z

can't load asc file to forum, it 's a text file extension.asc that contains:
1,-4363.482299,-11178.55188,100
2,3199.324591,8412.153242,100
3,-1452.998881,-3370.11784,142
4,-926.7674676,-1873.286433,143.7
5,29.33596056,439.0209578,135.3
6,-259.4792342,129.5010695,141.3
7,-643.6786518,804.1006113,136.5
8,-337.4946937,1564.000426,141.5
9,-832.5522052,341.8432763,142.2
10,-1184.591829,510.727127,137
11,-2118.382833,869.8012253,121.2
12,-2371.528217,964.0819033,117.7
13,-3057.048092,1242.761829,112
14,-4001.133963,1602.194437,105.1
15,-4920.187935,1970.215897,90.7
16,-166.9876961,1238.79583,144.1
17,-5198.689139,2081.737551,97
Attachments
ascii point cloud.FCStd
(5.91 KiB) Downloaded 49 times
User avatar
roo
Posts: 49
Joined: Sat Jul 29, 2017 9:24 am
Location: oz

Re: Contour Layout for Building Site

Post by roo »

emills2 wrote: Sun Jul 30, 2017 7:55 pm it's possible there is something in the thread Kunda1 linked that matches your needs. ...
No. These blokes must be economists ... first assume grid based elevation data (from mapping systems). :lol:
If you have a lot of data it is more straight forward. I expect the Civil Engineering Design functions will develop into a very sophisticated part of FreeCAD eventually.


Your process is boots on ground starting with raw survey data.

emills2 wrote: Sun Jul 30, 2017 8:14 pm .. i think it works like this:
point_number, y, x, z
I had a play with Points Module which is still in development but I didn't get anywhere. (Couldn't import and export the same data.) I am fairly sure it is X,Y,Z.

Currently the spreadsheet workbench still looks the best way to go.

As you said it looks like the TIN process is not easy. QGIS Tutorials and Tips - Interpolating Point Data:
Note
Interpolation results can vary significantly based on the method and parameters you choose. QGIS interpolation supports Triagulated Irregular Network (TIN) and Inverse Distance Weighting (IDW) methods for interpolation. TIN method is commonly used for elevation data ...
emills2
Posts: 866
Joined: Tue Apr 28, 2015 11:23 pm

Re: Contour Layout for Building Site

Post by emills2 »

I think a good first option for the TIN would be plane Delaunay in xy. I bet the FEM users could hand it over or point us in the right direction.

I'll ask in the python section later. This aspect touches on Surface reconstruction in general so there will be a lot of applicability.
emills2
Posts: 866
Joined: Tue Apr 28, 2015 11:23 pm

Re: Contour Layout for Building Site

Post by emills2 »

one more piece of the puzzle:
microelly2 wrote: Thu Jun 09, 2016 1:39 pm bp_021.png
This is the first example script for a distance 0.1

Code: Select all

import Points

# your point set
Points.insert("yourpath/aaa.asc",'pointcloudtest')
pts=App.ActiveDocument.ActiveObject
pts.ViewObject.hide()

# the exact model
App.ActiveDocument.addObject("Part::Box","Box")
mymodel=App.ActiveDocument.ActiveObject
mymodel.ViewObject.Transparency=80
App.ActiveDocument.ActiveObject.ViewObject.ShapeColor=(1.0,1.0,0.0)

App.ActiveDocument.recompute()


ptin=[]
ptoff=[]
for p in pts.Points.Points:
	if mymodel.Shape.isInside(p,0.1,True):
		ptin.append(p)
	else:
		ptoff.append(p)


# the good points
pin=Points.Points(ptin)
Points.show(pin)
App.ActiveDocument.ActiveObject.ViewObject.ShapeColor=(0.0,1.0,0.0)

# the bad points
pout=Points.Points(ptoff)
Points.show(pout)
App.ActiveDocument.ActiveObject.ViewObject.ShapeColor=(1.0,.0,0.0)

Gui.SendMsgToActiveView("ViewFit")



rename aaa.asc.zip to aaa.asc

We can make a finer grouping of the points for some threshold distances.
The next step can be a detailed calculation and visualization of the quality.
I will think about a common useable datamodel for this process ...

disttoShape is a little bit harder because I need a shape and not a point cloud, so I don't know about the complexity and execution time of that approach.
I think that Microelly intended to share this info freely, so unless he says otherwise, i will go ahead and extract the parts we need :)

i stripped it down to:

Code: Select all

import Points

# your point set
Points.insert("C:/Users/Edward Mills/Desktop/aaa.asc",'pointcloudtest')
pts=App.ActiveDocument.ActiveObject
App.ActiveDocument.recompute()
and used Microelly2's data file and i got the point cloud! i can use Draft-move and Draft-rotate no problem, but i can't use Part-shapebuilder to draw lines or make triangles.
import_ascii_point_cloud.png
import_ascii_point_cloud.png (331.11 KiB) Viewed 1697 times
the data format looks like this:

Code: Select all

# .PCD v.7 - Point Cloud Data file format
VERSION .7
FIELDS x y z
SIZE 4 4 4
TYPE F F F
COUNT 1 1 1
WIDTH 6731
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 6731
DATA ascii-1.722589 -0.143634 -0.216288
-1.740747 -0.177579 0.061200
-1.752511 -0.209131 0.347220
-1.664818 -0.243143 0.519649
-1.657540 -0.256695 0.735410
-1.649490 -0.268120 0.948397
-1.730741 -0.272268 1.282566
-1.716000 -0.278113 1.434756
...
Post Reply