wassimj / topologicpy

The python bindings for topologic
MIT License
83 stars 23 forks source link

Optimize Clustering Faces #43

Closed nickger closed 9 months ago

nickger commented 9 months ago

Currently faces are clustered by directions of their normals. This can lead to inaccuracies when one interprets the result as groups of coplanar faces, because coplanarity is defined through the absolute distance between points and common plane. Thus for big faces even a small difference between directions of normals does not guarantee coplanarity of vertices. Instead, one can use tolerance in distance units directly, if we compare not normalized normals: image If we keep the length of each vector proportional to (optimally) diagonal of the face, this criterium will help us to assure coplanarity. As a bonus, there is no need for atan() function, we stay with coordinates.

Line 2476 in Topology.py in this case:

elif 2*norm(cross_product(v1, v2))/max([norm(v1), norm(v2)]) < tol:

Line 2542:

character size as perimeter devided by compactness

normals.append(Vector.Multiply(Face.NormalAtParameters(aFace, 0.5, 0.5, "XYZ", 3), 2sqrt(piFace.Area(aFace)/Face.Compactness(aFace)**2)))

P.S. Is there a reason why the grouping is quadratic in number of faces..? Quasi-Linear would be like:

groups = {} for idx, v1 in enumerate(normals): ....found = False ....for v2 in groups: ........if 2*norm(cross_product(v1, v2))/max([norm(v1), norm(v2)]) < tol: ............groups[v2].append(aFaces[idx]) ............found = True ............break ....if not found: ........groups[v1] = [aFaces[idx]]

We basically don't care about optimizing the number of clusters - if there is an even distribution of normals (tesselated curved surface), we cluster as is, don't we? If normals are well separated, this algorithm works fine.

wassimj commented 9 months ago

Thanks. Will consider when I have some free time.