Exemplo n.º 1
1
		public TrackBallController(TrackBallController trackBallToCopy)
		{
			this.screenCenter = trackBallToCopy.screenCenter;
			this.rotationTrackingRadius = trackBallToCopy.rotationTrackingRadius;
			this.currentRotationMatrix = trackBallToCopy.currentRotationMatrix;
			this.currentTranslationMatrix = trackBallToCopy.currentTranslationMatrix;
		}
Exemplo n.º 2
0
		public ScaleRotateTranslate(Matrix4X4 scale, Matrix4X4 rotation, Matrix4X4 translation)
		{
			centering = Matrix4X4.Identity;
			this.scale = scale;
			this.rotation = rotation;
			this.translation = translation;
		}
		public AxisAlignedBoundingBox NewTransformed(Matrix4X4 transform)
		{
			Vector3[] boundsVerts = new Vector3[8];
			boundsVerts[0] = new Vector3(this[0][0], this[0][1], this[0][2]);
			boundsVerts[1] = new Vector3(this[0][0], this[0][1], this[1][2]);
			boundsVerts[2] = new Vector3(this[0][0], this[1][1], this[0][2]);
			boundsVerts[3] = new Vector3(this[0][0], this[1][1], this[1][2]);
			boundsVerts[4] = new Vector3(this[1][0], this[0][1], this[0][2]);
			boundsVerts[5] = new Vector3(this[1][0], this[0][1], this[1][2]);
			boundsVerts[6] = new Vector3(this[1][0], this[1][1], this[0][2]);
			boundsVerts[7] = new Vector3(this[1][0], this[1][1], this[1][2]);

			Vector3.Transform(boundsVerts, transform);

			Vector3 newMin = new Vector3(double.MaxValue, double.MaxValue, double.MaxValue);
			Vector3 newMax = new Vector3(double.MinValue, double.MinValue, double.MinValue);

			for (int i = 0; i < 8; i++)
			{
				newMin.x = Math.Min(newMin.x, boundsVerts[i].x);
				newMin.y = Math.Min(newMin.y, boundsVerts[i].y);
				newMin.z = Math.Min(newMin.z, boundsVerts[i].z);

				newMax.x = Math.Max(newMax.x, boundsVerts[i].x);
				newMax.y = Math.Max(newMax.y, boundsVerts[i].y);
				newMax.z = Math.Max(newMax.z, boundsVerts[i].z);
			}

			return new AxisAlignedBoundingBox(newMin, newMax);
		}
		public TransformUndoCommand(View3DWidget view3DWidget, int meshGroupIndex, Matrix4X4 undoTransform, Matrix4X4 redoTransform)
		{
			this.view3DWidget = view3DWidget;
			this.meshGroupIndex = meshGroupIndex;
			this.undoTransform = undoTransform;
			this.redoTransform = redoTransform;
		}
Exemplo n.º 5
0
        public void SetPrintLevelingEquation(Vector3 position0, Vector3 position1, Vector3 position2, Vector2 bedCenter)
        {
            if (position0 == position1 || position1 == position2 || position2 == position0)
            {
                return;
            }

            Plane planeOfPoints = new Plane(position0, position1, position2);

            Ray ray = new Ray(new Vector3(bedCenter, 0), Vector3.UnitZ);
            bool inFront;
            double distanceToPlaneAtBedCenter = planeOfPoints.GetDistanceToIntersection(ray, out inFront);

            Matrix4X4 makePointsFlatMatrix = Matrix4X4.CreateTranslation(-bedCenter.x, -bedCenter.y, -distanceToPlaneAtBedCenter);
            makePointsFlatMatrix *= Matrix4X4.CreateRotation(planeOfPoints.planeNormal, Vector3.UnitZ);
            makePointsFlatMatrix *= Matrix4X4.CreateTranslation(bedCenter.x, bedCenter.y, 0);//distanceToPlaneAtBedCenter);

            bedLevelMatrix = Matrix4X4.Invert(makePointsFlatMatrix);

            {
                // test that the points come back as 0 zs
                Vector3 outPosition0 = Vector3.TransformPosition(position0, makePointsFlatMatrix);
                Vector3 outPosition1 = Vector3.TransformPosition(position1, makePointsFlatMatrix);
                Vector3 outPosition2 = Vector3.TransformPosition(position2, makePointsFlatMatrix);

                Vector3 printPosition0 = new Vector3(ActiveSliceSettings.Instance.GetPrintLevelSamplePosition(0), 0);
                Vector3 printPosition1 = new Vector3(ActiveSliceSettings.Instance.GetPrintLevelSamplePosition(1), 0);
                Vector3 printPosition2 = new Vector3(ActiveSliceSettings.Instance.GetPrintLevelSamplePosition(2), 0);

                Vector3 leveledPositon0 = Vector3.TransformPosition(printPosition0, bedLevelMatrix);
                Vector3 leveledPositon1 = Vector3.TransformPosition(printPosition1, bedLevelMatrix);
                Vector3 leveledPositon2 = Vector3.TransformPosition(printPosition2, bedLevelMatrix);
            }
        }
Exemplo n.º 6
0
 public Transform(IRayTraceable root, Matrix4X4 transform)
 {
     this.child = root;
     WorldToAxis = transform;
     AxisToWorld = Matrix4X4.Invert(WorldToAxis);
     AxisToWorld = transform;
     WorldToAxis = Matrix4X4.Invert(AxisToWorld);
 }
Exemplo n.º 7
0
		public DeleteUndoCommand(View3DWidget view3DWidget, int deletedIndex)
		{
			this.view3DWidget = view3DWidget;
			this.deletedIndex = deletedIndex;
			meshGroupThatWasDeleted = view3DWidget.MeshGroups[deletedIndex];
			deletedTransform = view3DWidget.MeshGroupTransforms[deletedIndex];
			deletedPlatingData = view3DWidget.MeshGroupExtraData[deletedIndex];
		}
Exemplo n.º 8
0
		public void MoveToAbsolute(double x, double y, double z)
		{
			AxisToWorld[3, 0] = x;
			AxisToWorld[3, 1] = y;
			AxisToWorld[3, 2] = z;

			WorldToAxis = Matrix4X4.Invert(AxisToWorld);
		}
Exemplo n.º 9
0
		public CopyUndoCommand(View3DWidget view3DWidget, int newItemIndex)
		{
			this.view3DWidget = view3DWidget;
			this.newItemIndex = newItemIndex;
			meshGroupThatWasDeleted = view3DWidget.MeshGroups[newItemIndex];
			newItemTransform = view3DWidget.MeshGroupTransforms[newItemIndex];
			newItemPlatingData = view3DWidget.MeshGroupExtraData[newItemIndex];
		}
Exemplo n.º 10
0
		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);
		}
Exemplo n.º 11
0
		public void MarkAsChanged()
		{
			// mark this unchecked as we don't want to throw an exception if this rolls over.
			unchecked
			{
				fastAABBTransform = Matrix4X4.Identity;
				fastAABBTransform[0, 0] = double.MinValue;
				changedCount++;
			}
		}
Exemplo n.º 12
0
        public Camera(Camera cameraToCopy)
        {
            this.cameraFOV = cameraToCopy.cameraFOV;
            this.distanceToCameraPlane = cameraToCopy.distanceToCameraPlane;

            this.axisToWorld = cameraToCopy.axisToWorld;

            this.widthInPixels = cameraToCopy.widthInPixels;
            this.heightInPixels = cameraToCopy.heightInPixels;
        }
		private static void TransformVector(Vector3 vec, ref Matrix4X4 mat, out Vector3 result)
		{
			result.x = vec.x * mat.Row0.x +
					   vec.y * mat.Row1.x +
					   vec.z * mat.Row2.x;

			result.y = vec.x * mat.Row0.y +
					   vec.y * mat.Row1.y +
					   vec.z * mat.Row2.y;

			result.z = vec.x * mat.Row0.z +
					   vec.y * mat.Row1.z +
					   vec.z * mat.Row2.z;
		}
