public void If_the_ray_does_not_point_at_the_AABB_the_result_is_false_and_the_distance_is_set_to_infinity()
        {
            var box = new AxisAlignedBoundingBox(new Point(1, 1, 1), new Point(2, 2, 2));
            var ray = new Ray(new Point(0.5, -1, 2), -Vector.UnitY);

            Assert.False(box.IntersectsRay(ray, 0, double.PositiveInfinity));
        }
        public void If_the_ray_points_at_the_AABB_the_result_is_true_and_the_distance_is_set_correctly()
        {
            var box = new AxisAlignedBoundingBox(new Point(0, 0, 0), new Point(2, 2, 2));
            var ray = new Ray(new Point(-1, 1, 1), new Vector(1, 0.1, 0.2).ToUnitVector());

            Assert.True(box.IntersectsRay(ray, 0, double.PositiveInfinity));
        }
Ejemplo n.º 3
0
        public BvhNode(IIntersectable left, IIntersectable right)
        {
            _left = left;
            _right = right;

            if (left != null) {
                _leftBounds = left.GetBoundingBox();
            }

            if (right != null) {
                _rightBounds = right.GetBoundingBox();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// TODO: This method is BUTT SLOW. For now it just loops over all of the triangles in the mesh and returns the closest intersection...
        /// </summary>
        public Intersection FindClosestIntersectionWith(Ray ray)
        {
            if (_boundingBox == null) {
                _boundingBox = GetBoundingBox();
            }

            if (!_boundingBox.IntersectsRay(ray, 0, double.PositiveInfinity)) {
                return null;
            }

            return Triangles
                .Select(triangle => triangle.FindClosestIntersectionWith(ray))
                .WhereNotNull()
                .OrderBy(intersection => intersection.Distance)
                .FirstOrDefault();
        }
        public void For_ray_directions_with_zeros_the_result_is_still_true_for_valid_intersections()
        {
            var box = new AxisAlignedBoundingBox(new Point(0, 0, 0), new Point(2, 2, 2));
            var ray = new Ray(new Point(-1, 1, 1), Vector.UnitX);

            Assert.True(box.IntersectsRay(ray, 0, double.PositiveInfinity));

            box = new AxisAlignedBoundingBox(new Point(0, 0, 0), new Point(2, 2, 2));
            ray = new Ray(new Point(1, -1, 1), Vector.UnitY);

            Assert.True(box.IntersectsRay(ray, 0, double.PositiveInfinity));

            box = new AxisAlignedBoundingBox(new Point(0, 0, 0), new Point(2, 2, 2));
            ray = new Ray(new Point(1, 1, -1), Vector.UnitZ);

            Assert.True(box.IntersectsRay(ray, 0, double.PositiveInfinity));
        }
Ejemplo n.º 6
0
        private static Mesh CreateHullMesh(Mesh mesh)
        {
            var bounds = AxisAlignedBoundingBox.Empty();
            // Get the convex hull for the mesh
            var cHVertexList = new List <CHVertex>();

            foreach (var position in mesh.Vertices.Distinct().ToArray())
            {
                cHVertexList.Add(new CHVertex(position));
                bounds.ExpandToInclude(position);
            }

            var tollerance = .01;

            if (cHVertexList.Count == 0 ||
                bounds.XSize <= tollerance ||
                bounds.YSize <= tollerance ||
                bounds.ZSize <= tollerance ||
                double.IsNaN(cHVertexList.First().Position[0]))
            {
                return(mesh);
            }

            var convexHull = ConvexHull <CHVertex, CHFace> .Create(cHVertexList, tollerance);

            if (convexHull != null)
            {
                // create the mesh from the hull data
                Mesh hullMesh = new Mesh();
                foreach (var face in convexHull.Faces)
                {
                    int vertexCount = hullMesh.Vertices.Count;

                    foreach (var vertex in face.Vertices)
                    {
                        hullMesh.Vertices.Add(new Vector3(vertex.Position[0], vertex.Position[1], vertex.Position[2]));
                    }

                    hullMesh.Faces.Add(vertexCount, vertexCount + 1, vertexCount + 2, hullMesh.Vertices);
                }

                try
                {
                    // make sure there is not currently a convex hull on this object
                    if (mesh.PropertyBag.ContainsKey(ConvexHullMesh))
                    {
                        mesh.PropertyBag.Remove(ConvexHullMesh);
                    }

                    // add the new hull
                    mesh.PropertyBag.Add(ConvexHullMesh, hullMesh);
                    // make sure we remove this hull if the mesh changes
                    mesh.Changed += MeshChanged_RemoveConvexHull;

                    // remove the marker that says we are building the hull
                    if (mesh.PropertyBag.ContainsKey(CreatingConvexHullMesh))
                    {
                        mesh.PropertyBag.Remove(CreatingConvexHullMesh);
                    }

                    return(hullMesh);
                }
                catch
                {
                }
            }

            return(null);
        }
Ejemplo n.º 7
0
 public MoveTo(AxisAlignedBoundingBox nCurrentAABB, AxisAlignedBoundingBox nDesiredAABB)
 {
     currentAABB = nCurrentAABB;
     desiredAABB = nDesiredAABB;
     type        = Type.MoveTo;
 }
Ejemplo n.º 8
0
        public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox()
        {
            AxisAlignedBoundingBox childBounds = objectToTransform.GetAxisAlignedBoundingBox();

            return(childBounds.NewTransformed(transform));
        }
Ejemplo n.º 9
0
        public override List <WidgetAndPosition> FindDescendants(IEnumerable <string> namesToSearchFor, List <WidgetAndPosition> foundChildren, RectangleDouble touchingBounds, SearchType seachType, bool allowInvalidItems = true)
        {
            foreach (Object3DControl child in this.Object3DControls)
            {
                string object3DName = child.Name;

                bool nameFound = false;

                foreach (var nameToSearchFor in namesToSearchFor)
                {
                    if (seachType == SearchType.Exact)
                    {
                        if (object3DName == nameToSearchFor)
                        {
                            nameFound = true;
                            break;
                        }
                    }
                    else
                    {
                        if (nameToSearchFor == "" ||
                            object3DName.Contains(nameToSearchFor))
                        {
                            nameFound = true;
                            break;
                        }
                    }
                }

                if (nameFound &&
                    child.CollisionVolume != null)
                {
                    AxisAlignedBoundingBox bounds = child.CollisionVolume.GetAxisAlignedBoundingBox();
                    bounds = bounds.NewTransformed(child.TotalTransform);

                    RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
                    for (int i = 0; i < 4; i++)
                    {
                        screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i)));
                        screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i)));
                    }

                    if (touchingBounds.IsTouching(screenBoundsOfObject3D))
                    {
                        Vector3 renderPosition           = bounds.Center;
                        Vector2 objectCenterScreenSpace  = this.World.GetScreenPosition(renderPosition);
                        var     screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);

                        foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
                    }
                }
            }

            foreach (var child in scene.Children)
            {
                string object3DName = child.Name;
                if (object3DName == null && child.MeshPath != null)
                {
                    object3DName = Path.GetFileName(child.MeshPath);
                }

                bool nameFound = false;

                foreach (var nameToSearchFor in namesToSearchFor)
                {
                    if (seachType == SearchType.Exact)
                    {
                        if (object3DName == nameToSearchFor)
                        {
                            nameFound = true;
                            break;
                        }
                    }
                    else
                    {
                        if (nameToSearchFor == "" ||
                            object3DName.Contains(nameToSearchFor))
                        {
                            nameFound = true;
                            break;
                        }
                    }
                }

                if (nameFound)
                {
                    AxisAlignedBoundingBox bounds = child.GetBVHData().GetAxisAlignedBoundingBox();

                    RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
                    for (int i = 0; i < 4; i++)
                    {
                        screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i)));
                        screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i)));
                    }

                    if (touchingBounds.IsTouching(screenBoundsOfObject3D))
                    {
                        Vector3 renderPosition           = bounds.Center;
                        Vector2 objectCenterScreenSpace  = this.World.GetScreenPosition(renderPosition);
                        var     screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);

                        foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
                    }
                }
            }

            return(base.FindDescendants(namesToSearchFor, foundChildren, touchingBounds, seachType, allowInvalidItems));
        }
Ejemplo n.º 10
0
 public ActorAtmosphere()
 {
     Mesh        = new MeshSphere((float)(SgpConstants.EarthRadiusKm / 100 + 0.7), 96, 48);
     BoundingBox = new AxisAlignedBoundingBox(new Vector3(140, 140, 140), Vector3.Zero, true);
     _shader     = new ShaderProgram(ShaderBank.AtmosphereFrag, ShaderBank.AtmosphereVert);
 }
