RhinoCommon 中对Mesh 进行顶点焊接,可以使用CombineIdentical方法,参考代码如下:
Mesh capFace = new Mesh();
if (!(M.IsClosed))
{
Polyline[] nakedBoundaries = M.GetNakedEdges();
for (int i = 0; i <= nakedBoundaries.Count() - 1; i++)
{
capFace = Mesh.CreateFromClosedPolyline(nakedBoundaries[i]);
M.Append(capFace);
}
M.Vertices.CombineIdentical(true, true);
M.Normals.ComputeNormals();
M.UnifyNormals();
}
A = M;
以下为错误动作示范:
private void RunScript(Mesh M, ref object A)
{
Mesh capFace = new Mesh();
Mesh capFaces = new Mesh();
if (!(M.IsClosed))
{
Polyline[] nakedBoundaries = M.GetNakedEdges();
for (int i = 0; i <= nakedBoundaries.Count() - 1; i++)
{
capFace = Mesh.CreateFromClosedPolyline(nakedBoundaries[i]);
capFaces.Append(capFace);
}
M.Append(capFaces);
M.Vertices.CombineIdentical(false, true);
//if I put first option (ignore normals)as true I get invalid mesh
//With false I get a valid mesh but its doesnt seem to actually combine the Vertices
//M.Weld(Math.PI); <----why does weld work?
M.UnifyNormals();
}
A = M;
}
It works correctly for adding one cap as such
private void RunScript(Mesh M, ref object A)
{
Mesh capFace = new Mesh(); Mesh capFaces = new Mesh();
if (!(M.IsClosed))
{
Polyline[] nakedBoundaries = M.GetNakedEdges();
for (int i = 0; i <= 0 ;i++) // once cap
{
capFace = Mesh.CreateFromClosedPolyline(nakedBoundaries[i]);
M.Append(capFace);
}
M.Vertices.CombineIdentical(true, true);
}
A = M;
}
对于Mesh操作,以下列出一些参考:
mesh.HealNakedEdges(radius);
mesh.Vertices.CombineIdentical(true, true);
mesh.Vertices.CullUnused();
mesh.Weld(3.14159265358979);
mesh.FaceNormals.ComputeFaceNormals();
mesh.Normals.ComputeNormals();
if (mesh.SolidOrientation() == -1)
mesh.Flip(true, true, true);
mesh.Compact();
以下展示使用Rtree达到同样效果(速度偏慢):
//Store naked mesh vertices and their ids
List<Point3f> pts = new List<Point3f>();
bool[] flag = M.GetNakedEdgePointStatus();
allPointsFound = new List<List<int>>();
//History is need to stop searching rtee
//When all point groups are found
history.Clear();
//Create Rtree
RTree tree = new RTree();
for(int i = 0; i < flag.Length; i++){
if(flag[i]){
tree.Insert(M.Vertices[i], i);
pts.Add(M.Vertices[i]);
}
}
//Search RTree
for(int i = 0; i < pts.Count; i++){
tempIDList = new List<int>();
tree.Search(new Sphere(pts[i], radius), method);
if(tempIDList.Count > 1)
allPointsFound.Add(tempIDList);
if(history.Count == M.Vertices.Count)
break;
}
//Now move found vertices to one of firs vertex position
foreach(List<int> i in allPointsFound)
for(int j = 1; j < i.Count; j++)
M.Vertices[i[0]] = M.Vertices[i[j]];
M.Vertices.CombineIdentical(false, false);
A = M;
}
// <Custom additional code>
//Rtree collections
List<int> history = new List<int>();
List<List<int>> allPointsFound;
List<int> tempIDList;
private void method(object sender, RTreeEventArgs e){
if(!history.Contains(e.Id)){
tempIDList.Add(e.Id);
history.Add(e.Id);
}
}
···
[https://discourse.mcneel.com/t/welding-meshes/69131/4](https://discourse.mcneel.com/t/welding-meshes/69131/4)
网友评论