Beispiel #1
0
        public static ExcavationSection Interpolate(ExcavationSection startSection, ExcavationSection endSection, double ratio)
        {
            ExcavationSection result = new ExcavationSection();

            for (int i = 0; i < Math.Max(startSection.Elements.Count, endSection.Elements.Count); i++)
            {
                int startIndex = Math.Min(i, startSection.Elements.Count - 1);
                int endIndex   = Math.Min(i, endSection.Elements.Count - 1);

                double hStart  = startSection.Elements[startIndex].H;
                double vStart  = startSection.Elements[startIndex].V;
                double hlStart = startSection.Elements[startIndex].HeightLimit;
                double llStart = startSection.Elements[startIndex].LengthLimit;

                double hEnd  = startSection.Elements[endIndex].H;
                double vEnd  = startSection.Elements[endIndex].V;
                double hlEnd = startSection.Elements[endIndex].HeightLimit;
                double llEnd = startSection.Elements[endIndex].LengthLimit;

                double h = hStart + ratio * (hEnd - hStart);
                double v = vStart + ratio * (vEnd - vStart);

                double hl = ((hlStart > 0 && hlEnd > 0) ? hlStart + ratio * (hlEnd - hlStart) : Math.Max(hlStart, hlEnd));
                double ll = ((llStart > 0 && llEnd > 0) ? llStart + ratio * (llEnd - llStart) : Math.Max(llStart, llEnd));

                ExcavationSectionElement ele = new ExcavationSectionElement(h, v);
                ele.HeightLimit = hl;
                ele.LengthLimit = ll;
                result.Elements.Add(ele);
            }

            return(result);
        }
Beispiel #2
0
        protected List <ExcavationSection> ExcavateCurve(Side slopeSide = Side.Right, double offset = 0)
        {
            double len      = ExcavationBottom.GetLength();
            int    nmax     = (int)Math.Ceiling(len / ExcavationStepSize);
            double dist     = 0.0;
            double distStep = len / ((double)nmax);

            if (!ExcavationBottom.Closed)
            {
                nmax++;
            }

            List <ExcavationSection> outputSections = new List <ExcavationSection>();

            for (int i = 0; i < nmax; i++)
            {
                double            param       = dist > len ? ExcavationBottom.EndParam : dist < 0 ? ExcavationBottom.StartParam : ExcavationBottom.GetParameterAtDistance(dist);
                Point3d           bottomPoint = ExcavationBottom.GetPointAtParameter(param);
                Vector3d          normal      = ExcavationBottom.GetNormalVector(param);
                ExcavationSection section     = GetSection(ExcavationBottom, dist);
                Point3d           pt          = bottomPoint + (slopeSide == Side.Right ? 1 : -1) * normal * Math.Abs(offset);
                Vector3d          dir         = (slopeSide == Side.Right ? 1 : -1) * normal;
                ExcavationSection outSection  = ExcavateSlopeAtPoint(Mesh, section, pt, dir);
                outputSections.Add(outSection);
                dist += distStep;
            }

            return(outputSections);
        }
Beispiel #3
0
        protected ExcavationSection GetSection(Curve excavationBottom, double distance)
        {
            double curveLength = excavationBottom.GetLength();

            if (sections.Count == 0)
            {
                throw new InvalidOperationException("No sections defined.");
            }

            if (sections.Count == 1)
            {
                return(sections[0]);
            }

            // Find the section before and closest to the given distance
            int    startIndex = 0;
            double minDiff    = double.MaxValue;

            for (int i = 0; i < distances.Count; i++)
            {
                double diff = distance - distances[i];
                if (diff < 0)
                {
                    diff += curveLength;
                }
                if (diff < minDiff)
                {
                    minDiff    = diff;
                    startIndex = i;
                }
            }
            if (Math.Abs(minDiff) < LengthTolerance)
            {
                return(sections[startIndex]);
            }

            // Find the section after and closest to the given distance
            int endIndex = 0;

            minDiff = double.MaxValue;
            for (int i = 0; i < distances.Count; i++)
            {
                double diff = distances[i] - distance;
                if (diff < 0)
                {
                    diff += curveLength;
                }
                if (diff < minDiff)
                {
                    minDiff  = diff;
                    endIndex = i;
                }
            }
            if (Math.Abs(minDiff) < LengthTolerance)
            {
                return(sections[endIndex]);
            }

            // Interpolate between start and end sections
            double startDistance = distances[startIndex];
            double endDistance   = distances[endIndex];

            if (startDistance > endDistance)
            {
                startDistance -= curveLength;
            }
            if (Math.Abs(endDistance - startDistance) < LengthTolerance)
            {
                return(sections[startIndex]);
            }

            double ratio = (distance - startDistance) / (endDistance - startDistance);

            return(ExcavationSection.Interpolate(sections[startIndex], sections[endIndex], ratio));
        }