Ejemplo n.º 11
0
        public MoveInZControl(IObject3DControlContext context)
            : base(context)
        {
            theme = AppContext.Theme;
            Name  = "MoveInZControl";
            zHeightDisplayInfo = new InlineEditControl()
            {
                ForceHide = () =>
                {
                    var selectedItem = RootSelection;
                    // if the selection changes
                    if (selectedItem != ActiveSelectedItem)
                    {
                        return(true);
                    }

                    // if another control gets a hover
                    if (Object3DControlContext.HoveredObject3DControl != this &&
                        Object3DControlContext.HoveredObject3DControl != null)
                    {
                        return(true);
                    }

                    // if we clicked on the control
                    if (hadClickOnControl)
                    {
                        return(false);
                    }

                    return(false);
                },
                GetDisplayString = (value) => "{0:0.0#}".FormatWith(value)
            };

            zHeightDisplayInfo.VisibleChanged += (s, e) =>
            {
                if (!zHeightDisplayInfo.Visible)
                {
                    hadClickOnControl = false;
                }
            };

            zHeightDisplayInfo.EditComplete += (s, e) =>
            {
                var selectedItem = RootSelection;

                Matrix4X4 startingTransform = selectedItem.Matrix;

                var newZPosition = zHeightDisplayInfo.Value;

                if (Object3DControlContext.SnapGridDistance > 0)
                {
                    // snap this position to the grid
                    double snapGridDistance = Object3DControlContext.SnapGridDistance;

                    // snap this position to the grid
                    newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance;
                }

                AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                var moveAmount = newZPosition - originalSelectedBounds.MinXYZ.Z;

                if (moveAmount != 0)
                {
                    selectedItem.Matrix *= Matrix4X4.CreateTranslation(0, 0, moveAmount);
                    Invalidate();
                }

                context.Scene.AddTransformSnapshot(startingTransform);
            };

            Object3DControlContext.GuiSurface.AddChild(zHeightDisplayInfo);

            DrawOnTop = true;

            using (Stream arrowStream = StaticData.Instance.OpenStream(Path.Combine("Stls", "up_pointer.stl")))
            {
                upArrowMesh = StlProcessing.Load(arrowStream, CancellationToken.None);
            }

            CollisionVolume = upArrowMesh.CreateBVHData();

            Object3DControlContext.GuiSurface.BeforeDraw += Object3DControl_BeforeDraw;
        }
Ejemplo n.º 12
0
        public ScaleMatrixTopControl(IObject3DControlContext context)
            : base(context)
        {
            theme = AppContext.Theme;

            zValueDisplayInfo = new InlineEditControl()
            {
                ForceHide = () =>
                {
                    // if the selection changes
                    if (RootSelection != activeSelectedItem)
                    {
                        return(true);
                    }

                    // if another control gets a hover
                    if (Object3DControlContext.HoveredObject3DControl != this &&
                        Object3DControlContext.HoveredObject3DControl != null)
                    {
                        return(true);
                    }

                    // if we clicked on the control
                    if (hadClickOnControl)
                    {
                        return(false);
                    }

                    return(false);
                },
                GetDisplayString = (value) => "{0:0.0}".FormatWith(value)
            };

            zValueDisplayInfo.VisibleChanged += (s, e) =>
            {
                if (!zValueDisplayInfo.Visible)
                {
                    hadClickOnControl = false;
                }
            };

            zValueDisplayInfo.EditComplete += (s, e) =>
            {
                var selectedItem = activeSelectedItem;

                Matrix4X4 startingTransform      = selectedItem.Matrix;
                var       originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                Vector3   topPosition            = GetTopPosition(selectedItem);
                var       lockedBottom           = new Vector3(topPosition.X, topPosition.Y, originalSelectedBounds.MinXYZ.Z);

                Vector3 newSize = Vector3.Zero;
                newSize.Z = zValueDisplayInfo.Value;
                Vector3 scaleAmount = ScaleCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, Object3DControlContext.GuiSurface.ModifierKeys);

                var scale = Matrix4X4.CreateScale(scaleAmount);

                selectedItem.Matrix = selectedItem.ApplyAtBoundsCenter(scale);

                // and keep the locked edge in place
                AxisAlignedBoundingBox scaledSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                var newLockedBottom = new Vector3(topPosition.X, topPosition.Y, scaledSelectedBounds.MinXYZ.Z);

                selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedBottom - newLockedBottom);

                Invalidate();

                Object3DControlContext.Scene.AddTransformSnapshot(startingTransform);
            };

            Object3DControlContext.GuiSurface.AddChild(zValueDisplayInfo);

            DrawOnTop = true;

            topScaleMesh = PlatonicSolids.CreateCube(arrowSize, arrowSize, arrowSize);

            CollisionVolume = topScaleMesh.CreateBVHData();

            Object3DControlContext.GuiSurface.BeforeDraw += Object3DControl_BeforeDraw;
        }
Ejemplo n.º 13
0
        public MoveInZControl(IInteractionVolumeContext context)
            : base(context)
        {
            Name = "MoveInZControl";
            zHeightDisplayInfo = new InlineEditControl()
            {
                ForceHide = () =>
                {
                    var selectedItem = InteractionContext.Scene.RootSelectedItem;
                    // if the selection changes
                    if (selectedItem != ActiveSelectedItem)
                    {
                        return(true);
                    }

                    // if another control gets a hover
                    if (InteractionContext.HoveredInteractionVolume != this &&
                        InteractionContext.HoveredInteractionVolume != null)
                    {
                        return(true);
                    }

                    // if we clicked on the control
                    if (HadClickOnControl)
                    {
                        return(false);
                    }

                    return(false);
                }
                ,
                GetDisplayString = (value) => "{0:0.0#}mm".FormatWith(value)
            };

            zHeightDisplayInfo.VisibleChanged += (s, e) =>
            {
                if (!zHeightDisplayInfo.Visible)
                {
                    HadClickOnControl = false;
                }
            };

            zHeightDisplayInfo.EditComplete += (s, e) =>
            {
                var selectedItem = InteractionContext.Scene.RootSelectedItem;

                Matrix4X4 startingTransform = selectedItem.Matrix;

                var newZPosition = zHeightDisplayInfo.Value;

                if (InteractionContext.SnapGridDistance > 0)
                {
                    // snap this position to the grid
                    double snapGridDistance = InteractionContext.SnapGridDistance;

                    // snap this position to the grid
                    newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance;
                }

                AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity);
                var moveAmount = newZPosition - originalSelectedBounds.minXYZ.Z;

                if (moveAmount != 0)
                {
                    selectedItem.Matrix = selectedItem.Matrix * Matrix4X4.CreateTranslation(0, 0, moveAmount);
                    Invalidate();
                }

                context.AddTransformSnapshot(startingTransform);
            };

            InteractionContext.GuiSurface.AddChild(zHeightDisplayInfo);

            DrawOnTop = true;

            string arrowFile = Path.Combine("Icons", "3D Icons", "up_pointer.stl");

            using (Stream arrowStream = AggContext.StaticData.OpenStream(arrowFile))
            {
                upArrowMesh = MeshFileIo.Load(arrowStream, Path.GetExtension(arrowFile), CancellationToken.None).Mesh;
            }

            CollisionVolume = upArrowMesh.CreateTraceData();

            InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw;
        }
