public void SetCenteringForMeshGroup(MeshGroup meshGroup)
        {
            AxisAlignedBoundingBox bounds = meshGroup.GetAxisAlignedBoundingBox();
            Vector3 boundsCenter          = (bounds.maxXYZ + bounds.minXYZ) / 2;

            centering = Matrix4X4.CreateTranslation(-boundsCenter);
            // and move the translation back so the part does not move
            translation *= Matrix4X4.CreateTranslation(boundsCenter);
        }
示例#2
0
        public static void MoveMeshGroupToOpenPosition(int meshGroupToMoveIndex, List <PlatingMeshGroupData> perMeshInfo, List <MeshGroup> allMeshGroups, List <ScaleRotateTranslate> meshTransforms)
        {
            MeshGroup meshGroupToMove = allMeshGroups[meshGroupToMoveIndex];
            // find a place to put it that doesn't hit anything
            AxisAlignedBoundingBox meshToMoveBounds = meshGroupToMove.GetAxisAlignedBoundingBox(meshTransforms[meshGroupToMoveIndex].TotalTransform);

            // 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);
            double    ringDist       = Math.Min(meshToMoveBounds.XSize, meshToMoveBounds.YSize);
            double    currentDist    = 0;
            double    angle          = 0;
            double    angleIncrement = MathHelper.Tau / 64;
            Matrix4X4 transform;

            while (true)
            {
                Matrix4X4 positionTransform = Matrix4X4.CreateTranslation(currentDist, 0, 0);
                positionTransform *= Matrix4X4.CreateRotationZ(angle);
                Vector3 newPosition = Vector3.Transform(Vector3.Zero, positionTransform);
                transform = Matrix4X4.CreateTranslation(newPosition);
                AxisAlignedBoundingBox testBounds = meshToMoveBounds.NewTransformed(transform);
                bool foundHit = false;
                for (int i = 0; i < allMeshGroups.Count; i++)
                {
                    MeshGroup meshToTest = allMeshGroups[i];
                    if (meshToTest != meshGroupToMove)
                    {
                        AxisAlignedBoundingBox existingMeshBounds = meshToTest.GetAxisAlignedBoundingBox(meshTransforms[i].TotalTransform);
                        AxisAlignedBoundingBox intersection       = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds);
                        if (intersection.XSize > 0 && intersection.YSize > 0)
                        {
                            foundHit = true;
                            break;
                        }
                    }
                }

                if (!foundHit)
                {
                    break;
                }

                angle += angleIncrement;
                if (angle >= MathHelper.Tau)
                {
                    angle        = 0;
                    currentDist += ringDist;
                }
            }

            ScaleRotateTranslate moved = meshTransforms[meshGroupToMoveIndex];

            moved.translation *= transform;
            meshTransforms[meshGroupToMoveIndex] = moved;
        }
示例#3
0
 static AxisAlignedBoundingBox GetAxisAlignedBoundingBox(MeshGroup meshGroup, Matrix4X4 transform)
 {
     return(meshGroup.GetAxisAlignedBoundingBox(transform));
 }
示例#4
0
        private void AlignSelected()
        {
            if (SelectedMeshGroupIndex == -1)
            {
                SelectedMeshGroupIndex = 0;
            }
            // make sure our thread traslates numbmers 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].TotalTransform);
            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].TotalTransform);
                    Vector3 groupToMoveCenter = groupToMoveBounds.Center;

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

                    Vector3 deltaRequired = originalCoordinatesDelta - currentCoordinatesDelta;

                    if (deltaRequired.Length > .0001)
                    {
                        ScaleRotateTranslate translated = asyncMeshGroupTransforms[meshGroupToMoveIndex];
                        translated.translation *= Matrix4X4.CreateTranslation(deltaRequired);
                        asyncMeshGroupTransforms[meshGroupToMoveIndex] = translated;
                        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;
            }
        }