Exemplo n.º 14
0
		static public Frustum Transform(Frustum frustum, Matrix4X4 matrix)
		{
			Frustum transformedFrustum = new Frustum();
			transformedFrustum.plane = new Plane[frustum.plane.Length];
			for (int i = 0; i < frustum.plane.Length; ++i)
			{
				Vector3 planeNormal = frustum.plane[i].planeNormal;
				double distanceToPlane = frustum.plane[i].distanceToPlaneFromOrigin;
				transformedFrustum.plane[i].planeNormal = Vector3.TransformNormal(planeNormal, matrix);
				Vector3 pointOnPlane = planeNormal * distanceToPlane;
				Vector3 pointOnTransformedPlane = Vector3.TransformNormal(pointOnPlane, matrix);
				transformedFrustum.plane[i].distanceToPlaneFromOrigin = Vector3.Dot(transformedFrustum.plane[i].planeNormal, pointOnTransformedPlane);
			}

			return transformedFrustum;
		}
		public void SetPrintLevelingEquation(Vector3 position0, Vector3 position1, Vector3 position2, Vector2 bedCenter)
		{
			if (position0 == position1 || position1 == position2 || position2 == position0)
			{
				return;
			}

			Plane planeOfPoints = new Plane(position0, position1, position2);

			Ray ray = new Ray(new Vector3(bedCenter, 0), Vector3.UnitZ);
			bool inFront;
			double distanceToPlaneAtBedCenter = planeOfPoints.GetDistanceToIntersection(ray, out inFront);

			Matrix4X4 makePointsFlatMatrix = Matrix4X4.CreateTranslation(-bedCenter.x, -bedCenter.y, -distanceToPlaneAtBedCenter);
			makePointsFlatMatrix *= Matrix4X4.CreateRotation(planeOfPoints.PlaneNormal, Vector3.UnitZ);
			makePointsFlatMatrix *= Matrix4X4.CreateTranslation(bedCenter.x, bedCenter.y, 0);//distanceToPlaneAtBedCenter);

			bedLevelMatrix = Matrix4X4.Invert(makePointsFlatMatrix);
		}
Exemplo n.º 16
0
		public AxisAlignedBoundingBox GetAxisAlignedBoundingBox(Matrix4X4 transform)
		{
			bool first = true;
			AxisAlignedBoundingBox totalBounds = null;
			foreach (Mesh mesh in Meshes)
			{
				AxisAlignedBoundingBox bounds = mesh.GetAxisAlignedBoundingBox(transform);
				if (first)
				{
					totalBounds = bounds;
					first = false;
				}
				else
				{
					totalBounds = totalBounds + bounds;
				}
			}

			return totalBounds;
		}
Exemplo n.º 17
0
		private void RenderLine(Matrix4X4 transform, Vector3 start, Vector3 end, RGBA_Bytes color, bool zBuffered = true)
		{
			Vector3 lineCenter = (start + end) / 2;

			Vector3 delta = start - end;
			Matrix4X4 rotateTransform = Matrix4X4.CreateRotation(new Quaternion(Vector3.UnitX + new Vector3(.0001, -.00001, .00002), delta.GetNormal()));
			Matrix4X4 scaleTransform = Matrix4X4.CreateScale((end - start).Length, 1, 1);
			Matrix4X4 lineTransform = scaleTransform * rotateTransform * Matrix4X4.CreateTranslation(lineCenter) * transform;

			if (zBuffered)
			{
				RenderMeshToGl.Render(lineMesh, RGBA_Bytes.Black, lineTransform, RenderTypes.Shaded);
				//drawEvent.graphics2D.Line(cornerPositionScreen, cornerPositionCcwScreen, RGBA_Bytes.Gray);
			}
			else
			{
				// render on top of everything very lightly
				RenderMeshToGl.Render(lineMesh, new RGBA_Bytes(RGBA_Bytes.Black, 5), lineTransform, RenderTypes.Shaded);
			}
		}
Exemplo n.º 18
0
		public string LookForNamedPartRecursive(Solid objectToProcess, Matrix4X4 accumulatedMatrix)
		{
			if (objectToProcess.Name == nameWeAreLookingFor)
			{
				Vector3 position = Vector3.TransformPosition(objectToProcess.GetCenter(), accumulatedMatrix);
				if (outputAsScad)
				{
					string output = "translate([" + position.x.ToString() + ", " + position.y.ToString() + ", " + position.z.ToString() + "])\n";
					output += "sphere(1, $fn=10);\n";
					return output;
				}
				else
				{
					Vector2 position2D = new Vector2(position.x, position.y);
					return position2D.x.ToString("0.000") + ", " + position2D.y.ToString("0.000") + "\n";
				}
			}

			return "";
		}
Exemplo n.º 19
0
		public override void OnMouseDown(MouseEventArgs mouseEvent)
		{
			// Show transform override
			if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Right)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Rotate;
			}
			else if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Middle)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Translate;
			}

			autoRotating = false;
			base.OnMouseDown(mouseEvent);
			if (meshViewerWidget.TrackballTumbleWidget.UnderMouseState == Agg.UI.UnderMouseState.FirstUnderMouse)
			{
				if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
					&& mouseEvent.Button == MouseButtons.Left
					&& ModifierKeys != Keys.Shift
					&& ModifierKeys != Keys.Control
					&& ModifierKeys != Keys.Alt)
				{
					if (!meshViewerWidget.MouseDownOnInteractionVolume)
					{
						int meshGroupHitIndex;
						IntersectInfo info = new IntersectInfo();
						if (FindMeshGroupHitPosition(mouseEvent.Position, out meshGroupHitIndex, ref info))
						{
							CurrentSelectInfo.HitPlane = new PlaneShape(Vector3.UnitZ, CurrentSelectInfo.PlaneDownHitPos.z, null);
							SelectedMeshGroupIndex = meshGroupHitIndex;

							transformOnMouseDown = SelectedMeshGroupTransform;

							Invalidate();
							CurrentSelectInfo.DownOnPart = true;

							AxisAlignedBoundingBox selectedBounds = meshViewerWidget.GetBoundsForSelection();

							if (info.hitPosition.x < selectedBounds.Center.x)
							{
								if (info.hitPosition.y < selectedBounds.Center.y)
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.LB;
								}
								else
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.LT;
								}
							}
							else
							{
								if (info.hitPosition.y < selectedBounds.Center.y)
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.RB;
								}
								else
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.RT;
								}
							}
						}
						else
						{
							SelectedMeshGroupIndex = -1;
						}

						SelectedTransformChanged?.Invoke(this, null);
					}
				}
			}
		}
Exemplo n.º 20
0
        private void AdjustChildSize(object sender, EventArgs e)
        {
            if (Children.Count > 0)
            {
                var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
                ItemWithTransform.Matrix = Matrix4X4.Identity;
                var scale = Vector3.One;
                if (StretchZ)
                {
                    scale.Z = SizeZ / aabb.ZSize;
                }

                ItemWithTransform.Matrix = ItemWithTransform.Matrix.ApplyAtPosition(aabb.Center, Matrix4X4.CreateScale(scale));

                Matrix4X4 centering;
                if (AlternateCentering)
                {
                    centering = GetCenteringTransformVisualCenter(UntransformedChildren, Diameter / 2);
                }
                else
                {
                    centering = GetCenteringTransformExpandedToRadius(UntransformedChildren, Diameter / 2);
                }

                ItemWithTransform.Matrix = ItemWithTransform.Matrix.ApplyAtPosition(aabb.Center, centering);
            }
        }
