You'll probably have to subsample the cloud points. It's probably not wise to throw more than 15000 points on the best fit method.
For the sampling I had to change the cloud point retrieval a bit. Before I did add the points to the final list in a scan after scan way.
Since the sampling should happen on all the selected points in one go, I now need to get the ID's of the selected portions first, and throw that list onto the sampling method, which returns another ID.
(If you'd do the sampling in the scan by scan matter and compile the final list from those subsets, you'd end up with more and denser points than you'd want.)
Relatively simple once you find out. If Trimble would just bother to document it somewhere. Came across the .Net documentation for AutoCad yesterday, what a dream compared to the brick of empty white pages we've got.
# compile a list with the ID's of the selected cloud portions
cloudselectionids = []
for o in selectionSet:
if isinstance(o, self.pointcloudType):
cloudselectionids.Add(o.Integration.GetSelectedCloudId())
# throw that list of all the selected portions onto the sampling algorithm
# it returns another ID
cpssampleid = o.Integration.PointCloudDatabase.Integration.CreateSpatiallySampledCloud(cloudselectionids, 0.025, 15000)
# now get the points from that specific subcloud
cps2 = o.Integration.PointCloudDatabase.Integration.GetPoints(cpssampleid)
for p in cps2:
rwcloudpoints.Add(RwPoint3D(p.X, p.Y, p.Z))
------------------------------
Ronny Schneider
------------------------------
Original Message:
Sent: 06-18-2024 02:21
From: Fernando Calvo
Subject: what's the general purpose of the new Namespace Trimble.Rw.Core in 2024.00?
Hi Ronny,
thanks a lot for the info ! it sounds indeed promising, and I´ll give it a try asap.
Regards,
Fernando
------------------------------
Fernando Calvo
calvo@calvo-geospatial.com
Original Message:
Sent: 06-18-2024 01:27
From: Ronny Schneider
Subject: what's the general purpose of the new Namespace Trimble.Rw.Core in 2024.00?
Stumbled upon it by pure chance.
Does the Rw imply that it comes from Realworks or has it something to do with Railway?
It comes with some interesting Classes, which make it really simple to compute best fit planes. Might be useful for you, Fernando.
A long time ago have been experimenting with the external MathNet library in order to compute the SVD, but you need to setup the matrices and linear solver the right way, rather complicate.
Now you just need to throw a list with points onto FitPlaneTo3DPoints.
# the Plane3D and Point3D struct are unfortunately differentclr.AddReference ("Trimble.Rw.Core")from Trimble.Rw.Core.VectorMath.Geometry import Plane3D as RwPlane3Dfrom Trimble.Rw.Core.VectorMath import Point3D as RwPoint3D rwcloudpoints = [] for o in selectionSet: if isinstance(o, self.pointcloudType): cps = o.Integration.PointCloudDatabase.Integration.GetPoints(o.Integration.GetSelectedCloudId()) for p in cps: rwcloudpoints.Add(RwPoint3D(p.X, p.Y, p.Z)) # adding as Rw type Point3D rwplane = RwPlane3D.FitPlaneTo3DPoints(rwcloudpoints) # converting back to our usual Trimble.Vce.Geometry struct types centerp = Point3D(rwplane.Point.X, rwplane.Point.Y, rwplane.Point.Z) v = Vector3D(rwplane.NormalVector.X, rwplane.NormalVector.Y, rwplane.NormalVector.Z)
Makes it simple to create a best fit planar surface into a bunch of pickup points, something I had been missing just recently.
slope = wv.Add(clr.GetClrType(SlopingLevelSurface)) slope.Name = Model3D.GetUniqueName("Testslope", None, wv) #make sure name is unique slope.BoundarySerialNumber = l.SerialNumber slope.ElevationSlopeType = ElevationSlopeTypes.PointAndDirection slope.Point1 = centerp slope.Point2 = centerp + v slope.Azimuth = v.Azimuth slope.LeftInclination = 0 slope.RightInclination = 0 slope.Slope = v.Horizon + math.pi/2
------------------------------
Ronny Schneider
------------------------------