示例#5
0
        public static void ArrangeMeshGroups(List <MeshGroup> asyncMeshGroups, List <ScaleRotateTranslate> asyncMeshGroupTransforms, List <PlatingMeshGroupData> asyncPlatingDatas,
                                             Action <double, string> reportProgressChanged)
        {
            // move them all out of the way
            for (int i = 0; i < asyncMeshGroups.Count; i++)
            {
                ScaleRotateTranslate translate = asyncMeshGroupTransforms[i];
                translate.translation      *= Matrix4X4.CreateTranslation(10000, 10000, 0);
                asyncMeshGroupTransforms[i] = translate;
            }

            // sort them by size
            for (int i = 0; i < asyncMeshGroups.Count; i++)
            {
                AxisAlignedBoundingBox iAABB = asyncMeshGroups[i].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[i].TotalTransform);
                for (int j = i + 1; j < asyncMeshGroups.Count; j++)
                {
                    AxisAlignedBoundingBox jAABB = asyncMeshGroups[j].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[j].TotalTransform);
                    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;

                        ScaleRotateTranslate iTransform    = asyncMeshGroupTransforms[i];
                        ScaleRotateTranslate jTransform    = asyncMeshGroupTransforms[j];
                        Matrix4X4            tempTransform = iTransform.translation;
                        iTransform.translation = jTransform.translation;
                        jTransform.translation = 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].TotalTransform).minXYZ;
                ScaleRotateTranslate atZero        = asyncMeshGroupTransforms[meshGroupIndex];
                atZero.translation *= Matrix4X4.CreateTranslation(-meshLowerLeft);
                asyncMeshGroupTransforms[meshGroupIndex] = atZero;

                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].TotalTransform);
                for (int i = 1; i < asyncMeshGroups.Count; i++)
                {
                    bounds = AxisAlignedBoundingBox.Union(bounds, asyncMeshGroups[i].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[i].TotalTransform));
                }

                Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2;
                for (int i = 0; i < asyncMeshGroups.Count; i++)
                {
                    ScaleRotateTranslate translate = asyncMeshGroupTransforms[i];
                    translate.translation      *= Matrix4X4.CreateTranslation(-boundsCenter + new Vector3(0, 0, bounds.ZSize / 2));
                    asyncMeshGroupTransforms[i] = translate;
                }
            }
        }
示例#6
0
        private void arrangeMeshGroupsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DONT_COPY);

            BackgroundWorker backgroundWorker = (BackgroundWorker)sender;

            // move them all out of the way
            for (int i = 0; i < asynchMeshGroups.Count; i++)
            {
                ScaleRotateTranslate translate = asynchMeshGroupTransforms[i];
                translate.translation       *= Matrix4X4.CreateTranslation(10000, 10000, 0);
                asynchMeshGroupTransforms[i] = translate;
            }

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

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

                        ScaleRotateTranslate iTransform    = asynchMeshGroupTransforms[i];
                        ScaleRotateTranslate jTransform    = asynchMeshGroupTransforms[j];
                        Matrix4X4            tempTransform = iTransform.translation;
                        iTransform.translation = jTransform.translation;
                        jTransform.translation = tempTransform;

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

                        iAABB = jAABB;
                    }
                }
            }

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

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

                MeshGroup            meshGroup     = asynchMeshGroups[meshGroupIndex];
                Vector3              meshLowerLeft = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[meshGroupIndex].TotalTransform).minXYZ;
                ScaleRotateTranslate atZero        = asynchMeshGroupTransforms[meshGroupIndex];
                atZero.translation *= Matrix4X4.CreateTranslation(-meshLowerLeft);
                asynchMeshGroupTransforms[meshGroupIndex] = atZero;

                PlatingHelper.MoveMeshGroupToOpenPosition(meshGroupIndex, asynchPlatingDatas, asynchMeshGroups, asynchMeshGroupTransforms);

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

                currentRatioDone += ratioPerMeshGroup;

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

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

                Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2;
                for (int i = 0; i < asynchMeshGroups.Count; i++)
                {
                    ScaleRotateTranslate translate = asynchMeshGroupTransforms[i];
                    translate.translation       *= Matrix4X4.CreateTranslation(-boundsCenter + new Vector3(0, 0, bounds.ZSize / 2));
                    asynchMeshGroupTransforms[i] = translate;
                }
            }
        }