Exemplo n.º 21
0
        private void AddMirrorControls(FlowLayoutWidget buttonPanel)
        {
            List <GuiWidget> mirrorControls = new List <GuiWidget>();

            double oldFixedWidth = view3DWidget.textImageButtonFactory.FixedWidth;

            view3DWidget.textImageButtonFactory.FixedWidth = view3DWidget.EditButtonHeight;

            FlowLayoutWidget buttonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);

            buttonContainer.HAnchor = HAnchor.ParentLeftRight;

            Button mirrorXButton = view3DWidget.textImageButtonFactory.Generate("X", centerText: true);

            buttonContainer.AddChild(mirrorXButton);
            mirrorControls.Add(mirrorXButton);
            mirrorXButton.Click += (object sender, EventArgs mouseEvent) =>
            {
                if (view3DWidget.SelectedMeshGroupIndex != -1)
                {
                    view3DWidget.SelectedMeshGroup.ReverseFaceEdges();
                    view3DWidget.SelectedMeshGroupTransform = PlatingHelper.ApplyAtCenter(view3DWidget.SelectedMeshGroup, view3DWidget.SelectedMeshGroupTransform, Matrix4X4.CreateScale(-1, 1, 1));
                    view3DWidget.PartHasBeenChanged();
                    Invalidate();
                }
            };

            Button mirrorYButton = view3DWidget.textImageButtonFactory.Generate("Y", centerText: true);

            buttonContainer.AddChild(mirrorYButton);
            mirrorControls.Add(mirrorYButton);
            mirrorYButton.Click += (object sender, EventArgs mouseEvent) =>
            {
                if (view3DWidget.SelectedMeshGroupIndex != -1)
                {
                    view3DWidget.SelectedMeshGroup.ReverseFaceEdges();
                    view3DWidget.SelectedMeshGroupTransform = PlatingHelper.ApplyAtCenter(view3DWidget.SelectedMeshGroup, view3DWidget.SelectedMeshGroupTransform, Matrix4X4.CreateScale(1, -1, 1));
                    view3DWidget.PartHasBeenChanged();
                    Invalidate();
                }
            };

            Button mirrorZButton = view3DWidget.textImageButtonFactory.Generate("Z", centerText: true);

            buttonContainer.AddChild(mirrorZButton);
            mirrorControls.Add(mirrorZButton);
            mirrorZButton.Click += (object sender, EventArgs mouseEvent) =>
            {
                if (view3DWidget.SelectedMeshGroupIndex != -1)
                {
                    view3DWidget.SelectedMeshGroup.ReverseFaceEdges();
                    view3DWidget.SelectedMeshGroupTransform = PlatingHelper.ApplyAtCenter(view3DWidget.SelectedMeshGroup, view3DWidget.SelectedMeshGroupTransform, Matrix4X4.CreateScale(1, 1, -1));
                    view3DWidget.PartHasBeenChanged();
                    Invalidate();
                }
            };
            buttonPanel.AddChild(buttonContainer);
            buttonPanel.AddChild(view3DWidget.GenerateHorizontalRule());
            view3DWidget.textImageButtonFactory.FixedWidth = oldFixedWidth;
        }
Exemplo n.º 22
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            using (RebuildLock())
            {
                using (new CenterAndHeightMaintainer(this))
                {
                    var path = new VertexStorage();
                    path.MoveTo(0, 0);
                    path.LineTo(Math.Sqrt(2), 0);
                    path.LineTo(0, Height);

                    var mesh = VertexSourceToMesh.Revolve(path, 4);
                    mesh.Transform(Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(45)) * Matrix4X4.CreateScale(Width / 2, Depth / 2, 1));
                    Mesh = mesh;
                }
            }

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            return(Task.CompletedTask);
        }
Exemplo n.º 23
0
        public static void Fit(this WorldView world, IObject3D itemToRender, RectangleDouble goalBounds, Matrix4X4 offset)
        {
            AxisAlignedBoundingBox meshBounds = itemToRender.GetAxisAlignedBoundingBox(offset);

            bool   done          = false;
            double scaleFraction = .1;

            // make the target size a portion of the total size
            goalBounds.Inflate(-goalBounds.Width * .1);

            int rescaleAttempts = 0;

            while (!done && rescaleAttempts++ < 500)
            {
                RectangleDouble partScreenBounds = GetScreenBounds(meshBounds, world);

                if (!NeedsToBeSmaller(partScreenBounds, goalBounds))
                {
                    world.Scale     *= 1 + scaleFraction;
                    partScreenBounds = GetScreenBounds(meshBounds, world);

                    // If it crossed over the goal reduct the amount we are adjusting by.
                    if (NeedsToBeSmaller(partScreenBounds, goalBounds))
                    {
                        scaleFraction /= 2;
                    }
                }
                else
                {
                    world.Scale     *= 1 - scaleFraction;
                    partScreenBounds = GetScreenBounds(meshBounds, world);

                    // If it crossed over the goal reduct the amount we are adjusting by.
                    if (!NeedsToBeSmaller(partScreenBounds, goalBounds))
                    {
                        scaleFraction /= 2;
                        if (scaleFraction < .001)
                        {
                            done = true;
                        }
                    }
                }
            }
        }
    public float[] MatrixRotation(Matrix4X4 X, float[] vertex)
    {
        float cosAa = Mathf.Cos(cosA * Mathf.Deg2Rad);
        float sinAa = Mathf.Sin(sinA * Mathf.Deg2Rad);
        float sinBb = Mathf.Sin(sinB * Mathf.Deg2Rad);
        float cosBb = Mathf.Cos(cosB * Mathf.Deg2Rad);

        // cos  -sin  0  0
        // sin   cos  0  0
        //   0     0  1  0
        //   0     0  0  1

        X.matrix[0, 0] = 1;
        X.matrix[1, 1] = 1;
        X.matrix[2, 2] = 1;
        X.matrix[3, 3] = 1;

        X.matrix[0, 3] = dx;
        X.matrix[1, 3] = dy;
        X.matrix[2, 3] = dz;

        Matrix4X4 X2 = new Matrix4X4();

        X2.matrix[3, 3] = 1;

        X2.matrix[0, 0] = sx;
        X2.matrix[1, 1] = sy;
        X2.matrix[2, 2] = sz;

        Matrix4X4 X3 = new Matrix4X4();

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                for (int k = 0; k < 4; k++)
                {
                    X3.matrix[i, j] += X.matrix[i, k] * X2.matrix[k, j];
                }
            }
        }

        Matrix4X4 X4 = new Matrix4X4();

        X4.matrix[0, 0] = 1;
        X4.matrix[1, 1] = 1;
        X4.matrix[2, 2] = 1;
        X4.matrix[3, 3] = 1;

        X4.matrix[0, 3] = -1 * dx;
        X4.matrix[1, 3] = -1 * dy;
        X4.matrix[2, 3] = -1 * dz;

        Matrix4X4 X5 = new Matrix4X4();

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                for (int k = 0; k < 4; k++)
                {
                    X5.matrix[i, j] += X3.matrix[i, k] * X4.matrix[k, j];
                }
            }
        }

        if (isRoll)
        {
            // cos  -sin  0  0
            // sin   cos  0  0
            //   0     0  1  0
            //   0     0  0  1

            X.matrix[2, 2] = 1;
            X.matrix[3, 3] = 1;

            X.matrix[0, 0] = cosAa;
            X.matrix[0, 1] = sinAa * (-1);
            X.matrix[1, 0] = sinBb;
            X.matrix[1, 1] = cosBb;
        }
        else if (ispitch)
        {
            //   1     0     0   0
            //   0   cos  -sin   0
            //   0   sin   cos   0
            //   0     0     0   1

            X.matrix[0, 0] = 1;
            X.matrix[3, 3] = 1;

            X.matrix[1, 1] = cosAa;
            X.matrix[1, 2] = sinAa * (-1);
            X.matrix[2, 1] = sinBb;
            X.matrix[2, 2] = cosBb;
        }
        else if (isYaw)
        {
            //   cos   0  sin  0
            //     0   1    0  0
            //  -sin   0  cos  0
            //     0   0    0  1
            X.matrix[1, 1] = 1;
            X.matrix[3, 3] = 1;

            X.matrix[0, 0] = cosAa;
            X.matrix[0, 2] = sinAa;
            X.matrix[2, 0] = sinBb * (-1);
            X.matrix[2, 2] = cosBb;
        }

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                X5.matrix[i, j] *= vertex[j];
            }
        }

        float[] x = new float[4];
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                x[i] += X5.matrix[i, j];
            }
        }
        return(x);
    }
