예제 #1
0
        public static Point3d DistFromPointToSolid(
            ref Document doc, ref Solid3d solid, Point3d point, double start, double step, ref double off, bool line)
        {
            var rez = new Point3d();

            using (var acTrans = doc.Database.TransactionManager.StartTransaction())
            {
                var acBlkTbl = (BlockTable)acTrans.GetObject(doc.Database.BlockTableId, OpenMode.ForWrite);

                var acBlkTblRec = (BlockTableRecord)acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                var SOLID = (Solid3d)solid.Clone();
                SOLID.SetDatabaseDefaults();
                acBlkTblRec.AppendEntity(SOLID);
                acTrans.AddNewlyCreatedDBObject(SOLID, true);


                var startR = start <= 0 ? step : start;

                var sphere = new Solid3d();
                sphere.SetDatabaseDefaults();
                sphere.CreateSphere(startR);
                sphere.TransformBy(Matrix3d.Displacement(Point3d.Origin.GetVectorTo(point)));
                sphere.SetDatabaseDefaults();
                acBlkTblRec.AppendEntity(sphere);
                acTrans.AddNewlyCreatedDBObject(sphere, true);


                while (sphere.CheckInterference(solid) == false)
                {
                    try
                    {
                        sphere.OffsetBody(step);
                        off += step;
                    }
                    catch
                    {
                    }
                }

                if (line)
                {
                    var counter = 0;

                    sphere.BooleanOperation(BooleanOperationType.BoolIntersect, SOLID);
                    var dbo = new DBObjectCollection();
                    sphere.Explode(dbo);

                    var coll       = new Point3dCollection();
                    var curvesColl = new DBObjectCollection();

                    var ent = dbo[0] as Entity;
                    if (ent.GetType().ToString().IndexOf("Surface") > 0)
                    {
                        var surf =
                            ent as Surface;
                        var ns = surf.ConvertToNurbSurface();
                        foreach (var nurb in ns)
                        {
                            double ustart   = nurb.UKnots.StartParameter,
                                     uend   = nurb.UKnots.EndParameter,
                                     uinc   = (uend - ustart) / nurb.UKnots.Count,
                                     vstart = nurb.VKnots.StartParameter,
                                     vend   = nurb.VKnots.EndParameter,
                                     vinc   = (vend - vstart) / nurb.VKnots.Count;

                            for (var u = ustart; u <= uend; u += uinc)
                            {
                                for (var v = vstart; v <= vend; v += vinc)
                                {
                                    coll.Add(nurb.Evaluate(u, v));
                                    counter++;
                                }
                            }
                        }
                        if (counter < 1)
                        {
                            var sub = new DBObjectCollection();
                            surf.Explode(sub);
                            foreach (Entity entt in sub)
                            {
                                acBlkTblRec.AppendEntity(entt);
                                acTrans.AddNewlyCreatedDBObject(entt, true);
                                curvesColl.Add(entt);
                            }
                        }
                    }
                    else
                    {
                        var surf = (Region)ent;
                        var p1   = surf.GeometricExtents.MaxPoint;
                        var p2   = surf.GeometricExtents.MinPoint;
                        var p    = new Point3d((p1.X + p2.X) / 2.0, (p1.Y + p2.Y) / 2.0, (p1.Z + p2.Z) / 2.0);
                        coll.Add(p);
                        coll.Add(p);
                        var sub = new DBObjectCollection();
                        surf.Explode(sub);
                        foreach (Entity entt in sub)
                        {
                            acBlkTblRec.AppendEntity(entt);
                            acTrans.AddNewlyCreatedDBObject(entt, true);
                            curvesColl.Add(entt);
                        }
                    }

                    foreach (DBObject ob in curvesColl)
                    {
                        var curve = (Curve)acTrans.GetObject(ob.Id, OpenMode.ForRead);
                        var p1    = curve.StartPoint;
                        var p2    = curve.EndPoint;
                        var p     = new Point3d((p1.X + p2.X) / 2.0, (p1.Y + p2.Y) / 2.0, (p1.Z + p2.Z) / 2.0);

                        coll.Add(p);
                        coll.Add(p1);
                        coll.Add(p2);
                    }

                    if (coll.Count > 0)
                    {
                        rez = coll[0];
                        foreach (Point3d p in coll)
                        {
                            if (p.DistanceTo(point) < rez.DistanceTo(point))
                            {
                                rez = p;
                            }
                        }
                    }
                    else
                    {
                        rez = point;
                    }
                }
                // acTrans.Commit();
            }
            return(rez);
        }