Beispiel #1
0
        public static Solid CreateFromIntersectingPlanes(IEnumerable<Plane> planes, IDGenerator generator)
        {
            var solid = new Solid(generator.GetNextObjectID());
            var list = planes.ToList();
            for (var i = 0; i < list.Count; i++)
            {
                // Split the polygon by all the other planes
                var poly = new Polygon(list[i]);
                for (var j = 0; j < list.Count; j++)
                {
                    if (i != j) poly.Split(list[j]);
                }

                // The final polygon is the face
                var face = new Face(generator.GetNextFaceID()) { Plane = poly.Plane , Parent = solid };
                face.Vertices.AddRange(poly.Vertices.Select(x => new Vertex(x, face)));
                face.UpdateBoundingBox();
                face.AlignTextureToWorld();
                solid.Faces.Add(face);
            }

            // Ensure all the faces point outwards
            var origin = solid.GetOrigin();
            foreach (var face in solid.Faces)
            {
                if (face.Plane.OnPlane(origin) >= 0) face.Flip();
            }

            solid.UpdateBoundingBox();
            return solid;
        }
Beispiel #2
0
 public void BenchmarkSolidConstruction()
 {
     var idg = new IDGenerator();
     var box = new Box(Coordinate.One * -100, Coordinate.One * 100);
     var planes = new CylinderBrush().Create(idg, box, null, 2).OfType<Solid>().SelectMany(x => x.Faces).Select(x => x.Plane).ToList();
     var stopwatch = new Stopwatch();
     stopwatch.Start();
     for (var b = 0; b < 1000; b++)
     {
         Solid.CreateFromIntersectingPlanes(planes, idg);
     }
     stopwatch.Stop();
     Debug.WriteLine(stopwatch.Elapsed);
     stopwatch.Restart();
     for (var b = 0; b < 1000; b++)
     {
         var polys = new List<Polygon>();
         for (var i = 0; i < planes.Count; i++)
         {
             var poly = new Polygon(planes[i]);
             for (var j = 0; j < planes.Count; j++)
             {
                 if (i != j) poly.Split(planes[j]);
             }
             polys.Add(poly);
         }
         var solid = new Solid(idg.GetNextObjectID());
         foreach (var polygon in polys)
         {
             var face = new Face(idg.GetNextFaceID()) {Plane = polygon.Plane};
             face.Vertices.AddRange(polygon.Vertices.Select(x => new Vertex(x, face)));
             face.UpdateBoundingBox();
             face.AlignTextureToWorld();
             solid.Faces.Add(face);
         }
         solid.UpdateBoundingBox();
     }
     stopwatch.Stop();
     Debug.WriteLine(stopwatch.Elapsed);
 }
Beispiel #3
0
        private void Split(object sender)
        {
            var face = GetSplitFace();
            if (face == null) return;

            var solid = face.Parent;

            var sel = MainTool.Points.Where(x => x.IsSelected).ToList();
            var p1 = sel[0];
            var p2 = sel[1];

            if (p1.IsMidPoint) AddAdjacentPoint(face, p1);
            if (p2.IsMidPoint) AddAdjacentPoint(face, p2);

            var polygon = new Polygon(face.Vertices.Select(x => x.Location));
            var clip = new Plane(p1.Coordinate, p2.Coordinate, p1.Coordinate + face.Plane.Normal * 10);
            Polygon back, front;
            polygon.Split(clip, out back, out front);
            if (back == null || front == null) return;

            solid.Faces.Remove(face);
            face.Parent = null;

            CreateFace(back, solid, face);
            CreateFace(front, solid, face);

            solid.UpdateBoundingBox();

            MainTool.SetDirty(true, true);
        }
Beispiel #4
0
        private void Render3D(Viewport3D vp)
        {
            if (_state == ClipState.None
                || _clipPlanePoint1 == null
                || _clipPlanePoint2 == null
                || _clipPlanePoint3 == null
                || Document.Selection.IsEmpty()) return; // Nothing to draw at this point

            TextureHelper.Unbind();

            // Draw points

            if (!_clipPlanePoint1.EquivalentTo(_clipPlanePoint2)
                    && !_clipPlanePoint2.EquivalentTo(_clipPlanePoint3)
                    && !_clipPlanePoint1.EquivalentTo(_clipPlanePoint3))
            {
                var plane = new Plane(_clipPlanePoint1, _clipPlanePoint2, _clipPlanePoint3);

                // Draw clipped solids
                GL.Enable(EnableCap.LineSmooth);
                GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);

                var faces = new List<Face>();
                var idg = new IDGenerator();
                foreach (var solid in Document.Selection.GetSelectedObjects().OfType<Solid>().ToList())
                {
                    Solid back, front;
                    if (solid.Split(plane, out back, out front, idg))
                    {
                        if (_side != ClipSide.Front) faces.AddRange(back.Faces);
                        if (_side != ClipSide.Back) faces.AddRange(front.Faces);
                    }
                }
                GL.LineWidth(2);
                GL.Color3(Color.White);
                Rendering.Immediate.MapObjectRenderer.DrawWireframe(faces, true, false);
                GL.LineWidth(1);

                GL.Hint(HintTarget.LineSmoothHint, HintMode.Fastest);
                GL.Disable(EnableCap.LineSmooth);

                // Draw the clipping plane
                var poly = new Polygon(plane);
                var bbox = Document.Selection.GetSelectionBoundingBox();
                var point = bbox.Center;
                foreach (var boxPlane in bbox.GetBoxPlanes())
                {
                    var proj = boxPlane.Project(point);
                    var dist = (point - proj).VectorMagnitude() * 0.1m;
                    poly.Split(new Plane(boxPlane.Normal, proj + boxPlane.Normal * Math.Max(dist, 100)));
                }

                GL.Disable(EnableCap.CullFace);
                GL.Begin(PrimitiveType.Polygon);
                GL.Color4(Color.FromArgb(100, Color.Turquoise));
                foreach (var c in poly.Vertices) GL.Vertex3(c.DX, c.DY, c.DZ);
                GL.End();
                GL.Enable(EnableCap.CullFace);
            }
        }
Beispiel #5
0
 public void TestPolygonSplitting()
 {
     var planes = new[]
                      {
                          new Plane(new Coordinate(-64, 64, 64), new Coordinate(64, 64, 64), new Coordinate(64, -64, 64)),
                          new Plane(new Coordinate(-64, -64, -64), new Coordinate(64, -64, -64), new Coordinate(64, 64, -64)),
                          new Plane(new Coordinate(-64, 64, 64), new Coordinate(-64, -64, 64), new Coordinate(-64, -64, -64)),
                          new Plane(new Coordinate(64, 64, -64), new Coordinate(64, -64, -64), new Coordinate(64, -64, 64)),
                          new Plane(new Coordinate(64, 64, 64), new Coordinate(-64, 64, 64), new Coordinate(-64, 64, -64)),
                          new Plane(new Coordinate(64, -64, -64), new Coordinate(-64, -64, -64), new Coordinate(-64, -64, 64))
                      }.ToList();
     var polys = new List<Polygon>();
     for (var i = 0; i < planes.Count; i++)
     {
         var poly = new Polygon(planes[i]);
         for (var j = 0; j < planes.Count; j++)
         {
             if (i != j) poly.Split(planes[j]);
         }
         polys.Add(poly);
     }
     Assert.AreEqual(6, polys.Count);
 }