Ejemplo n.º 14
0
        public override void SetPosition()
        {
            if (MeshViewerToDrawWith.HaveSelection)
            {
                // draw the hight from the bottom to the bed
                AxisAlignedBoundingBox selectedBounds = MeshViewerToDrawWith.GetBoundsForSelection();

                MeshSelectInfo meshSelectInfo = view3DWidget.CurrentSelectInfo;

                switch (meshSelectInfo.HitQuadrant)
                {
                case HitQuadrant.LB:
                {
                    Vector3 cornerPoint = new Vector3(selectedBounds.minXYZ.x, selectedBounds.minXYZ.y, 0);
                    double  distBetweenPixelsWorldSpace = MeshViewerToDrawWith.TrackballTumbleWidget.GetWorldUnitsPerScreenPixelAtPosition(cornerPoint);

                    lines[0] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0));
                    lines[1] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3((distToStart + lineLength) * distBetweenPixelsWorldSpace, 0, 0));

                    lines[2] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3(0, distToStart * distBetweenPixelsWorldSpace, 0));
                    lines[3] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3(0, (distToStart + lineLength) * distBetweenPixelsWorldSpace, 0));
                }
                break;

                case HitQuadrant.LT:
                {
                    Vector3 cornerPoint = new Vector3(selectedBounds.minXYZ.x, selectedBounds.maxXYZ.y, 0);
                    double  distBetweenPixelsWorldSpace = MeshViewerToDrawWith.TrackballTumbleWidget.GetWorldUnitsPerScreenPixelAtPosition(cornerPoint);

                    lines[0] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0));
                    lines[1] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3((distToStart + lineLength) * distBetweenPixelsWorldSpace, 0, 0));

                    lines[2] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3(0, distToStart * distBetweenPixelsWorldSpace, 0));
                    lines[3] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3(0, (distToStart + lineLength) * distBetweenPixelsWorldSpace, 0));
                }
                break;

                case HitQuadrant.RB:
                {
                    Vector3 cornerPoint = new Vector3(selectedBounds.maxXYZ.x, selectedBounds.minXYZ.y, 0);
                    double  distBetweenPixelsWorldSpace = MeshViewerToDrawWith.TrackballTumbleWidget.GetWorldUnitsPerScreenPixelAtPosition(cornerPoint);

                    lines[0] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0));
                    lines[1] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3((distToStart + lineLength) * distBetweenPixelsWorldSpace, 0, 0));

                    lines[2] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3(0, distToStart * distBetweenPixelsWorldSpace, 0));
                    lines[3] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint - new Vector3(0, (distToStart + lineLength) * distBetweenPixelsWorldSpace, 0));
                }
                break;

                case HitQuadrant.RT:
                {
                    Vector3 cornerPoint = new Vector3(selectedBounds.maxXYZ.x, selectedBounds.maxXYZ.y, 0);
                    double  distBetweenPixelsWorldSpace = MeshViewerToDrawWith.TrackballTumbleWidget.GetWorldUnitsPerScreenPixelAtPosition(cornerPoint);

                    lines[0] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0));
                    lines[1] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3((distToStart + lineLength) * distBetweenPixelsWorldSpace, 0, 0));

                    lines[2] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3(0, distToStart * distBetweenPixelsWorldSpace, 0));
                    lines[3] = MeshViewerToDrawWith.TrackballTumbleWidget.GetScreenPosition(cornerPoint + new Vector3(0, (distToStart + lineLength) * distBetweenPixelsWorldSpace, 0));
                }
                break;
                }
            }
        }
        public static Mesh[] SplitIntoMeshesOnOrthographicZ(Mesh meshToSplit, Vector3 buildVolume, BackgroundWorker backgroundWorker, int startPercent, int endPercent)
        {
            int lengthPercent = endPercent - startPercent;
            // check if the part is bigger than the build plate (if it is we need to use that as our size)
            AxisAlignedBoundingBox partBounds = meshToSplit.GetAxisAlignedBoundingBox();

            buildVolume.x = Math.Max(buildVolume.x, partBounds.XSize + 2);
            buildVolume.y = Math.Max(buildVolume.y, partBounds.YSize + 2);
            buildVolume.z = Math.Max(buildVolume.z, partBounds.ZSize + 2);

            // Find all the separate objects that are on the plate
            // Create a 2D image the size of the printer bed at some scale with the parts draw on it top down

            double      scaleFactor  = 5;
            ImageBuffer partPlate    = new ImageBuffer((int)(buildVolume.x * scaleFactor), (int)(buildVolume.y * scaleFactor), 32, new BlenderBGRA());
            Vector2     renderOffset = new Vector2(buildVolume.x / 2, buildVolume.y / 2) - new Vector2(partBounds.Center.x, partBounds.Center.y);

            PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partPlate.NewGraphics2D(), meshToSplit, renderOffset, scaleFactor, RGBA_Bytes.White);

            if (backgroundWorker != null)
            {
                backgroundWorker.ReportProgress(startPercent + (int)(lengthPercent * .2));
            }

            //ImageIO.SaveImageData("test part plate 0.png", partPlate);
            // expand the bounds a bit so that we can collect all the vertices and polygons within each bound
            Dilate.DoDilate3x3Binary(partPlate, 1);
            //ImageIO.SaveImageData("test part plate 1.png", partPlate);

            // trace all the bounds of the objects on the plate
            PolyTree polyTreeForPlate = FindDistictObjectBounds(partPlate);

            if (polyTreeForPlate == null)
            {
                Mesh[] singleMesh = new Mesh[1];
                singleMesh[0] = meshToSplit;
                return(singleMesh);
            }

            // get all the discrete areas that are polygons so we can search them
            Polygons discreteAreas = new Polygons();

            GetAreasRecursive(polyTreeForPlate, discreteAreas);
            if (discreteAreas.Count == 0)
            {
                return(null);
            }
            else if (discreteAreas.Count == 1)
            {
                Mesh[] singleMesh = new Mesh[1];
                singleMesh[0] = meshToSplit;
                return(singleMesh);
            }

            Graphics2D graphics2D = partPlate.NewGraphics2D();

            graphics2D.Clear(RGBA_Bytes.Black);
            Random rand = new Random();

            foreach (Polygon polygon in discreteAreas)
            {
                graphics2D.Render(PlatingHelper.PolygonToPathStorage(polygon), new RGBA_Bytes(rand.Next(128, 255), rand.Next(128, 255), rand.Next(128, 255)));
            }
            if (backgroundWorker != null)
            {
                backgroundWorker.ReportProgress(startPercent + (int)(lengthPercent * .50));
            }
            //ImageIO.SaveImageData("test part plate 2.png", partPlate);

            // add each of the separate bounds polygons to new meshes
            Mesh[] discreteMeshes = new Mesh[discreteAreas.Count];
            for (int i = 0; i < discreteAreas.Count; i++)
            {
                discreteMeshes[i] = new Mesh();
            }

            foreach (Face face in meshToSplit.Faces)
            {
                bool faceDone = false;
                // figure out which area one or more of the vertices are in add the face to the right new mesh
                foreach (FaceEdge faceEdge in face.FaceEdges())
                {
                    Vector2 position = new Vector2(faceEdge.firstVertex.Position.x, faceEdge.firstVertex.Position.y);
                    position += renderOffset;
                    position *= scaleFactor;

                    for (int areaIndex = discreteAreas.Count - 1; areaIndex >= 0; areaIndex--)
                    {
                        if (PointInPolygon(discreteAreas[areaIndex], new IntPoint((int)position.x, (int)position.y)))
                        {
                            List <Vertex> faceVertices = new List <Vertex>();
                            foreach (FaceEdge faceEdgeToAdd in face.FaceEdges())
                            {
                                Vertex newVertex = discreteMeshes[areaIndex].CreateVertex(faceEdgeToAdd.firstVertex.Position);
                                faceVertices.Add(newVertex);
                            }

                            discreteMeshes[areaIndex].CreateFace(faceVertices.ToArray());
                            faceDone = true;
                            break;
                        }
                    }

                    if (faceDone)
                    {
                        break;
                    }
                }
            }

            if (backgroundWorker != null)
            {
                backgroundWorker.ReportProgress(startPercent + (int)(lengthPercent));
            }

            for (int i = 0; i < discreteMeshes.Count(); i++)
            {
                Mesh mesh = discreteMeshes[i];
            }

            return(discreteMeshes);
        }
Ejemplo n.º 16
0
        public Task Create(IProgress <ProgressStatus> progress, CancellationToken cancellationToken)
        {
            var selectedItem = scene.SelectedItem;

            using (new SelectionMaintainer(scene))
            {
                var status = new ProgressStatus
                {
                    Status = "Enter"
                };
                progress?.Report(status);

                // Get visible meshes for each of them
                var allBedItems = scene.Children.SelectMany(i => i.VisibleMeshes());

                var suppoortBounds = AxisAlignedBoundingBox.Empty();
                if (selectedItem != null)
                {
                    foreach (var candidate in selectedItem.VisibleMeshes())
                    {
                        suppoortBounds += candidate.GetAxisAlignedBoundingBox(candidate.Matrix.Inverted * candidate.WorldMatrix());
                    }
                }
                else
                {
                    foreach (var candidate in allBedItems)
                    {
                        suppoortBounds += candidate.GetAxisAlignedBoundingBox(candidate.Matrix.Inverted * candidate.WorldMatrix());
                    }
                }

                // create the gird of possible support
                var gridBounds = new RectangleDouble(Math.Floor((double)(suppoortBounds.MinXYZ.X / PillarSize)),
                                                     Math.Floor((double)(suppoortBounds.MinXYZ.Y / PillarSize)),
                                                     Math.Ceiling(suppoortBounds.MaxXYZ.X / PillarSize),
                                                     Math.Ceiling(suppoortBounds.MaxXYZ.Y / PillarSize));

                var partBounds = new RectangleDouble(gridBounds.Left * PillarSize,
                                                     gridBounds.Bottom * PillarSize,
                                                     gridBounds.Right * PillarSize,
                                                     gridBounds.Top * PillarSize);

                int gridWidth   = (int)gridBounds.Width;
                int gridHeight  = (int)gridBounds.Height;
                var supportGrid = new List <List <List <(bool isBottom, double z)> > >();

                for (int x = 0; x < gridWidth; x++)
                {
                    supportGrid.Add(new List <List <(bool, double)> >());
                    for (int y = 0; y < gridHeight; y++)
                    {
                        supportGrid[x].Add(new List <(bool, double)>());
                    }
                }

                // get all the support plane intersections
                status.Status = "Trace";
                progress?.Report(status);
                var detectedPlanes = DetectRequiredSupportByTracing(gridBounds, allBedItems);

                status.Status = "Columns";
                progress?.Report(status);

                // minimum height requiring support is 1/2 the layer height
                AddSupportColumns(gridBounds, detectedPlanes);

                // this is the theory for regions rather than pillars
                // separate the faces into face patch groups (these are the new support tops)
                // project all the vertices of each patch group down until they hit an up face in the scene (or 0)
                // make a new patch group at the z of the hit (these will be the bottoms)
                // find the outline of the patch groups (these will be the walls of the top and bottom patches
                // make a new mesh object with the top, bottom and walls, add it to the scene and mark it as support

                return(Task.CompletedTask);
            }
        }