Beispiel #4
0
 public void AddSection(double distance, ExcavationSection section)
 {
     distances.Add(distance);
     sections.Add(section);
 }
Beispiel #5
0
        protected static ExcavationSection ExcavateSlopeAtPoint(TriangleNet.Mesh surfaceMesh, ExcavationSection section, Point3d bottomPoint, Vector3d normal)
        {
            double            xyLen      = Math.Sqrt(normal.X * normal.X + normal.Y * normal.Y);
            ExcavationSection outSection = new ExcavationSection();

            foreach (ExcavationSectionElement inputelement in section.Elements)
            {
                ExcavationSectionElement element = (ExcavationSectionElement)inputelement.Clone();
                element.HasIntersection = false;
                element.HasTopPoint     = false;
                element.CurrentRatio    = double.MaxValue;
                element.BottomPoint     = bottomPoint;

                // Calculate 3D slope
                Vector3d slope = new Vector3d(normal.X / xyLen * element.H, normal.Y / xyLen * element.H, element.V);
                slope         = slope / slope.Length;
                element.Slope = slope;

                // Intersects slope vectors with surface triangles
                foreach (TriangleNet.Data.Triangle tri in surfaceMesh.Triangles)
                {
                    TriangleNet.Data.Vertex v1 = tri.GetVertex(0);
                    TriangleNet.Data.Vertex v2 = tri.GetVertex(1);
                    TriangleNet.Data.Vertex v3 = tri.GetVertex(2);

                    // Intersect the 3D ray from excavation bottom with the triangle
                    double  t;
                    Point3d topPoint;
                    bool    intersect = RayTriangleIntersection(bottomPoint, slope,
                                                                new Point3d(v1.X, v1.Y, v1.Attributes[0]), new Point3d(v2.X, v2.Y, v2.Attributes[0]), new Point3d(v3.X, v3.Y, v3.Attributes[0]),
                                                                out t, out topPoint);
                    double xyDist = double.MaxValue;
                    double zDist  = double.MaxValue;
                    if (intersect)
                    {
                        xyDist = new Vector3d(topPoint.X - bottomPoint.X, topPoint.Y - bottomPoint.Y, 0).Length;
                        zDist  = topPoint.Z - bottomPoint.Z;
                    }
                    if (!intersect ||
                        (element.HeightLimit > 0 && zDist > element.HeightLimit) ||
                        (element.LengthLimit > 0 && xyDist > element.LengthLimit))
                    {
                        t = double.MaxValue;
                    }
                    if (t < element.CurrentRatio)
                    {
                        element.CurrentRatio    = t;
                        element.TopPoint        = topPoint;
                        element.HasIntersection = true;
                    }
                }

                // Create the output section
                if (element.HasIntersection)
                {
                    // This element intersected the surface
                    // Add to output section and end calculation
                    element.HasTopPoint = true;
                    outSection.Elements.Add(element);
                    break;
                }
                else
                {
                    // No intersections
                    // Add to output section and continue calculation
                    // Calculate the top point for this element (bottom point for the next element)
                    if (element.HeightLimit > 0)
                    {
                        element.TopPoint    = element.BottomPoint + slope * element.HeightLimit / element.V;
                        element.HasTopPoint = true;
                    }
                    else if (element.LengthLimit > 0)
                    {
                        element.TopPoint    = element.BottomPoint + slope * element.LengthLimit / element.H;
                        element.HasTopPoint = true;
                    }
                    else
                    {
                        element.HasTopPoint = false;
                    }

                    outSection.Elements.Add(element);
                    bottomPoint = element.TopPoint;
                }
            }

            return(outSection);
        }
        public void TrenchExcavation()
        {
            if (!CheckLicense.Check())
            {
                return;
            }

            Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            Topography.SurfaceType surface = Topography.PickSurface();
            if (surface == Topography.SurfaceType.None)
            {
                return;
            }
            if (!Topography.EnsureSurfaceNotEmpty(surface))
            {
                return;
            }
            Topography topo = Topography.Instance;

            TriangleNet.Mesh mesh = (surface == Topography.SurfaceType.Original ? topo.OriginalTIN : topo.ProposedTIN);

            // Pick polyline
            bool     flag         = true;
            ObjectId centerlineId = ObjectId.Null;

            while (flag)
            {
                PromptEntityOptions entityOpts = new PromptEntityOptions("\nKazı tabanı [Seçenekler]:", "Settings");
                entityOpts.SetRejectMessage("\nSelect a curve.");
                entityOpts.AddAllowedClass(typeof(Curve), false);
                PromptEntityResult entityRes = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.GetEntity(entityOpts);
                if (entityRes.Status == PromptStatus.Keyword && entityRes.StringResult == "Settings")
                {
                    ShowSettings();
                    continue;
                }
                else if (entityRes.Status == PromptStatus.OK)
                {
                    centerlineId = entityRes.ObjectId;
                    break;
                }
                else
                {
                    return;
                }
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
                using (BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite))
                {
                    Curve centerline = tr.GetObject(centerlineId, OpenMode.ForRead) as Curve;

                    // Excavate
                    TrenchExcavation  ex    = new TrenchExcavation(mesh, centerline, Width, ExcavationStepSize);
                    ExcavationSection slope = new ExcavationSection();
                    slope.AddSlope(ExcavationH, ExcavationV);
                    ex.AddSection(0, slope);
                    ex.Excavate();

                    // Draw excavation boundries
                    Point3dCollection bottombounds = new Point3dCollection();
                    Point3dCollection topbounds    = new Point3dCollection();
                    bool closed = true;
                    bool alt    = false;
                    foreach (ExcavationSection section in ex.OutputSections)
                    {
                        if (section.Elements[section.Elements.Count - 1].HasTopPoint)
                        {
                            bottombounds.Add(section.Elements[0].BottomPoint);
                            topbounds.Add(section.Elements[section.Elements.Count - 1].TopPoint);

                            Point3d pt1 = section.Elements[0].BottomPoint;
                            Point3d pt2 = section.Elements[section.Elements.Count - 1].TopPoint;
                            if (alt)
                            {
                                pt1 = pt1 + (pt2 - pt1) / 2;
                            }
                            Line line = AcadUtility.AcadEntity.CreateLine(db, pt1, pt2);
                            line.ColorIndex = 11;
                            btr.AppendEntity(line);
                            tr.AddNewlyCreatedDBObject(line, true);
                        }
                        else
                        {
                            if (bottombounds.Count > 1)
                            {
                                Polyline3d pline = AcadUtility.AcadEntity.CreatePolyLine3d(db, bottombounds);
                                btr.AppendEntity(pline);
                                tr.AddNewlyCreatedDBObject(pline, true);
                            }
                            if (topbounds.Count > 1)
                            {
                                Polyline3d pline = AcadUtility.AcadEntity.CreatePolyLine3d(db, topbounds);
                                btr.AppendEntity(pline);
                                tr.AddNewlyCreatedDBObject(pline, true);
                            }

                            closed    = false;
                            topbounds = new Point3dCollection();
                        }

                        alt = !alt;
                    }
                    if (bottombounds.Count > 1)
                    {
                        Polyline3d pline = AcadUtility.AcadEntity.CreatePolyLine3d(db, bottombounds);
                        btr.AppendEntity(pline);
                        tr.AddNewlyCreatedDBObject(pline, true);
                    }
                    if (topbounds.Count > 1)
                    {
                        Polyline3d pline = AcadUtility.AcadEntity.CreatePolyLine3d(db, closed, topbounds);
                        btr.AppendEntity(pline);
                        tr.AddNewlyCreatedDBObject(pline, true);
                    }

                    tr.Commit();
                }
        }