Exemplo n.º 25
0
        private static bool CheckPosition(IEnumerable <IObject3D> itemsToAvoid, IObject3D itemToMove, 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       = 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();
                    AxisAlignedBoundingBox intersection       = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds);
                    if (intersection.XSize > 0 && intersection.YSize > 0)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 26
0
        static public void CreateCylinder(VectorPOD <ColorVertexData> colorVertexData, VectorPOD <int> indexData, Vector3 startPos, Vector3 endPos, double radius, int steps, Color color, double layerHeight)
        {
            Vector3 direction           = endPos - startPos;
            Vector3 directionNormal     = direction.GetNormal();
            Vector3 startSweepDirection = Vector3.GetPerpendicular(startPos, endPos).GetNormal();

            int[] tubeStartIndices = new int[steps];
            int[] tubeEndIndices   = new int[steps];

            int[] capStartIndices = new int[steps];
            int[] capEndIndices   = new int[steps];

            double halfHeight = layerHeight / 2 + (layerHeight * .1);
            double halfWidth  = radius;
            double zScale     = halfHeight / radius;
            double xScale     = halfWidth / radius;

            // Adjust start/end positions to be centered on Z for the given layer height
            startPos.Z -= halfHeight;
            endPos.Z   -= halfHeight;

            Vector3 scale = new Vector3(xScale, xScale, zScale);

            for (int i = 0; i < steps; i++)
            {
                // create tube ends verts
                Vector3 tubeNormal = Vector3.Transform(startSweepDirection, Matrix4X4.CreateRotation(direction, MathHelper.Tau / (steps * 2) + MathHelper.Tau / (steps) * i));
                Vector3 offset     = Vector3.Transform(startSweepDirection * radius, Matrix4X4.CreateRotation(direction, MathHelper.Tau / (steps * 2) + MathHelper.Tau / (steps) * i));
                offset *= scale;

                Vector3 tubeStart = startPos + offset;
                tubeStartIndices[i] = colorVertexData.Count;
                colorVertexData.Add(new ColorVertexData(tubeStart, tubeNormal, color));

                Vector3 tubeEnd = endPos + offset;
                tubeEndIndices[i] = colorVertexData.Count;
                colorVertexData.Add(new ColorVertexData(tubeEnd, tubeNormal, color));

                // create cap verts
                Vector3 rotateAngle    = Vector3.Cross(startSweepDirection, direction);
                Vector3 capStartNormal = Vector3.Transform(startSweepDirection, Matrix4X4.CreateRotation(rotateAngle, MathHelper.Tau / 8));
                capStartNormal = Vector3.Transform(capStartNormal, Matrix4X4.CreateRotation(direction, MathHelper.Tau / (steps * 2) + MathHelper.Tau / (steps) * i));
                capStartNormal = (capStartNormal * scale).GetNormal();
                Vector3 capStartOffset = capStartNormal * radius;
                capStartOffset *= scale;
                Vector3 capStart = startPos + capStartOffset;
                capStartIndices[i] = colorVertexData.Count;
                colorVertexData.Add(new ColorVertexData(capStart, capStartNormal, color));

                Vector3 capEndNormal = Vector3.Transform(startSweepDirection, Matrix4X4.CreateRotation(-rotateAngle, MathHelper.Tau / 8));
                capEndNormal = Vector3.Transform(capEndNormal, Matrix4X4.CreateRotation(direction, MathHelper.Tau / (steps * 2) + MathHelper.Tau / (steps) * i));
                capEndNormal = (capEndNormal * scale).GetNormal();
                Vector3 capEndOffset = capEndNormal * radius;
                capEndOffset *= scale;
                Vector3 capEnd = endPos + capEndOffset;
                capEndIndices[i] = colorVertexData.Count;
                colorVertexData.Add(new ColorVertexData(capEnd, capEndNormal, color));
            }

            int     tipStartIndex = colorVertexData.Count;
            Vector3 tipOffset     = directionNormal * radius;

            tipOffset *= scale;
            colorVertexData.Add(new ColorVertexData(startPos - tipOffset, -directionNormal, color));
            int tipEndIndex = colorVertexData.Count;

            colorVertexData.Add(new ColorVertexData(endPos + tipOffset, directionNormal, color));

            for (int i = 0; i < steps; i++)
            {
                // create tube polys
                indexData.Add(tubeStartIndices[i]);
                indexData.Add(tubeEndIndices[i]);
                indexData.Add(tubeEndIndices[(i + 1) % steps]);

                indexData.Add(tubeStartIndices[i]);
                indexData.Add(tubeEndIndices[(i + 1) % steps]);
                indexData.Add(tubeStartIndices[(i + 1) % steps]);

                // create start cap polys
                indexData.Add(tubeStartIndices[i]);
                indexData.Add(capStartIndices[i]);
                indexData.Add(capStartIndices[(i + 1) % steps]);

                indexData.Add(tubeStartIndices[i]);
                indexData.Add(capStartIndices[(i + 1) % steps]);
                indexData.Add(tubeStartIndices[(i + 1) % steps]);

                // create end cap polys
                indexData.Add(tubeEndIndices[i]);
                indexData.Add(capEndIndices[i]);
                indexData.Add(capEndIndices[(i + 1) % steps]);

                indexData.Add(tubeEndIndices[i]);
                indexData.Add(capEndIndices[(i + 1) % steps]);
                indexData.Add(tubeEndIndices[(i + 1) % steps]);

                // create start tip polys
                indexData.Add(tipStartIndex);
                indexData.Add(capStartIndices[i]);
                indexData.Add(capStartIndices[(i + 1) % steps]);

                // create end tip polys
                indexData.Add(tipEndIndex);
                indexData.Add(capEndIndices[i]);
                indexData.Add(capEndIndices[(i + 1) % steps]);
            }
        }