Ejemplo n.º 17
0
        public static void MakeLowestFaceFlat(this InteractiveScene scene, IObject3D objectToLayFlatGroup)
        {
            var preLayFlatMatrix = objectToLayFlatGroup.Matrix;

            bool firstVertex = true;

            IObject3D objectToLayFlat = objectToLayFlatGroup;

            Vector3Float lowestPosition       = Vector3Float.PositiveInfinity;
            Vector3Float sourceVertexPosition = Vector3Float.NegativeInfinity;
            IObject3D    itemToLayFlat        = null;
            Mesh         meshWithLowest       = null;

            var items = objectToLayFlat.VisibleMeshes().Where(i => i.OutputType != PrintOutputTypes.Support);

            if (!items.Any())
            {
                items = objectToLayFlat.VisibleMeshes();
            }

            // Process each child, checking for the lowest vertex
            foreach (var itemToCheck in items)
            {
                var meshToCheck = itemToCheck.Mesh.GetConvexHull(false);

                if (meshToCheck == null &&
                    meshToCheck.Vertices.Count < 3)
                {
                    continue;
                }

                // find the lowest point on the model
                for (int testIndex = 0; testIndex < meshToCheck.Vertices.Count; testIndex++)
                {
                    var vertex         = meshToCheck.Vertices[testIndex];
                    var vertexPosition = vertex.Transform(itemToCheck.WorldMatrix());
                    if (firstVertex)
                    {
                        meshWithLowest       = meshToCheck;
                        lowestPosition       = vertexPosition;
                        sourceVertexPosition = vertex;
                        itemToLayFlat        = itemToCheck;
                        firstVertex          = false;
                    }
                    else if (vertexPosition.Z < lowestPosition.Z)
                    {
                        meshWithLowest       = meshToCheck;
                        lowestPosition       = vertexPosition;
                        sourceVertexPosition = vertex;
                        itemToLayFlat        = itemToCheck;
                    }
                }
            }

            if (meshWithLowest == null)
            {
                // didn't find any selected mesh
                return;
            }

            int    faceToLayFlat            = -1;
            double largestAreaOfAnyFace     = 0;
            var    facesSharingLowestVertex = meshWithLowest.Faces
                                              .Select((face, i) => new { face, i })
                                              .Where(faceAndIndex => meshWithLowest.Vertices[faceAndIndex.face.v0] == sourceVertexPosition ||
                                                     meshWithLowest.Vertices[faceAndIndex.face.v1] == sourceVertexPosition ||
                                                     meshWithLowest.Vertices[faceAndIndex.face.v2] == sourceVertexPosition)
                                              .Select(j => j.i);

            var lowestFacesByAngle = facesSharingLowestVertex.OrderBy(i =>
            {
                var face        = meshWithLowest.Faces[i];
                var worldNormal = face.normal.TransformNormal(itemToLayFlat.WorldMatrix());
                return(worldNormal.CalculateAngle(-Vector3Float.UnitZ));
            });

            // Check all the faces that are connected to the lowest point to find out which one to lay flat.
            foreach (var faceIndex in lowestFacesByAngle)
            {
                var face = meshWithLowest.Faces[faceIndex];

                var worldNormal       = face.normal.TransformNormal(itemToLayFlat.WorldMatrix());
                var worldAngleDegrees = MathHelper.RadiansToDegrees(worldNormal.CalculateAngle(-Vector3Float.UnitZ));

                double largestAreaFound   = 0;
                var    faceVeretexIndices = new int[] { face.v0, face.v1, face.v2 };

                foreach (var vi in faceVeretexIndices)
                {
                    if (meshWithLowest.Vertices[vi] != lowestPosition)
                    {
                        var planSurfaceArea = 0.0;
                        foreach (var coPlanarFace in meshWithLowest.GetCoplanerFaces(faceIndex))
                        {
                            planSurfaceArea += meshWithLowest.GetSurfaceArea(coPlanarFace);
                        }

                        if (largestAreaOfAnyFace == 0 ||
                            (planSurfaceArea > largestAreaFound &&
                             worldAngleDegrees < 45))
                        {
                            largestAreaFound = planSurfaceArea;
                        }
                    }
                }
                if (largestAreaFound > largestAreaOfAnyFace)
                {
                    largestAreaOfAnyFace = largestAreaFound;
                    faceToLayFlat        = faceIndex;
                }
            }

            double maxDistFromLowestZ = 0;
            var    lowestFace         = meshWithLowest.Faces[faceToLayFlat];
            var    lowestFaceIndices  = new int[] { lowestFace.v0, lowestFace.v1, lowestFace.v2 };
            var    faceVertices       = new List <Vector3Float>();

            foreach (var vertex in lowestFaceIndices)
            {
                var vertexPosition = meshWithLowest.Vertices[vertex].Transform(itemToLayFlat.WorldMatrix());
                faceVertices.Add(vertexPosition);
                maxDistFromLowestZ = Math.Max(maxDistFromLowestZ, vertexPosition.Z - lowestPosition.Z);
            }

            if (maxDistFromLowestZ > .001)
            {
                var xPositive   = (faceVertices[1] - faceVertices[0]).GetNormal();
                var yPositive   = (faceVertices[2] - faceVertices[0]).GetNormal();
                var planeNormal = xPositive.Cross(yPositive).GetNormal();

                // this code takes the minimum rotation required and looks much better.
                Quaternion rotation        = new Quaternion(planeNormal, new Vector3Float(0, 0, -1));
                Matrix4X4  partLevelMatrix = Matrix4X4.CreateRotation(rotation);

                // rotate it
                objectToLayFlat.Matrix = objectToLayFlatGroup.ApplyAtBoundsCenter(partLevelMatrix);
            }

            if (objectToLayFlatGroup is Object3D object3D)
            {
                AxisAlignedBoundingBox bounds = object3D.GetAxisAlignedBoundingBox(Matrix4X4.Identity, (item) =>
                {
                    return(item.OutputType != PrintOutputTypes.Support);
                });
                Vector3 boundsCenter = (bounds.MaxXYZ + bounds.MinXYZ) / 2;

                object3D.Matrix *= Matrix4X4.CreateTranslation(new Vector3(0, 0, -boundsCenter.Z + bounds.ZSize / 2));
            }
            else
            {
                PlatingHelper.PlaceOnBed(objectToLayFlatGroup);
            }

            scene.UndoBuffer.Add(new TransformCommand(objectToLayFlatGroup, preLayFlatMatrix, objectToLayFlatGroup.Matrix));
        }
Ejemplo n.º 18
0
        public void FrustumIntersetAABBTests()
        {
            {
                Frustum frustum = new Frustum(
                    new Plane(new Vector3(1, 0, 0), 20),
                    new Plane(new Vector3(-1, 0, 0), 20),
                    new Plane(new Vector3(0, 1, 0), 20),
                    new Plane(new Vector3(0, -1, 0), 20),
                    new Plane(new Vector3(0, 0, 1), 20),
                    new Plane(new Vector3(0, 0, -1), 20));

                // outside to left
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-30, -10, -10), new Vector3(-25, 10, 10));
                    FrustumIntersection    intersection = frustum.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Outside);
                }

                // intersect
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-25, 0, -10), new Vector3(-15, 10, 10));
                    FrustumIntersection    intersection = frustum.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Intersect);
                }

                // not intersect
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-25, 0, 30), new Vector3(-15, 10, 35));
                    FrustumIntersection    intersection = frustum.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Outside);
                }

                // inside
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
                    FrustumIntersection    intersection = frustum.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Inside);
                }
            }

            {
                Frustum frustum = new Frustum(
                    new Plane(new Vector3(-1, -1, 0), 0),
                    new Plane(new Vector3(1, -1, 0), 0),
                    new Plane(new Vector3(0, -1, -1), 0),
                    new Plane(new Vector3(0, -1, 1), 0),
                    new Plane(new Vector3(0, -1, 0), 0),
                    new Plane(new Vector3(0, 1, 0), 10000));

                // outside to left
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-110, 0, -10), new Vector3(-100, 10, 10));
                    FrustumIntersection    intersection = frustum.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Outside);
                }

                // intersect with origin (front)
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10));
                    FrustumIntersection    intersection = frustum.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Intersect);
                }

                // inside
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-5, 100, -5), new Vector3(5, 110, 5));
                    FrustumIntersection    intersection = frustum.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Inside);
                }
            }

            {
                // looking down -z
                Frustum frustum5PlaneNegZ = new Frustum(
                    new Vector3(-1, 0, 1),
                    new Vector3(-1, 0, 1),
                    new Vector3(0, 1, 1),
                    new Vector3(0, -1, 1),
                    new Vector3(0, 0, -1), 10000);

                // outside to left
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-110, 0, -10), new Vector3(-100, 10, 10));
                    FrustumIntersection    intersection = frustum5PlaneNegZ.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Outside);
                }

                // intersect with origin (front)
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-10, -10, -10), new Vector3(10, 10, 10));
                    FrustumIntersection    intersection = frustum5PlaneNegZ.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Intersect);
                }

                // inside
                {
                    AxisAlignedBoundingBox aabb         = new AxisAlignedBoundingBox(new Vector3(-5, -5, -110), new Vector3(5, 5, -100));
                    FrustumIntersection    intersection = frustum5PlaneNegZ.GetIntersect(aabb);
                    Assert.IsTrue(intersection == FrustumIntersection.Inside);
                }
            }
        }
