CloudComPy icon indicating copy to clipboard operation
CloudComPy copied to clipboard

C2C maxSearchDist Question

Open PMDevine1 opened this issue 2 years ago • 8 comments

Hello,

I was wondering if you could please explain how set up the code to run a C2C distance with a maxSearchDist parameter? I tried setting the maxSearchDist in Cloud2CloudDistancesComputationParams, but the results are way different than what I get in the GUI or commandline.

I also see in the documentation: WARNING Max search distance (Cloud2CloudDistanceComputationParams::maxSearchDist > 0) is not compatible with the determination of the Closest Point Set (Cloud2CloudDistanceComputationParams::CPSet)"

I'm sure it's just something going over my head, but some help on how to utilize the tool would be much appreciated.

Thank you!

PMDevine1 avatar Aug 25 '22 21:08 PMDevine1

Can you share some code maybe? It may be easier to point out what's wrong that explaining you all the parameters 😅

(I guess you already looked at what is done in CC? https://github.com/CloudCompare/CloudCompare/blob/master/qCC/ccComparisonDlg.cpp#L718

dgirardeau avatar Aug 26 '22 09:08 dgirardeau

True! haha Here's the code I have for c2c:

bestOctreeLevel = cc.DistanceComputationTools.determineBestOctreeLevel(compCloud =source_cc, refMesh = None, refCloud = ref_cc) c2c_params = cc.Cloud2CloudDistancesComputationParams() c2c_params.octreeLevel = bestOctreeLevel c2c_params.maxSearchDist = 1.0 cc.DistanceComputationTools.computeCloud2CloudDistances(source_cc,ref_cc, c2c_params)

I looked in that doc, but still not seeing what the problem is.

Thanks!

PMDevine1 avatar Aug 26 '22 13:08 PMDevine1

Nothing obvious pops out on my side. Maybe @prascle will have an idea?

dgirardeau avatar Aug 26 '22 13:08 dgirardeau

Hello,

I don't see any problem with your code...

Here is an example that works for me.

I want to check if I can find a good value for the minimum distance between two clouds, (2 spheres with radius 2.4, distance 0.2). I am not interested in the accuracy of the distance field everywhere, using maxSearchDist with a small value will speed up the calculation.

I use computeApproxCloud2CloudDistance to get an estimate of the minimum distance: here we find approxMinDistance=0.15. I use maxSearchDist = 3*approxMinDistance to be sure to be above the actual minimum distance.

I find the minimum distance value of 2.04 in the scalar field 'C2C absolute distances'. The scalar field does not have a value greater than 3*approxMinDistance.

Let me know if this works for you and if it helps you solve your problem.

Best regards, Paul

import os
import sys
import math
import psutil

os.environ["_CCTRACE_"]="ON" # only if you want C++ debug traces

from gendata import dataDir, isCoordEqual
import cloudComPy as cc

sphere0 = cc.ccSphere(2.4, None, "sphere0", 72)
c0 = sphere0.samplePoints(False, 1000000)

tr1 = cc.ccGLMatrix()
tr1.initFromParameters(0.0, (0., 0., 0.), (3, 4, 0))
sphere1 = cc.ccSphere(2.4, tr1, "sphere1", 72)
c1 = sphere1.samplePoints(False, 1000000)

stats = cc.DistanceComputationTools.computeApproxCloud2CloudDistance(c0, c1)
approxMinDistance = stats[0]

bestOctreeLevel = cc.DistanceComputationTools.determineBestOctreeLevel(c0, None, c1)
params = cc.Cloud2CloudDistancesComputationParams()
params.octreeLevel = bestOctreeLevel
params.maxSearchDist = 3*approxMinDistance

cc.DistanceComputationTools.computeCloud2CloudDistances(c0, c1, params)

dic = c0.getScalarFieldDic()
sf = c0.getScalarField(dic['C2C absolute distances'])
minDist = sf.getMin()
maxDist = sf.getMax()

cc.SaveEntities([c0,c1], os.path.join(dataDir, "cloudDist.bin"))

prascle avatar Aug 27 '22 12:08 prascle

Thank you for your reply! That code helps a lot!

I think I figure out what my problem is -- I think it has to do with the global offsets. When I use the GUI, I offset my first cloud using the suggested values and then import the rest of the co-aligned point clouds with the "previous input" setting so they're all imported in the same coordinate space with the same offsets.

I think CloudCompy is suggesting different offset values for the clouds so they're not imported into the same coordinate space, which is why I'm seeing different different results compared to the GUI or commandline.

Is there a way in CloudCompy to use the "previous input" for the offsets like you can in the GUI? I see I can use CC_SHIFT_MODE.XYZ to set specific XYZ offsets, but I guess that means I'd have to calculate what those offsets would be ahead of time before importing into CloudCompy.

Thanks!

PMDevine1 avatar Aug 27 '22 16:08 PMDevine1

I just did a test with CC_SHIFT_MODE.XYZ using the same known XYZ offsets for both clouds and got perfect results with the distance tool. I guess the only problem with that is I have to know or calculate the offsets ahead of time.

PMDevine1 avatar Aug 27 '22 16:08 PMDevine1

You are right, I hope it will be easier in the next release, with issue #66 solved. With #66, the idea is to have an automatic shift with a first cloud, get the shift value and apply this shift to other cloud. With CloudComPy, I can't easily reproduce the GUI behaviour (apply automatically the first shift to subsequent clouds). I still have several things to fix before the next release, I hope to do it within 2 weeks. Regards, Paul

prascle avatar Aug 27 '22 21:08 prascle

Thanks for all you do!

PMDevine1 avatar Aug 29 '22 00:08 PMDevine1