Exemplo n.º 27
0
        override public Task Rebuild()
        {
            this.DebugDepth("Rebuild");
            bool valuesChanged = Diameter == double.MinValue;

            if (StartPercent < 0 ||
                StartPercent > 100)
            {
                StartPercent  = Math.Min(100, Math.Max(0, StartPercent));
                valuesChanged = true;
            }

            using (RebuildLock())
            {
                ResetMeshWrapperMeshes(Object3DPropertyFlags.All, CancellationToken.None);

                // remember the current matrix then clear it so the parts will rotate at the original wrapped position
                var currentMatrix = Matrix;
                Matrix = Matrix4X4.Identity;

                var meshWrapperEnumerator = WrappedObjects();

                var aabb = this.GetAxisAlignedBoundingBox();

                if (Diameter == double.MinValue)
                {
                    // uninitialized set to a reasonable value
                    Diameter = (int)aabb.XSize;
                    // TODO: ensure that the editor display value is updated
                }

                if (Diameter > 0)
                {
                    var radius        = Diameter / 2;
                    var circumference = MathHelper.Tau * radius;
                    rotationCenter = new Vector2(aabb.MinXYZ.X + (aabb.MaxXYZ.X - aabb.MinXYZ.X) * (StartPercent / 100), aabb.MaxXYZ.Y + radius);
                    foreach (var object3Ds in meshWrapperEnumerator)
                    {
                        var matrix = object3Ds.original.WorldMatrix(this);
                        if (!BendCcw)
                        {
                            // rotate around so it will bend correctly
                            matrix *= Matrix4X4.CreateTranslation(0, -aabb.MaxXYZ.Y, 0);
                            matrix *= Matrix4X4.CreateRotationX(MathHelper.Tau / 2);
                            matrix *= Matrix4X4.CreateTranslation(0, aabb.MaxXYZ.Y - aabb.YSize, 0);
                        }

                        var matrixInv = matrix.Inverted;

                        var curvedMesh = object3Ds.meshCopy.Mesh;

                        // split long edges so it will be curved
                        if (false)
                        {
                            double numRotations   = aabb.XSize / circumference;
                            double numberOfCuts   = numRotations * MinSidesPerRotation;
                            var    maxXLength     = aabb.XSize / numberOfCuts;
                            var    maxXLengthSqrd = maxXLength * maxXLength;

                            // convert the mesh into vertex and face arrays
                            double[] v;
                            int[]    f;
                            v = curvedMesh.Vertices.ToDoubleArray(object3Ds.meshCopy.Matrix);
                            f = curvedMesh.Faces.ToIntArray();

                            // make lists so we can add to them
                            var vL = v.ToVector3List();
                            vL.Transform(matrix);
                            var fL = new FaceList(f, curvedMesh.Vertices);

                            Teselate.SplitEdges(vL, fL, maxXLength);
                            vL.Transform(matrixInv);

                            // convert the lists back into the mesh
                            object3Ds.meshCopy.Mesh = new Mesh(vL, fL);
                            curvedMesh = object3Ds.meshCopy.Mesh;
                        }

                        for (int i = 0; i < curvedMesh.Vertices.Count; i++)
                        {
                            var worldPosition = curvedMesh.Vertices[i].Transform((Matrix4X4)matrix);

                            var angleToRotate      = ((worldPosition.X - rotationCenter.X) / circumference) * MathHelper.Tau - MathHelper.Tau / 4;
                            var distanceFromCenter = rotationCenter.Y - worldPosition.Y;

                            var rotatePosition = new Vector3Float(Math.Cos(angleToRotate), Math.Sin(angleToRotate), 0) * distanceFromCenter;
                            rotatePosition.Z = worldPosition.Z;
                            var worldWithBend = rotatePosition + new Vector3Float(rotationCenter.X, radius + aabb.MaxXYZ.Y, 0);
                            curvedMesh.Vertices[i] = worldWithBend.Transform(matrixInv);
                        }

                        curvedMesh.MarkAsChanged();
                        curvedMesh.CalculateNormals();
                    }

                    if (!BendCcw)
                    {
                        // fix the stored center so we draw correctly
                        rotationCenter = new Vector2(rotationCenter.X, aabb.MinXYZ.Y - radius);
                    }
                }

                // set the matrix back
                Matrix = currentMatrix;
            }

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            if (valuesChanged)
            {
                Invalidate(InvalidateType.DisplayValues);
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 28
0
		public static Matrix4X4 ApplyAtPosition(this Matrix4X4 currentTransform, Vector3 positionToApplyAt, Matrix4X4 transformToApply)
		{
			currentTransform *= Matrix4X4.CreateTranslation(-positionToApplyAt);
			currentTransform *= transformToApply;
			currentTransform *= Matrix4X4.CreateTranslation(positionToApplyAt);

			return currentTransform;
		}
Exemplo n.º 29
0
		public static Matrix4X4 ApplyAtPosition(this IObject3D item, Vector3 positionToApplyAt, Matrix4X4 transformToApply)
		{
			return item.Matrix.ApplyAtPosition(positionToApplyAt, transformToApply);
		}
Exemplo n.º 30
0
		public static Matrix4X4 ApplyAtCenter(this Matrix4X4 currentTransform, AxisAlignedBoundingBox boundsToApplyTo, Matrix4X4 transformToApply)
		{
			return ApplyAtPosition(currentTransform, boundsToApplyTo.Center, transformToApply);
		}
Exemplo n.º 31
0
		public static Matrix4X4 ApplyAtBoundsCenter(this IObject3D objectWithBounds, Matrix4X4 transformToApply)
		{
			return ApplyAtCenter(objectWithBounds.Matrix, objectWithBounds.GetAxisAlignedBoundingBox(Matrix4X4.Identity), transformToApply);
		}
Exemplo n.º 32
0
		public static void Render(Mesh meshToRender, IColorType partColor, Matrix4X4 transform, RenderTypes renderType)
		{
			if (meshToRender != null)
			{
				GL.Color4(partColor.Red0To255, partColor.Green0To255, partColor.Blue0To255, partColor.Alpha0To255);

				if (partColor.Alpha0To1 < 1)
				{
					GL.Enable(EnableCap.Blend);
				}
				else
				{
					GL.Disable(EnableCap.Blend);
				}

				GL.MatrixMode(MatrixMode.Modelview);
				GL.PushMatrix();
				GL.MultMatrix(transform.GetAsFloatArray());

				switch (renderType)
				{
					case RenderTypes.Hidden:
						break;

					case RenderTypes.Shaded:
						DrawToGL(meshToRender);
						break;

					case RenderTypes.Polygons:
					case RenderTypes.Outlines:
						DrawWithWireOverlay(meshToRender, renderType);
						break;
				}

				GL.PopMatrix();
			}
		}
Exemplo n.º 33
0
		public static IObject3D Scale(this IObject3D objectToTranslate, Vector3 translation, string name = "")
		{
			objectToTranslate.Matrix *= Matrix4X4.CreateScale(translation);
			return objectToTranslate;
		}
Exemplo n.º 34
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);
        }
Exemplo n.º 35
0
        private (Vector3 edge, Vector3 otherSide) GetHitPosition(IObject3D selectedItem)
        {
            Vector3 GetEdgePosition(IObject3D item, double angle, ObjectSpace.Placement placement)
            {
                var aabb           = item.GetAxisAlignedBoundingBox(item.Matrix.Inverted);
                var centerPosition = aabb.Center;

                switch (placement)
                {
                case ObjectSpace.Placement.Bottom:
                    centerPosition.Z = aabb.MinXYZ.Z;
                    break;

                case ObjectSpace.Placement.Center:
                    centerPosition.Z = aabb.Center.Z;
                    break;

                case ObjectSpace.Placement.Top:
                    centerPosition.Z = aabb.MaxXYZ.Z;
                    break;
                }

                var offset = new Vector3(getDiameters[diameterIndex]() / 2, 0, 0).Transform(Matrix4X4.CreateRotationZ(angle + angleOffset));

                centerPosition += offset;

                return(centerPosition.Transform(item.Matrix));
            }

            var bestZEdgePosition = Vector3.Zero;
            var otherSide         = Vector3.Zero;
            var bestCornerZ       = double.PositiveInfinity;
            // get the closest z on the bottom in view space
            var rotations = 16;

            for (int i = 0; i < rotations; i++)
            {
                Vector3 cornerPosition    = GetEdgePosition(selectedItem, MathHelper.Tau * i / rotations, placement);
                Vector3 cornerScreenSpace = Object3DControlContext.World.WorldToScreenSpace(cornerPosition);
                if (cornerScreenSpace.Z < bestCornerZ)
                {
                    bestCornerZ       = cornerScreenSpace.Z;
                    bestZEdgePosition = cornerPosition;
                    otherSide         = GetEdgePosition(selectedItem, MathHelper.Tau * i / rotations + MathHelper.Tau / 2, placement);
                }
            }

            return(bestZEdgePosition, otherSide);
        }
Exemplo n.º 36
0
		public override void OnMouseDown(MouseEvent3DArgs mouseEvent3D)
		{
			zHitHeight = mouseEvent3D.info.hitPosition.z;
			lastMoveDelta = new Vector3();
			double distanceToHit = Vector3.Dot(mouseEvent3D.info.hitPosition, mouseEvent3D.MouseRay.directionNormal);
			hitPlane = new PlaneShape(mouseEvent3D.MouseRay.directionNormal, distanceToHit, null);

			IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);
			zHitHeight = info.hitPosition.z;
			transformOnMouseDown = MeshViewerToDrawWith.SelectedMeshGroupTransform;

			base.OnMouseDown(mouseEvent3D);
		}
Exemplo n.º 37
0
        /// <summary>
        /// Create a bounding volume hierarchy for the give mesh.
        /// </summary>
        /// <param name="mesh">The mesh to add the BVH to.</param>
        /// <param name="material">The tracing material to use.</param>
        /// <param name="matrix">A transformation to apply to the trace data</param>
        /// <param name="maxRecursion">The max depth to create the BVH tree.</param>
        /// <returns>The created BVH tree.</returns>
        public static IPrimitive CreateBVHData(this Mesh mesh, MaterialAbstract material, Matrix4X4 matrix, int maxRecursion = int.MaxValue)
        {
            var allPolys = new List <IPrimitive>();

            mesh.AddTracePrimitives(material, matrix, allPolys);

            return(BoundingVolumeHierarchy.CreateNewHierachy(allPolys, maxRecursion));
        }