Ejemplo n.º 19
0
        public Vector3 GetTopPosition(IObject3D selectedItem)
        {
            AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();

            return(new Vector3(originalSelectedBounds.Center.X, originalSelectedBounds.Center.Y, originalSelectedBounds.MaxXYZ.Z));
        }
Ejemplo n.º 20
0
        public static IBoundedItem CreateNewHierachy(List <IBoundedItem> traceableItems, int maxRecursion = int.MaxValue, int recursionDepth = 0, SortingAccelerator accelerator = null)
        {
            if (accelerator == null)
            {
                accelerator = new SortingAccelerator();
            }

            int numItems = traceableItems.Count;

            if (numItems == 0)
            {
                return(null);
            }

            if (numItems == 1)
            {
                return(traceableItems[0]);
            }

            int bestAxis                    = -1;
            int bestIndexToSplitOn          = -1;
            CompareCentersOnAxis axisSorter = new CompareCentersOnAxis(0);

            if (recursionDepth < maxRecursion)
            {
                if (numItems > 5000)
                {
                    bestAxis           = accelerator.NextAxis;
                    bestIndexToSplitOn = numItems / 2;
                }
                else
                {
                    double totalIntersectCost = 0;
                    int    skipInterval       = 1;
                    for (int i = 0; i < numItems; i += skipInterval)
                    {
                        IBoundedItem item = traceableItems[i];
                        totalIntersectCost += item.GetIntersectCost();
                    }

                    // get the bounding box of all the items we are going to consider.
                    AxisAlignedBoundingBox OverallBox = traceableItems[0].GetAxisAlignedBoundingBox();
                    for (int i = skipInterval; i < numItems; i += skipInterval)
                    {
                        OverallBox += traceableItems[i].GetAxisAlignedBoundingBox();
                    }
                    double areaOfTotalBounds = OverallBox.GetSurfaceArea();

                    double bestCost = totalIntersectCost;

                    Vector3  totalDeviationOnAxis = new Vector3();
                    double[] surfaceArreaOfItem   = new double[numItems - 1];
                    double[] rightBoundsAtItem    = new double[numItems - 1];

                    for (int axis = 0; axis < 3; axis++)
                    {
                        double intersectCostOnLeft = 0;

                        axisSorter.WhichAxis = axis;
                        traceableItems.Sort(axisSorter);

                        // Get all left bounds
                        AxisAlignedBoundingBox currentLeftBounds = traceableItems[0].GetAxisAlignedBoundingBox();
                        surfaceArreaOfItem[0] = currentLeftBounds.GetSurfaceArea();
                        for (int itemIndex = 1; itemIndex < numItems - 1; itemIndex += skipInterval)
                        {
                            currentLeftBounds            += traceableItems[itemIndex].GetAxisAlignedBoundingBox();
                            surfaceArreaOfItem[itemIndex] = currentLeftBounds.GetSurfaceArea();

                            totalDeviationOnAxis[axis] += Math.Abs(traceableItems[itemIndex].GetCenter()[axis] - traceableItems[itemIndex - 1].GetCenter()[axis]);
                        }

                        // Get all right bounds
                        if (numItems > 1)
                        {
                            AxisAlignedBoundingBox currentRightBounds = traceableItems[numItems - 1].GetAxisAlignedBoundingBox();
                            rightBoundsAtItem[numItems - 2] = currentRightBounds.GetSurfaceArea();
                            for (int itemIndex = numItems - 1; itemIndex > 1; itemIndex -= skipInterval)
                            {
                                currentRightBounds += traceableItems[itemIndex - 1].GetAxisAlignedBoundingBox();
                                rightBoundsAtItem[itemIndex - 2] = currentRightBounds.GetSurfaceArea();
                            }
                        }

                        // Sweep from left
                        for (int itemIndex = 0; itemIndex < numItems - 1; itemIndex += skipInterval)
                        {
                            double thisCost = 0;

                            {
                                // Evaluate Surface Cost Equation
                                double costOfTwoAABB = 2 * AxisAlignedBoundingBox.GetIntersectCost();                                 // the cost of the two children AABB tests

                                // do the left cost
                                intersectCostOnLeft += traceableItems[itemIndex].GetIntersectCost();
                                double leftCost = (surfaceArreaOfItem[itemIndex] / areaOfTotalBounds) * intersectCostOnLeft;

                                // do the right cost
                                double intersectCostOnRight = totalIntersectCost - intersectCostOnLeft;
                                double rightCost            = (rightBoundsAtItem[itemIndex] / areaOfTotalBounds) * intersectCostOnRight;

                                thisCost = costOfTwoAABB + leftCost + rightCost;
                            }

                            if (thisCost < bestCost + .000000001)                             // if it is less within some tiny error
                            {
                                if (thisCost > bestCost - .000000001)
                                {
                                    // they are the same within the error
                                    if (axis > 0 && bestAxis != axis)                                     // we have changed axis since last best and we need to decide if this is better than the last axis best
                                    {
                                        if (totalDeviationOnAxis[axis] > totalDeviationOnAxis[axis - 1])
                                        {
                                            // this new axis is better and we'll switch to it.  Otherwise don't switch.
                                            bestCost           = thisCost;
                                            bestIndexToSplitOn = itemIndex;
                                            bestAxis           = axis;
                                        }
                                    }
                                }
                                else                                 // this is just better
                                {
                                    bestCost           = thisCost;
                                    bestIndexToSplitOn = itemIndex;
                                    bestAxis           = axis;
                                }
                            }
                        }
                    }
                }
            }

            if (bestAxis == -1)
            {
                // No better partition found
                return(new UnboundCollection(traceableItems));
            }
            else
            {
                axisSorter.WhichAxis = bestAxis;
                traceableItems.Sort(axisSorter);
                List <IBoundedItem> leftItems  = new List <IBoundedItem>(bestIndexToSplitOn + 1);
                List <IBoundedItem> rightItems = new List <IBoundedItem>(numItems - bestIndexToSplitOn + 1);
                for (int i = 0; i <= bestIndexToSplitOn; i++)
                {
                    leftItems.Add(traceableItems[i]);
                }
                for (int i = bestIndexToSplitOn + 1; i < numItems; i++)
                {
                    rightItems.Add(traceableItems[i]);
                }
                IBoundedItem            leftGroup  = CreateNewHierachy(leftItems, maxRecursion, recursionDepth + 1, accelerator);
                IBoundedItem            rightGroup = CreateNewHierachy(rightItems, maxRecursion, recursionDepth + 1, accelerator);
                BoundingVolumeHierarchy newBVHNode = new BoundingVolumeHierarchy(leftGroup, rightGroup, bestAxis);
                return(newBVHNode);
            }
        }
Ejemplo n.º 21
0
        public override void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver)
        {
            var selectedItem = RootSelection;

            activeSelectedItem = selectedItem;
            if (MouseIsOver)
            {
                zValueDisplayInfo.Visible = true;
            }
            else if (!hadClickOnControl)
            {
                zValueDisplayInfo.Visible = false;
            }

            if (MouseDownOnControl)
            {
                IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);

                if (info != null &&
                    selectedItem != null)
                {
                    AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();

                    Vector3 delta = info.HitPosition - initialHitPosition;

                    Vector3 newPosition = originalPointToMove + delta;

                    if (Object3DControlContext.SnapGridDistance > 0)
                    {
                        // snap this position to the grid
                        double snapGridDistance = Object3DControlContext.SnapGridDistance;

                        // snap this position to the grid
                        newPosition.Z = ((int)((newPosition.Z / snapGridDistance) + .5)) * snapGridDistance;
                    }

                    Vector3 topPosition  = GetTopPosition(selectedItem);
                    var     lockedBottom = new Vector3(topPosition.X, topPosition.Y, originalSelectedBounds.MinXYZ.Z);

                    Vector3 newSize = Vector3.Zero;
                    newSize.Z = newPosition.Z - lockedBottom.Z;

                    // scale it
                    Vector3 scaleAmount = ScaleCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, Object3DControlContext.GuiSurface.ModifierKeys);

                    var scale = Matrix4X4.CreateScale(scaleAmount);

                    selectedItem.Matrix = selectedItem.ApplyAtBoundsCenter(scale);

                    // and keep the locked edge in place
                    AxisAlignedBoundingBox scaledSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                    var newLockedBottom = new Vector3(topPosition.X, topPosition.Y, scaledSelectedBounds.MinXYZ.Z);

                    selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedBottom - newLockedBottom);

                    Invalidate();
                }
            }

            base.OnMouseMove(mouseEvent3D, mouseIsOver);
        }
 public CenterAndHeightMantainer(IObject3D item)
 {
     this.item = item;
     aabb      = item.GetAxisAlignedBoundingBox();
 }
Ejemplo n.º 23
0
 public double GetIntersectCost()
 {
     return(AxisAlignedBoundingBox.GetIntersectCost());
 }
