[CommandMethod("MyPointCloud")]
public void GeneratePoints()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
using (Transaction tr = doc.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
Random rnd
= new Random
(); for (int i = 0; i < 1000; i++)
{
DBPoint p
= new DBPoint
(new Point3d
(5 * rnd
.NextDouble(),
100 * rnd
.NextDouble(),
100 * rnd
.NextDouble())); btr.AppendEntity(p);
tr.AddNewlyCreatedDBObject(p, true);
}
tr.Commit();
}
}
[CommandMethod("GetNormals")]
public void GetNormals()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
RXClass rxc
= RXClass
.GetClass(typeof(DBPoint
));
using (BlockTableRecord btr = (BlockTableRecord)db.CurrentSpaceId.Open(OpenMode.ForWrite))
{
ObjectId[] ids = btr.Cast<ObjectId>().Where(id => id.ObjectClass == rxc).ToArray();
int len = ids.Length;
Point3d
[] pts
= new Point3d
[len
]; for (int i = 0; i < len; i++)
{
using (DBPoint pt = (DBPoint)ids[i].Open(OpenMode.ForRead))
{
pts[i] = pt.Position;
}
}
Point3dTree tree
= new Point3dTree
(pts,
false); Dictionary
<Point3d, List
<Point3d
>> neighbors
= new Dictionary
<Point3d, List
<Point3d
>>(); getNeighbors(tree, tree.Root, 15, neighbors);
List
<Vector3d
> vectors
= new List
<Vector3d
>(); foreach (var set in neighbors)
{
Vector3d ave
= new Vector3d
(0,
0,
0); if (set.Value.Count < 2) continue;
Point3d pt = Nearest(set.Key,set.Value);
int count = set.Value.Count;
set.Value.Remove(pt);
for (int i = set.Value.Count-1; i > -1; i--)
{
vectors.Add(set.Key.GetVectorTo(pt));
pt = Nearest(pt, set.Value);
set.Value.Remove(pt);
}
Vector3d tmp;
for (int i = 0; i < vectors.Count-1; i++)
{
tmp = vectors[i].CrossProduct(vectors[i + 1]);
if (ave.DotProduct(tmp) < 0)
ave -= tmp;
else
ave += tmp;
}
tmp = vectors[0].CrossProduct(vectors[vectors.Count - 1]);
if (ave.DotProduct(tmp) < 0)
ave -= tmp;
else
ave += tmp;
vectors.Clear();
ave = ave.DivideBy(ave.Length / 10);
using (Line line
= new Line
(set.Key,
set.Key+ave
)) {
btr.AppendEntity(line);
}
}
}
}
private Point3d Nearest(Point3d pt, List<Point3d> pts)
{
double best = double.MaxValue;
Point3d ret
= new Point3d
(); foreach (Point3d pnt in pts)
{
double cur =pt.DistanceTo(pnt);
if (cur<best)
{
best = cur;
ret = pnt;
}
}
return ret;
}
private void getNeighbors(Point3dTree tree, KdTreeNode<Point3d> node, double dist, Dictionary<Point3d, List<Point3d>> neighbors)
{
if (node == null) return;
node.Processed = true;
if (neighbors.ContainsKey(node.Value))//this is just a sanity check, MUST be removed for processing large items once method is proven
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nPoint processed again");
}
else
{
List
<Point3d
> pts
= new List
<Point3d
>(); foreach (Point3d pt in tree.NearestNeighbours(node, dist))
{
pts.Add(pt);
}
neighbors.Add(node.Value, pts);
}
getNeighbors(tree, node.LeftChild, dist, neighbors);
getNeighbors(tree, node.RightChild, dist, neighbors);
}