Exemplo n.º 38
0
		//Mouse drag, calculate rotation
		public void OnMouseMove(Vector2 mousePosition)
		{
			switch (currentTrackingType)
			{
				case MouseDownType.Rotation:
					activeRotationQuaternion = Quaternion.Identity;
					//Map the point to the sphere
					MapToSphere(mousePosition, out rotationCurrent);

					//Return the quaternion equivalent to the rotation
					//Compute the vector perpendicular to the begin and end vectors
					Vector3 Perp = Vector3.Cross(rotationStart, rotationCurrent);

					//Compute the length of the perpendicular vector
					if (Perp.Length > Epsilon)
					{
						//if its non-zero
						//We're ok, so return the perpendicular vector as the transform after all
						activeRotationQuaternion.X = Perp.x;
						activeRotationQuaternion.Y = Perp.y;
						activeRotationQuaternion.Z = Perp.z;
						//In the quaternion values, w is cosine (theta / 2), where theta is the rotation angle
						activeRotationQuaternion.W = Vector3.Dot(rotationStart, rotationCurrent);
						OnTransformChanged(null);
					}
					break;

				case MouseDownType.Translation:
					{
						Vector2 mouseDelta = mousePosition - lastTranslationMousePosition;
						Vector2 scaledDelta = mouseDelta / screenCenter.x * 4.75;
						Vector3 offset = new Vector3(scaledDelta.x, scaledDelta.y, 0);
						offset = Vector3.TransformPosition(offset, Matrix4X4.Invert(CurrentRotation));
						offset = Vector3.TransformPosition(offset, localToScreenTransform);
						currentTranslationMatrix = currentTranslationMatrix * Matrix4X4.CreateTranslation(offset);
						lastTranslationMousePosition = mousePosition;
						OnTransformChanged(null);
					}
					break;

				case MouseDownType.Scale:
					{
						Vector2 mouseDelta = mousePosition - lastScaleMousePosition;
						double zoomDelta = 1;
						if (mouseDelta.y < 0)
						{
							zoomDelta = 1 - (-1 * mouseDelta.y / 100);
						}
						else if (mouseDelta.y > 0)
						{
							zoomDelta = 1 + (1 * mouseDelta.y / 100);
						}
						currentTranslationMatrix *= Matrix4X4.CreateScale(zoomDelta);
						lastScaleMousePosition = mousePosition;
						OnTransformChanged(null);
					}
					break;

				default:
					throw new NotImplementedException();
			}
		}
        public override Task Rebuild()
        {
            // Point Size 10
            // Height 1
            // Font Fredoka

            // Align
            // X: Right Right -11
            // Y: Front -.3
            // Z: Bottom .8

            this.DebugDepth("Rebuild");
            bool valuesChanged = false;

            using (RebuildLock())
            {
                MaxTemperature = agg_basics.Clamp(MaxTemperature, 140, 400, ref valuesChanged);
                Sections       = agg_basics.Clamp(Sections, 2, 20, ref valuesChanged);
                ChangeAmount   = agg_basics.Clamp(ChangeAmount, 1, 30, ref valuesChanged);

                using (new CenterAndHeightMaintainer(this))
                {
                    Children.Modify(async(children) =>
                    {
                        children.Clear();

                        // add the base
                        var towerBase = new Object3D()
                        {
                            Mesh = new RoundedRect(-25, -15, 25, 15, 3)
                            {
                                ResolutionScale = 10
                            }.Extrude(BaseHeight),
                            Name = "Base"
                        };

                        children.Add(towerBase);

                        // Add each section
                        for (int i = 0; i < Sections; i++)
                        {
                            var temp    = MaxTemperature - i * ChangeAmount;
                            var section = new Object3D()
                            {
                                Matrix = Matrix4X4.CreateTranslation(0, 0, BaseHeight + i * SectionHeight),
                                Name   = $"{temp:0.##}"
                            };
                            children.Add(section);
                            // Add base mesh
                            section.Children.Add(new Object3D()
                            {
                                Mesh = shape,
                                Name = "CC - gaaZolee - AS"
                            });
                            // Add temp changer
                            section.Children.Add(new SetTemperatureObject3D()
                            {
                                Temperature = temp,
                                Name        = $"Set to {temp:0.##}",
                                Matrix      = Matrix4X4.CreateScale(.2, .1, 1)
                            });
                            // Add temperature text
                            var text = new TextObject3D()
                            {
                                Font        = NamedTypeFace.Fredoka,
                                Height      = 1,
                                Name        = $"{temp:0.##}",
                                PointSize   = 10,
                                NameToWrite = $"{temp:0.##}",
                                Matrix      = Matrix4X4.CreateRotationX(MathHelper.Tau / 4) * Matrix4X4.CreateTranslation(0, -4.3, .8),
                            };
                            text.Rebuild().Wait();
                            var textBounds = text.GetAxisAlignedBoundingBox();
                            text.Matrix   *= Matrix4X4.CreateTranslation(11 - textBounds.MaxXYZ.X, 0, 0);
                            section.Children.Add(text);
                        }
                    });
                }
            }

            Invalidate(InvalidateType.DisplayValues);

            Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh));
            return(Task.CompletedTask);
        }
Exemplo n.º 40
0
		public void OnMouseWheel(int wheelDelta)
		{
			double zoomDelta = 1;
			if (wheelDelta > 0)
			{
				zoomDelta = 1.2;
			}
			else if (wheelDelta < 0)
			{
				zoomDelta = .8;
			}

			currentTranslationMatrix *= Matrix4X4.CreateScale(zoomDelta);
			OnTransformChanged(null);
		}
Exemplo n.º 41
0
        public void SubtractIcosahedronsWorks()
        {
            Vector3 centering = new Vector3(100, 100, 20);
            Mesh    meshA     = PlatonicSolids.CreateIcosahedron(35);

            meshA.Translate(centering);
            Mesh meshB = PlatonicSolids.CreateIcosahedron(35);

            Vector3   finalTransform = new Vector3(105.240172225344, 92.9716306394062, 18.4619570261172);
            Vector3   rotCurrent     = new Vector3(4.56890223673623, -2.67874102322035, 1.02768848238523);
            Vector3   scaleCurrent   = new Vector3(1.07853517569753, 0.964980885267323, 1.09290934544604);
            Matrix4X4 transformB     = Matrix4X4.CreateScale(scaleCurrent) * Matrix4X4.CreateRotation(rotCurrent) * Matrix4X4.CreateTranslation(finalTransform);

            meshB.Transform(transformB);

            Mesh meshToAdd = CsgOperations.Subtract(meshA, meshB);

            AxisAlignedBoundingBox a_aabb         = meshA.GetAxisAlignedBoundingBox();
            AxisAlignedBoundingBox b_aabb         = meshB.GetAxisAlignedBoundingBox();
            AxisAlignedBoundingBox intersect_aabb = meshToAdd.GetAxisAlignedBoundingBox();

            Assert.IsTrue(a_aabb.XSize == 40 && a_aabb.YSize == 40 && a_aabb.ZSize == 40);
            Assert.IsTrue(intersect_aabb.XSize == 40 && intersect_aabb.YSize == 40 && intersect_aabb.ZSize == 40);
        }