Ejemplo n.º 24
0
        private static bool CheckPosition(IEnumerable <IObject3D> itemsToAvoid, IObject3D itemToMove, AxisAlignedBoundingBox meshToMoveBounds, int yStep, int xStep, out Matrix4X4 transform)
        {
            double xStepAmount = 5;
            double yStepAmount = 5;

            var     positionTransform = Matrix4X4.CreateTranslation(xStep * xStepAmount, yStep * yStepAmount, 0);
            Vector3 newPosition       = Vector3Ex.Transform(Vector3.Zero, positionTransform);

            transform = Matrix4X4.CreateTranslation(newPosition);

            AxisAlignedBoundingBox testBounds = meshToMoveBounds.NewTransformed(transform);

            foreach (IObject3D meshToTest in itemsToAvoid)
            {
                if (meshToTest != itemToMove)
                {
                    AxisAlignedBoundingBox existingMeshBounds = meshToTest.GetAxisAlignedBoundingBox();
                    var intersection = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds);
                    if (intersection.XSize > 0 && intersection.YSize > 0)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 25
0
 public void BuildBoundingBox()
 {
     BoundingBox = new AxisAlignedBoundingBox(new Vector3(Center.X - Radius, Center.Y - Radius, Center.Z - Radius), new Vector3(Center.X + Radius, Center.Y + Radius, Center.Z + Radius));
 }
Ejemplo n.º 26
0
        public static void ArrangeMeshGroups(List <MeshGroup> asyncMeshGroups, List <Matrix4X4> asyncMeshGroupTransforms, List <PlatingMeshGroupData> asyncPlatingDatas,
                                             Action <double, string> reportProgressChanged)
        {
            // move them all out of the way
            for (int i = 0; i < asyncMeshGroups.Count; i++)
            {
                asyncMeshGroupTransforms[i] *= Matrix4X4.CreateTranslation(10000, 10000, 0);
            }

            // sort them by size
            for (int i = 0; i < asyncMeshGroups.Count; i++)
            {
                AxisAlignedBoundingBox iAABB = asyncMeshGroups[i].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[i]);
                for (int j = i + 1; j < asyncMeshGroups.Count; j++)
                {
                    AxisAlignedBoundingBox jAABB = asyncMeshGroups[j].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[j]);
                    if (Math.Max(iAABB.XSize, iAABB.YSize) < Math.Max(jAABB.XSize, jAABB.YSize))
                    {
                        PlatingMeshGroupData tempData = asyncPlatingDatas[i];
                        asyncPlatingDatas[i] = asyncPlatingDatas[j];
                        asyncPlatingDatas[j] = tempData;

                        MeshGroup tempMeshGroup = asyncMeshGroups[i];
                        asyncMeshGroups[i] = asyncMeshGroups[j];
                        asyncMeshGroups[j] = tempMeshGroup;

                        Matrix4X4 iTransform    = asyncMeshGroupTransforms[i];
                        Matrix4X4 jTransform    = asyncMeshGroupTransforms[j];
                        Matrix4X4 tempTransform = iTransform;
                        iTransform = jTransform;
                        jTransform = tempTransform;

                        asyncMeshGroupTransforms[i] = jTransform;
                        asyncMeshGroupTransforms[j] = iTransform;

                        iAABB = jAABB;
                    }
                }
            }

            double ratioPerMeshGroup = 1.0 / asyncMeshGroups.Count;
            double currentRatioDone  = 0;

            // put them onto the plate (try the center) starting with the biggest and moving down
            for (int meshGroupIndex = 0; meshGroupIndex < asyncMeshGroups.Count; meshGroupIndex++)
            {
                reportProgressChanged(currentRatioDone, "Calculating Positions...".Localize());

                MeshGroup meshGroup     = asyncMeshGroups[meshGroupIndex];
                Vector3   meshLowerLeft = meshGroup.GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[meshGroupIndex]).minXYZ;
                asyncMeshGroupTransforms[meshGroupIndex] *= Matrix4X4.CreateTranslation(-meshLowerLeft);

                PlatingHelper.MoveMeshGroupToOpenPosition(meshGroupIndex, asyncPlatingDatas, asyncMeshGroups, asyncMeshGroupTransforms);

                // and create the trace info so we can select it
                if (asyncPlatingDatas[meshGroupIndex].meshTraceableData.Count == 0)
                {
                    PlatingHelper.CreateITraceableForMeshGroup(asyncPlatingDatas, asyncMeshGroups, meshGroupIndex, null);
                }

                currentRatioDone += ratioPerMeshGroup;

                // and put it on the bed
                PlatingHelper.PlaceMeshGroupOnBed(asyncMeshGroups, asyncMeshGroupTransforms, meshGroupIndex);
            }

            // and finally center whatever we have as a group
            {
                AxisAlignedBoundingBox bounds = asyncMeshGroups[0].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[0]);
                for (int i = 1; i < asyncMeshGroups.Count; i++)
                {
                    bounds = AxisAlignedBoundingBox.Union(bounds, asyncMeshGroups[i].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[i]));
                }

                Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2;
                for (int i = 0; i < asyncMeshGroups.Count; i++)
                {
                    asyncMeshGroupTransforms[i] *= Matrix4X4.CreateTranslation(-boundsCenter + new Vector3(0, 0, bounds.ZSize / 2));
                }
            }
        }
Ejemplo n.º 27
0
        public void SavingFunction()
        {
            currentlySaving        = true;
            countThatHaveBeenSaved = 0;
            // first create images for all the parts
            foreach (FileNameAndPresentationName queuePartFileName in queuPartFilesToAdd)
            {
                List <MeshGroup> loadedMeshGroups = MeshFileIo.Load(queuePartFileName.fileName);
                if (loadedMeshGroups != null)
                {
                    bool firstMeshGroup         = true;
                    AxisAlignedBoundingBox aabb = null;
                    foreach (MeshGroup meshGroup in loadedMeshGroups)
                    {
                        if (firstMeshGroup)
                        {
                            aabb           = meshGroup.GetAxisAlignedBoundingBox();
                            firstMeshGroup = false;
                        }
                        else
                        {
                            aabb = AxisAlignedBoundingBox.Union(aabb, meshGroup.GetAxisAlignedBoundingBox());
                        }
                    }
                    RectangleDouble bounds2D    = new RectangleDouble(aabb.minXYZ.x, aabb.minXYZ.y, aabb.maxXYZ.x, aabb.maxXYZ.y);
                    double          widthInMM   = bounds2D.Width + PartMarginMM * 2;
                    double          textSpaceMM = 5;
                    double          heightMM    = textSpaceMM + bounds2D.Height + PartMarginMM * 2;

                    TypeFacePrinter typeFacePrinter = new TypeFacePrinter(queuePartFileName.presentationName, 28, Vector2.Zero, Justification.Center, Baseline.BoundsCenter);
                    double          sizeOfNameX     = typeFacePrinter.GetSize().x + PartMarginPixels * 2;
                    Vector2         sizeOfRender    = new Vector2(widthInMM * PixelPerMM, heightMM * PixelPerMM);

                    ImageBuffer imageOfPart = new ImageBuffer((int)(Math.Max(sizeOfNameX, sizeOfRender.x)), (int)(sizeOfRender.y), 32, new BlenderBGRA());
                    typeFacePrinter.Origin = new Vector2(imageOfPart.Width / 2, (textSpaceMM / 2) * PixelPerMM);

                    Graphics2D partGraphics2D = imageOfPart.NewGraphics2D();

                    RectangleDouble rectBounds  = new RectangleDouble(0, 0, imageOfPart.Width, imageOfPart.Height);
                    double          strokeWidth = .5 * PixelPerMM;
                    rectBounds.Inflate(-strokeWidth / 2);
                    RoundedRect rect = new RoundedRect(rectBounds, PartMarginMM * PixelPerMM);
                    partGraphics2D.Render(rect, RGBA_Bytes.LightGray);
                    Stroke rectOutline = new Stroke(rect, strokeWidth);
                    partGraphics2D.Render(rectOutline, RGBA_Bytes.DarkGray);

                    foreach (MeshGroup meshGroup in loadedMeshGroups)
                    {
                        foreach (Mesh loadedMesh in meshGroup.Meshes)
                        {
                            PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partGraphics2D, loadedMesh, new Vector2(-bounds2D.Left + PartMarginMM, -bounds2D.Bottom + textSpaceMM + PartMarginMM), PixelPerMM, RGBA_Bytes.Black);
                        }
                    }
                    partGraphics2D.Render(typeFacePrinter, RGBA_Bytes.Black);

                    partImagesToPrint.Add(new PartImage(imageOfPart));

                    countThatHaveBeenSaved++;
                }

                if (UpdateRemainingItems != null)
                {
                    UpdateRemainingItems(this, new StringEventArgs(Path.GetFileName(queuePartFileName.presentationName)));
                }
            }

            partImagesToPrint.Sort(BiggestToLittlestImages);

            PdfDocument document = new PdfDocument();

            document.Info.Title    = "MatterHackers Parts Sheet";
            document.Info.Author   = "MatterHackers Inc.";
            document.Info.Subject  = "This is a list of the parts that are in a queue from MatterControl.";
            document.Info.Keywords = "MatterControl, STL, 3D Printing";

            int  nextPartToPrintIndex = 0;
            int  plateNumber          = 1;
            bool done = false;

            while (!done && nextPartToPrintIndex < partImagesToPrint.Count)
            {
                PdfPage pdfPage = document.AddPage();
                CreateOnePage(plateNumber++, ref nextPartToPrintIndex, pdfPage);
            }
            try
            {
                // save the final document
                document.Save(pathAndFileToSaveTo);
                // Now try and open the document. This will lanch whatever PDF viewer is on the system and ask it
                // to show the file (at least on Windows).
                Process.Start(pathAndFileToSaveTo);
            }
            catch (Exception)
            {
            }

            OnDoneSaving();
            currentlySaving = false;
        }