Exemplo n.º 42
0
        public static void AddTracePrimitives(this Mesh mesh, MaterialAbstract material, Matrix4X4 matrix, List <IPrimitive> tracePrimitives)
        {
            for (int faceIndex = 0; faceIndex < mesh.Faces.Count; faceIndex++)
            {
                var face = mesh.Faces[faceIndex];

                IPrimitive triangle;
                if (material != null)
                {
                    triangle = new TriangleShape(
                        mesh.Vertices[face.v0].Transform(matrix),
                        mesh.Vertices[face.v1].Transform(matrix),
                        mesh.Vertices[face.v2].Transform(matrix),
                        material);
                }
                else
                {
                    triangle = new MinimalTriangle((fi, vi) =>
                    {
                        switch (vi)
                        {
                        case 0:
                            return(mesh.Vertices[mesh.Faces[fi].v0]);

                        case 1:
                            return(mesh.Vertices[mesh.Faces[fi].v1]);

                        default:
                            return(mesh.Vertices[mesh.Faces[fi].v2]);
                        }
                    }, faceIndex);
                }

                tracePrimitives.Add(triangle);
            }
        }
Exemplo n.º 43
0
 public static IObject3D Translate(this IObject3D objectToTranslate, Vector3 translation, string name = "")
 {
     objectToTranslate.Matrix *= Matrix4X4.CreateTranslation(translation);
     return(objectToTranslate);
 }
Exemplo n.º 44
0
        public static BspNode RenderOrder(this BspNode node, List <Face> meshFaces, Matrix4X4 meshToViewTransform, Matrix4X4 invMeshToViewTransform)
        {
            var faceNormalInViewSpace  = Vector3.TransformNormalInverse(meshFaces[node.Index].Normal, invMeshToViewTransform);
            var pointOnFaceInViewSpace = Vector3.Transform(meshFaces[node.Index].firstFaceEdge.FirstVertex.Position, meshToViewTransform);
            var infrontOfFace          = Vector3.Dot(faceNormalInViewSpace, pointOnFaceInViewSpace) < 0;

            if (infrontOfFace)
            {
                return(new BspNode()
                {
                    Index = node.Index,
                    BackNode = node.BackNode,
                    FrontNode = node.FrontNode
                });
            }
            else
            {
                return(new BspNode()
                {
                    Index = node.Index,
                    BackNode = node.FrontNode,
                    FrontNode = node.BackNode
                });
            }
        }
Exemplo n.º 45
0
		private void CreateBooleanTestGeometry(GuiWidget drawingWidget, DrawEventArgs e)
		{
			try
			{
				booleanGroup = new MeshGroup();

				booleanGroup.Meshes.Add(ApplyBoolean(PolygonMesh.Csg.CsgOperations.Union, AxisAlignedBoundingBox.Union, new Vector3(100, 0, 20), "U"));
				booleanGroup.Meshes.Add(ApplyBoolean(PolygonMesh.Csg.CsgOperations.Subtract, null, new Vector3(100, 100, 20), "S"));
				booleanGroup.Meshes.Add(ApplyBoolean(PolygonMesh.Csg.CsgOperations.Intersect, AxisAlignedBoundingBox.Intersection , new Vector3(100, 200, 20), "I"));

				offset += direction;
				rotCurrent += rotChange;
				scaleCurrent += scaleChange;
				meshViewerWidget.MeshGroups.Add(booleanGroup);

				groupTransform = Matrix4X4.Identity;
				meshViewerWidget.MeshGroupTransforms.Add(groupTransform);
			}
			catch(Exception e2)
			{
				string text = e2.Message;
                int a = 0;
			}
		}
Exemplo n.º 46
0
        /// <summary>
        /// Get an ordered list of the faces to render based on the camera position.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="meshToViewTransform"></param>
        /// <param name="invMeshToViewTransform"></param>
        /// <param name="faceRenderOrder"></param>
        public static IEnumerable <Face> GetFacesInVisibiltyOrder(List <Face> meshFaces, BspNode root, Matrix4X4 meshToViewTransform, Matrix4X4 invMeshToViewTransform)
        {
            var renderOrder = new Stack <BspNode>(new BspNode[] { root.RenderOrder(meshFaces, meshToViewTransform, invMeshToViewTransform) });

            do
            {
                var lastBack = renderOrder.Peek().BackNode;
                while (lastBack != null &&
                       lastBack.Index != -1)
                {
                    renderOrder.Peek().BackNode = null;
                    renderOrder.Push(lastBack.RenderOrder(meshFaces, meshToViewTransform, invMeshToViewTransform));
                    lastBack = renderOrder.Peek().BackNode;
                }

                var node = renderOrder.Pop();
                if (node.Index != -1)
                {
                    yield return(meshFaces[node.Index]);
                }
                var lastFront = node.FrontNode;
                if (lastFront != null && lastFront.Index != -1)
                {
                    renderOrder.Push(lastFront.RenderOrder(meshFaces, meshToViewTransform, invMeshToViewTransform));
                }
            } while (renderOrder.Any());
        }
Exemplo n.º 47
0
        public static void Render3DLineNoPrep(this WorldView world, Frustum clippingFrustum, Vector3 start, Vector3 end, Color color, double width = 1)
        {
            if (clippingFrustum.ClipLine(ref start, ref end))
            {
                double unitsPerPixelStart = world.GetWorldUnitsPerScreenPixelAtPosition(start);
                double unitsPerPixelEnd   = world.GetWorldUnitsPerScreenPixelAtPosition(end);

                Vector3   delta           = start - end;
                var       deltaLength     = delta.Length;
                var       rotateTransform = Matrix4X4.CreateRotation(new Quaternion(Vector3.UnitX + new Vector3(.0001, -.00001, .00002), -delta / deltaLength));
                var       scaleTransform  = Matrix4X4.CreateScale(deltaLength, 1, 1);
                Vector3   lineCenter      = (start + end) / 2;
                Matrix4X4 lineTransform   = scaleTransform * rotateTransform * Matrix4X4.CreateTranslation(lineCenter);

                var startScale = unitsPerPixelStart * width;
                var endScale   = unitsPerPixelEnd * width;
                for (int i = 0; i < unscaledLineMesh.Vertices.Count; i++)
                {
                    var vertexPosition = unscaledLineMesh.Vertices[i];
                    if (vertexPosition.X < 0)
                    {
                        scaledLineMesh.Vertices[i] = new Vector3Float(vertexPosition.X, vertexPosition.Y * startScale, vertexPosition.Z * startScale);
                    }
                    else
                    {
                        scaledLineMesh.Vertices[i] = new Vector3Float(vertexPosition.X, vertexPosition.Y * endScale, vertexPosition.Z * endScale);
                    }
                }

                if (true)
                {
                    GL.Color4(color.Red0To255, color.Green0To255, color.Blue0To255, color.Alpha0To255);

                    if (color.Alpha0To1 < 1)
                    {
                        GL.Enable(EnableCap.Blend);
                    }
                    else
                    {
                        // GL.Disable(EnableCap.Blend);
                    }

                    GL.MatrixMode(MatrixMode.Modelview);
                    GL.PushMatrix();
                    GL.MultMatrix(lineTransform.GetAsFloatArray());

                    GL.Begin(BeginMode.Triangles);
                    for (int faceIndex = 0; faceIndex < scaledLineMesh.Faces.Count; faceIndex++)
                    {
                        var face     = scaledLineMesh.Faces[faceIndex];
                        var vertices = scaledLineMesh.Vertices;
                        var position = vertices[face.v0];
                        GL.Vertex3(position.X, position.Y, position.Z);
                        position = vertices[face.v1];
                        GL.Vertex3(position.X, position.Y, position.Z);
                        position = vertices[face.v2];
                        GL.Vertex3(position.X, position.Y, position.Z);
                    }

                    GL.End();
                    GL.PopMatrix();
                }
                else
                {
                    scaledLineMesh.MarkAsChanged();

                    GLHelper.Render(scaledLineMesh, color, lineTransform, RenderTypes.Shaded);
                }
            }
        }
 // Getting the Martix for the Mesh
 public Matrix4X4 GetWorldMatrix()
 {
     return(Matrix4X4.Trs(Position, Rotation, Scale));
 }
Exemplo n.º 49
0
        public ScaleTopControl(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;
        }
Exemplo n.º 50
0
        public void Draw(GuiWidget sender, IObject3D item, bool isSelected, DrawEventArgs e, Matrix4X4 itemMaxtrix, WorldView world)
        {
            if (isSelected && scene.DrawSelection)
            {
                var    selectionColor = Color.White;
                double secondsSinceSelectionChanged = (UiThread.CurrentTimerMs - lastSelectionChangedMs) / 1000.0;
                if (secondsSinceSelectionChanged < .5)
                {
                    var accentColor = Color.LightGray;

                    if (secondsSinceSelectionChanged < .25)
                    {
                        selectionColor = Color.White.Blend(accentColor, Quadratic.InOut(secondsSinceSelectionChanged * 4));
                    }
                    else
                    {
                        selectionColor = accentColor.Blend(Color.White, Quadratic.InOut((secondsSinceSelectionChanged - .25) * 4));
                    }

                    guiWidget.Invalidate();
                }

                if (item.Color != Color.Transparent)
                {
                    selectionColor = selectionColor.WithAlpha(item.Color.Alpha0To255);
                }

                this.RenderSelection(item, selectionColor, world);
            }
        }
Exemplo n.º 51
0
		//Mouse down
		public void OnMouseDown(Vector2 mousePosition, Matrix4X4 screenToLocal, MouseDownType trackType = MouseDownType.Rotation)
		{
			//if (currentTrackingType == MouseDownType.None)
			{
				localToScreenTransform = Matrix4X4.Invert(screenToLocal);
				currentTrackingType = trackType;
				switch (currentTrackingType)
				{
					case MouseDownType.Rotation:
						MapToSphere(mousePosition, out rotationStart);
						break;

					case MouseDownType.Translation:
						lastTranslationMousePosition = mousePosition;
						break;

					case MouseDownType.Scale:
						lastScaleMousePosition = mousePosition;
						break;

					default:
						throw new NotImplementedException();
				}
			}
		}
Exemplo n.º 52
0
        private void ArrangeMeshGroups()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DONT_COPY);

            // 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;
                }
            }
        }
Exemplo n.º 53
0
		public void OnMouseUp()
		{
			switch (currentTrackingType)
			{
				case MouseDownType.Rotation:
					currentRotationMatrix = currentRotationMatrix * Matrix4X4.CreateRotation(activeRotationQuaternion);
					activeRotationQuaternion = Quaternion.Identity;
					OnTransformChanged(null);
					break;

				case MouseDownType.Translation:
					//currentTranslationMatrix = Matrix4X4.Identity;
					break;

				case MouseDownType.Scale:
					break;

				default:
					throw new NotImplementedException();
			}
			currentTrackingType = MouseDownType.None;
		}
Exemplo n.º 54
0
		public void Reset()
		{
			currentRotationMatrix = Matrix4X4.Identity;
			currentTranslationMatrix = Matrix4X4.Identity;
		}
Exemplo n.º 55
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));
        }
Exemplo n.º 56
0
		public void Rotate(Quaternion rotation)
		{
			currentRotationMatrix = currentRotationMatrix * Matrix4X4.CreateRotation(rotation);
			OnTransformChanged(null);
		}
Exemplo n.º 57
0
		public void Translate(Vector3 deltaPosition)
		{
			currentTranslationMatrix = Matrix4X4.CreateTranslation(deltaPosition) * currentTranslationMatrix;
			OnTransformChanged(null);
		}
Exemplo n.º 58
0
        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(1000, 1000, 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++)
            {
                MeshGroup            meshGroup  = asynchMeshGroups[meshGroupIndex];
                Vector3              meshCenter = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[meshGroupIndex].translation).Center;
                ScaleRotateTranslate atZero     = asynchMeshGroupTransforms[meshGroupIndex];
                atZero.translation = Matrix4X4.Identity;
                asynchMeshGroupTransforms[meshGroupIndex] = atZero;
                PlatingHelper.MoveMeshGroupToOpenPosition(meshGroupIndex, asynchPlatingDatas, asynchMeshGroups, asynchMeshGroupTransforms);

                // and create the trace info so we can select it
                PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, meshGroupIndex, (double progress0To1, string processingState, out bool continueProcessing) =>
                {
                    BackgroundWorker_ProgressChanged(progress0To1, processingState, out continueProcessing);
                });

                currentRatioDone += ratioPerMeshGroup;

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

            // 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;
                }
            }
        }
Exemplo n.º 59
0
		public override void OnMouseDown(MouseEventArgs mouseEvent)
		{
			// Show transform override
			if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Right)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Rotate;
			}
			else if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Middle)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Translate;
			}

			autoRotating = false;
			base.OnMouseDown(mouseEvent);
			if (meshViewerWidget.TrackballTumbleWidget.UnderMouseState == Agg.UI.UnderMouseState.FirstUnderMouse)
			{
				if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
					&& mouseEvent.Button == MouseButtons.Left
					&& ModifierKeys != Keys.Shift
					&& ModifierKeys != Keys.Control
					&& ModifierKeys != Keys.Alt)
				{
					if (!meshViewerWidget.MouseDownOnInteractionVolume)
					{
						int meshGroupHitIndex;
						if (FindMeshGroupHitPosition(mouseEvent.Position, out meshGroupHitIndex))
						{
							meshSelectInfo.hitPlane = new PlaneShape(Vector3.UnitZ, meshSelectInfo.planeDownHitPos.z, null);
							SelectedMeshGroupIndex = meshGroupHitIndex;

							transformOnMouseDown = SelectedMeshGroupTransform.translation;

							Invalidate();
							meshSelectInfo.downOnPart = true;
						}
						else
						{
							SelectedMeshGroupIndex = -1;
						}

						UpdateSizeInfo();
					}
				}
			}
		}
Exemplo n.º 60
0
        public async Task AlignObjectHasCorrectPositionsOnXAxis()
        {
            StaticData.RootPath = TestContext.CurrentContext.ResolveProjectPath(4, "StaticData");
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));

            // Automation runner must do as much as program.cs to spin up platform
            string platformFeaturesProvider = "MatterHackers.MatterControl.WindowsPlatformsFeatures, MatterControl.Winforms";

            AppContext.Platform = AggContext.CreateInstanceFrom <INativePlatformFeatures>(platformFeaturesProvider);
            AppContext.Platform.ProcessCommandline();

            var scene = new InteractiveScene();

            var cube = await CubeObject3D.Create(20, 20, 20);

            cube.Matrix = Matrix4X4.CreateTranslation(50, 60, 10);
            Assert.IsTrue(cube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 50, 0), new Vector3(60, 70, 20)), .01));
            scene.Children.Add(cube);

            var bigCube = await CubeObject3D.Create(40, 40, 40);

            bigCube.Matrix = Matrix4X4.CreateTranslation(20, 20, 20);
            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(40, 40, 40)), .01));
            scene.Children.Add(bigCube);

            // select them
            scene.SelectedItem = cube;
            scene.AddToSelection(bigCube);

            // create an align of them
            var align = new AlignObject3D();

            align.AddSelectionAsChildren(scene, scene.SelectedItem);

            var unalignedBounds = align.GetAxisAlignedBoundingBox();

            // assert the align in built correctly
            Assert.AreEqual(1, scene.Children.Count);
            Assert.AreEqual(2, align.Children.Count);
            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(60, 70, 40)), 1.0));

            align.SelectedChild = new SelectedChildren()
            {
                cube.ID.ToString()
            };

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(unalignedBounds, 1.0));

            // turn align on
            align.XAlign = Align.Min;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 0, 0), new Vector3(80, 70, 40)), 1.0));

            // turn it off
            align.XAlign = Align.None;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(unalignedBounds, 1.0));

            // turn it back on
            align.XAlign = Align.Min;
            await align.Rebuild();

            Assert.IsTrue(align.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 0, 0), new Vector3(80, 70, 40)), 1.0));

            // remove the align and assert stuff moved back to where it started
            align.Remove(null);
            Assert.IsTrue(cube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(40, 50, 0), new Vector3(60, 70, 20)), .01));
            Assert.IsTrue(bigCube.GetAxisAlignedBoundingBox().Equals(new AxisAlignedBoundingBox(new Vector3(0, 0, 0), new Vector3(40, 40, 40)), .01));
        }