Ejemplo n.º 28
0
        public static void MoveMeshGroupToOpenPosition(int meshGroupToMoveIndex, List <PlatingMeshGroupData> perMeshInfo, List <MeshGroup> allMeshGroups, List <Matrix4X4> meshTransforms)
        {
            AxisAlignedBoundingBox allPlacedMeshBounds = GetAxisAlignedBoundingBox(allMeshGroups[0], meshTransforms[0]);

            for (int i = 1; i < meshGroupToMoveIndex; i++)
            {
                AxisAlignedBoundingBox nextMeshBounds = GetAxisAlignedBoundingBox(allMeshGroups[i], meshTransforms[i]);
                allPlacedMeshBounds = AxisAlignedBoundingBox.Union(allPlacedMeshBounds, nextMeshBounds);
            }

            double xStart = allPlacedMeshBounds.minXYZ.x;
            double yStart = allPlacedMeshBounds.minXYZ.y;

            MeshGroup meshGroupToMove = allMeshGroups[meshGroupToMoveIndex];
            // find a place to put it that doesn't hit anything
            AxisAlignedBoundingBox meshToMoveBounds = GetAxisAlignedBoundingBox(meshGroupToMove, meshTransforms[meshGroupToMoveIndex]);

            // add in a few mm so that it will not be touching
            meshToMoveBounds.minXYZ -= new Vector3(2, 2, 0);
            meshToMoveBounds.maxXYZ += new Vector3(2, 2, 0);

            Matrix4X4 transform   = Matrix4X4.Identity;
            int       currentSize = 1;
            bool      partPlaced  = false;

            while (!partPlaced && meshGroupToMoveIndex > 0)
            {
                int yStep = 0;
                int xStep = currentSize;
                // check far right edge
                for (yStep = 0; yStep < currentSize; yStep++)
                {
                    partPlaced = CheckPosition(meshGroupToMoveIndex, allMeshGroups, meshTransforms, meshGroupToMove, meshToMoveBounds, yStep, xStep, ref transform);

                    if (partPlaced)
                    {
                        break;
                    }
                }

                if (!partPlaced)
                {
                    yStep = currentSize;
                    // check top edge
                    for (xStep = 0; xStep < currentSize; xStep++)
                    {
                        partPlaced = CheckPosition(meshGroupToMoveIndex, allMeshGroups, meshTransforms, meshGroupToMove, meshToMoveBounds, yStep, xStep, ref transform);

                        if (partPlaced)
                        {
                            break;
                        }
                    }

                    if (!partPlaced)
                    {
                        xStep = currentSize;
                        // check top right point
                        partPlaced = CheckPosition(meshGroupToMoveIndex, allMeshGroups, meshTransforms, meshGroupToMove, meshToMoveBounds, yStep, xStep, ref transform);
                    }
                }

                currentSize++;
            }

            meshTransforms[meshGroupToMoveIndex] *= transform;
        }
Ejemplo n.º 29
0
        private void AlignSelected()
        {
            if (SelectedMeshGroupIndex == -1)
            {
                SelectedMeshGroupIndex = 0;
            }
            // make sure our thread translates numbers correctly (always do this in a thread)
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            // save our data so we don't mess up the display while doing work
            PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DO_COPY);

            // try to move all the not selected meshes relative to the selected mesh
            AxisAlignedBoundingBox selectedOriginalBounds = asyncMeshGroups[SelectedMeshGroupIndex].GetAxisAlignedBoundingBox();
            Vector3 selectedOriginalCenter = selectedOriginalBounds.Center;
            AxisAlignedBoundingBox selectedCurrentBounds = asyncMeshGroups[SelectedMeshGroupIndex].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[SelectedMeshGroupIndex]);
            Vector3 selctedCurrentCenter = selectedCurrentBounds.Center;

            for (int meshGroupToMoveIndex = 0; meshGroupToMoveIndex < asyncMeshGroups.Count; meshGroupToMoveIndex++)
            {
                MeshGroup meshGroupToMove = asyncMeshGroups[meshGroupToMoveIndex];
                if (meshGroupToMove != asyncMeshGroups[SelectedMeshGroupIndex])
                {
                    AxisAlignedBoundingBox groupToMoveOriginalBounds = meshGroupToMove.GetAxisAlignedBoundingBox();
                    Vector3 groupToMoveOriginalCenter        = groupToMoveOriginalBounds.Center;
                    AxisAlignedBoundingBox groupToMoveBounds = meshGroupToMove.GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[meshGroupToMoveIndex]);
                    Vector3 groupToMoveCenter = groupToMoveBounds.Center;

                    Vector3 originalCoordinatesDelta = groupToMoveOriginalCenter - selectedOriginalCenter;
                    Vector3 currentCoordinatesDelta  = groupToMoveCenter - selctedCurrentCenter;

                    Vector3 deltaRequired = originalCoordinatesDelta - currentCoordinatesDelta;

                    if (deltaRequired.Length > .0001)
                    {
                        asyncMeshGroupTransforms[meshGroupToMoveIndex] *= Matrix4X4.CreateTranslation(deltaRequired);
                        PartHasBeenChanged();
                    }
                }
            }

            // now put all the meshes into just one group
            MeshGroup meshGroupWeAreKeeping = asyncMeshGroups[SelectedMeshGroupIndex];

            for (int meshGroupToMoveIndex = asyncMeshGroups.Count - 1; meshGroupToMoveIndex >= 0; meshGroupToMoveIndex--)
            {
                MeshGroup meshGroupToMove = asyncMeshGroups[meshGroupToMoveIndex];
                if (meshGroupToMove != meshGroupWeAreKeeping)
                {
                    // move all the meshes into the new aligned mesh group
                    for (int moveIndex = 0; moveIndex < meshGroupToMove.Meshes.Count; moveIndex++)
                    {
                        Mesh mesh = meshGroupToMove.Meshes[moveIndex];
                        meshGroupWeAreKeeping.Meshes.Add(mesh);
                    }

                    asyncMeshGroups.RemoveAt(meshGroupToMoveIndex);
                    asyncMeshGroupTransforms.RemoveAt(meshGroupToMoveIndex);
                }
            }

            asyncPlatingDatas.Clear();
            double ratioPerMeshGroup = 1.0 / asyncMeshGroups.Count;
            double currentRatioDone  = 0;

            for (int i = 0; i < asyncMeshGroups.Count; i++)
            {
                PlatingMeshGroupData newInfo = new PlatingMeshGroupData();
                asyncPlatingDatas.Add(newInfo);

                MeshGroup meshGroup = asyncMeshGroups[i];

                // create the selection info
                PlatingHelper.CreateITraceableForMeshGroup(asyncPlatingDatas, asyncMeshGroups, i, (double progress0To1, string processingState, out bool continueProcessing) =>
                {
                    ReportProgressChanged(progress0To1, processingState, out continueProcessing);
                });

                currentRatioDone += ratioPerMeshGroup;
            }
        }
Ejemplo n.º 30
0
        private static bool CheckPosition(int meshGroupToMoveIndex, List <MeshGroup> allMeshGroups, List <Matrix4X4> meshTransforms, MeshGroup meshGroupToMove, AxisAlignedBoundingBox meshToMoveBounds, int yStep, int xStep, ref Matrix4X4 transform)
        {
            double xStepAmount = 5;
            double yStepAmount = 5;

            Matrix4X4 positionTransform = Matrix4X4.CreateTranslation(xStep * xStepAmount, yStep * yStepAmount, 0);
            Vector3   newPosition       = Vector3.Transform(Vector3.Zero, positionTransform);

            transform = Matrix4X4.CreateTranslation(newPosition);
            AxisAlignedBoundingBox testBounds = meshToMoveBounds.NewTransformed(transform);
            bool foundHit = false;

            for (int i = 0; i < meshGroupToMoveIndex; i++)
            {
                MeshGroup meshToTest = allMeshGroups[i];
                if (meshToTest != meshGroupToMove)
                {
                    AxisAlignedBoundingBox existingMeshBounds = GetAxisAlignedBoundingBox(meshToTest, meshTransforms[i]);
                    AxisAlignedBoundingBox intersection       = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds);
                    if (intersection.XSize > 0 && intersection.YSize > 0)
                    {
                        foundHit = true;
                        break;
                    }
                }
            }

            if (!foundHit)
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 31
0
        public async Task SaveSheets()
        {
            await Task.Run((Func <Task>)(async() =>
            {
                currentlySaving = true;
                // first create images for all the parts
                foreach (var item in itemSource)
                {
                    var object3D = await item.CreateContent();

                    var loadedMeshGroups = object3D.VisibleMeshes().ToList();
                    if (loadedMeshGroups?.Count > 0)
                    {
                        AxisAlignedBoundingBox aabb = loadedMeshGroups[0].Mesh.GetAxisAlignedBoundingBox(loadedMeshGroups[0].WorldMatrix());

                        for (int i = 1; i < loadedMeshGroups.Count; i++)
                        {
                            aabb = AxisAlignedBoundingBox.Union(aabb, loadedMeshGroups[i].Mesh.GetAxisAlignedBoundingBox(loadedMeshGroups[i].WorldMatrix()));
                        }

                        RectangleDouble bounds2D = new RectangleDouble(aabb.minXYZ.X, aabb.minXYZ.Y, aabb.maxXYZ.X, aabb.maxXYZ.Y);
                        double widthInMM         = bounds2D.Width + PartMarginMM * 2;
                        double textSpaceMM       = 5;
                        double heightMM          = textSpaceMM + bounds2D.Height + PartMarginMM * 2;

                        TypeFacePrinter typeFacePrinter = new TypeFacePrinter(item.Name, 28, Vector2.Zero, Justification.Center, Baseline.BoundsCenter);
                        double sizeOfNameX   = typeFacePrinter.GetSize().X + PartMarginPixels * 2;
                        Vector2 sizeOfRender = new Vector2(widthInMM *PixelPerMM, heightMM *PixelPerMM);

                        ImageBuffer imageOfPart = new ImageBuffer((int)(Math.Max(sizeOfNameX, sizeOfRender.X)), (int)(sizeOfRender.Y));
                        typeFacePrinter.Origin  = new Vector2(imageOfPart.Width / 2, (textSpaceMM / 2) * PixelPerMM);

                        Graphics2D partGraphics2D = imageOfPart.NewGraphics2D();

                        RectangleDouble rectBounds = new RectangleDouble(0, 0, imageOfPart.Width, imageOfPart.Height);
                        double strokeWidth         = .5 * PixelPerMM;
                        rectBounds.Inflate(-strokeWidth / 2);
                        RoundedRect rect = new RoundedRect(rectBounds, PartMarginMM *PixelPerMM);
                        partGraphics2D.Render(rect, Color.LightGray);
                        Stroke rectOutline = new Stroke(rect, strokeWidth);
                        partGraphics2D.Render(rectOutline, Color.DarkGray);

                        foreach (var meshGroup in loadedMeshGroups)
                        {
                            PolygonMesh.Rendering.OrthographicZProjection.DrawTo(partGraphics2D, meshGroup.Mesh, meshGroup.WorldMatrix(), new Vector2(-bounds2D.Left + PartMarginMM, -bounds2D.Bottom + textSpaceMM + PartMarginMM), PixelPerMM, Color.Black);
                        }
                        partGraphics2D.Render(typeFacePrinter, Color.Black);

                        partImagesToPrint.Add(new PartImage(imageOfPart));
                    }

                    UpdateRemainingItems?.Invoke(this, new StringEventArgs(item.Name));
                }

                partImagesToPrint.Sort(BiggestToLittlestImages);

                PdfDocument document   = new PdfDocument();
                document.Info.Title    = "MatterHackers Parts Sheet";
                document.Info.Author   = "MatterHackers Inc.";
                document.Info.Subject  = "This is a list of the parts that are in a queue from MatterControl.";
                document.Info.Keywords = "MatterControl, STL, 3D Printing";

                int nextPartToPrintIndex = 0;
                int plateNumber          = 1;
                bool done = false;

                while (!done && nextPartToPrintIndex < partImagesToPrint.Count)
                {
                    PdfPage pdfPage = document.AddPage();
                    CreateOnePage(plateNumber++, ref nextPartToPrintIndex, pdfPage);
                }

                try
                {
                    // save the final document
                    document.Save(pathAndFileToSaveTo);

                    // Now try and open the document. This will launch whatever PDF viewer is on the system and ask it
                    // to show the file (at least on Windows).
                    Process.Start(pathAndFileToSaveTo);
                }
                catch (Exception)
                {
                }

                OnDoneSaving();
                currentlySaving = false;
            }));
        }
Ejemplo n.º 32
0
 public static Matrix4X4 ApplyAtCenter(AxisAlignedBoundingBox boundsToApplyTo, Matrix4X4 currentTransform, Matrix4X4 transformToApply)
 {
     return(ApplyAtPosition(currentTransform, transformToApply, boundsToApplyTo.Center));
 }
Ejemplo n.º 33
0
 public void UpdateBoundingBox()
 {
     var vertices = GetRawVertexList();
     var a = vertices[0];
     var b = vertices[0];
     foreach(var v in vertices)
     {
         a = Min(a, v);
         b = Max(b, v);
     }
     AABB = new AxisAlignedBoundingBox()
     {
         Minimum = a,
         Maximum = b
     };
 }
Ejemplo n.º 34
0
        internal ModelMesh(W3dMesh w3dMesh, AssetLoadContext loadContext)
        {
            SetNameAndInstanceId("W3DMesh", w3dMesh.Header.MeshName);

            W3dShaderMaterial   w3dShaderMaterial;
            ShaderResourcesBase shaderResources;

            if (w3dMesh.MaterialPasses.Count == 1 && w3dMesh.MaterialPasses[0].ShaderMaterialIds != null)
            {
                if (w3dMesh.MaterialPasses[0].ShaderMaterialIds.Items.Length > 1)
                {
                    throw new NotSupportedException();
                }
                var shaderMaterialID = w3dMesh.MaterialPasses[0].ShaderMaterialIds.Items[0];
                w3dShaderMaterial = w3dMesh.ShaderMaterials.Items[(int)shaderMaterialID];
                var effectName = w3dShaderMaterial.Header.TypeName.Replace(".fx", string.Empty);

                shaderResources = loadContext.ShaderResources.GetShaderMaterialResources(effectName);
            }
            else
            {
                w3dShaderMaterial = null;
                shaderResources   = loadContext.ShaderResources.FixedFunction;
            }

            _depthPipeline = loadContext.ShaderResources.MeshDepth.Pipeline;

            MeshParts = new List <ModelMeshPart>();
            if (w3dShaderMaterial != null)
            {
                MeshParts.Add(CreateModelMeshPartShaderMaterial(
                                  loadContext,
                                  w3dMesh,
                                  w3dMesh.MaterialPasses[0],
                                  w3dShaderMaterial,
                                  (ShaderMaterialShaderResources)shaderResources));
            }
            else
            {
                var vertexMaterials = CreateMaterials(w3dMesh);

                var shadingConfigurations = new FixedFunctionShaderResources.ShadingConfiguration[w3dMesh.Shaders.Items.Count];
                for (var i = 0; i < shadingConfigurations.Length; i++)
                {
                    shadingConfigurations[i] = CreateShadingConfiguration(w3dMesh.Shaders.Items[i]);
                }

                for (var i = 0; i < w3dMesh.MaterialPasses.Count; i++)
                {
                    CreateModelMeshPartsFixedFunction(
                        loadContext,
                        w3dMesh,
                        w3dMesh.MaterialPasses[i],
                        vertexMaterials,
                        shadingConfigurations,
                        MeshParts);
                }
            }

            BoundingBox = new AxisAlignedBoundingBox(
                w3dMesh.Header.Min,
                w3dMesh.Header.Max);

            _shaderSet = shaderResources.ShaderSet;

            Skinned        = w3dMesh.IsSkinned;
            Hidden         = w3dMesh.Header.Attributes.HasFlag(W3dMeshFlags.Hidden);
            CameraOriented = (w3dMesh.Header.Attributes & W3dMeshFlags.GeometryTypeMask) == W3dMeshFlags.GeometryTypeCameraOriented;

            _vertexBuffer = AddDisposable(loadContext.GraphicsDevice.CreateStaticBuffer(
                                              MemoryMarshal.AsBytes(new ReadOnlySpan <MeshShaderResources.MeshVertex.Basic>(CreateVertices(w3dMesh, w3dMesh.IsSkinned))),
                                              BufferUsage.VertexBuffer));

            _indexBuffer = AddDisposable(loadContext.GraphicsDevice.CreateStaticBuffer(
                                             CreateIndices(w3dMesh),
                                             BufferUsage.IndexBuffer));

            var hasHouseColor = w3dMesh.Header.MeshName.StartsWith("HOUSECOLOR");

            _meshConstantsResourceSet = loadContext.ShaderResources.Mesh.GetCachedMeshResourceSet(
                Skinned,
                hasHouseColor);

            PostInitialize(loadContext);
        }
        public void Contains(float x, float y, float z, bool expected)
        {
            var sut = new AxisAlignedBoundingBox(new Vector3(-2), new Vector3(2));

            Assert.Equal(expected, sut.Contains(new Vector3(x, y, z)));
        }
Ejemplo n.º 36
0
 public abstract bool CheckIfBundleHitsAabb(AxisAlignedBoundingBox aabbToCheck);