private static bool CheckPosition(int meshGroupToMoveIndex, List <MeshGroup> allMeshGroups, List <ScaleRotateTranslate> meshTransforms, MeshGroup meshGroupToMove, AxisAlignedBoundingBox meshToMoveBounds, int yStep, int xStep, ref Matrix4X4 transform) { double xStepAmount = 5; double yStepAmount = 5; Matrix4X4 positionTransform = Matrix4X4.CreateTranslation(xStep * xStepAmount, yStep * yStepAmount, 0); Vector3 newPosition = Vector3.Transform(Vector3.Zero, positionTransform); transform = Matrix4X4.CreateTranslation(newPosition); AxisAlignedBoundingBox testBounds = meshToMoveBounds.NewTransformed(transform); bool foundHit = false; for (int i = 0; i < meshGroupToMoveIndex; i++) { MeshGroup meshToTest = allMeshGroups[i]; if (meshToTest != meshGroupToMove) { AxisAlignedBoundingBox existingMeshBounds = GetAxisAlignedBoundingBox(meshToTest, meshTransforms[i].TotalTransform); AxisAlignedBoundingBox intersection = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds); if (intersection.XSize > 0 && intersection.YSize > 0) { foundHit = true; break; } } } if (!foundHit) { return(true); } return(false); }
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(Matrix4X4.Identity); AxisAlignedBoundingBox intersection = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds); if (intersection.XSize > 0 && intersection.YSize > 0) { return(false); } } } return(true); }
public static void SplitFaces(this Mesh meshToSplit, Mesh meshToConsider) { AxisAlignedBoundingBox boundsForFaces = meshToSplit.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox boundsForEdges = meshToConsider.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox faceEdgeBoundsIntersection = AxisAlignedBoundingBox.Intersection(boundsForEdges, boundsForFaces); foreach (Face thisFace in meshToSplit.Faces.ToArray()) // GetFacesTouching(faceEdgeBoundsIntersection).ToArray()) { foreach (Face compareFace in meshToConsider.Faces) //.GetFacesTouching(thisFace.GetAxisAlignedBoundingBox())) { //distance from the face1 vertices to the face2 plane //distances signs from the face1 vertices to the face2 plane //if all the signs are zero, the planes are coplanar //if all the signs are positive or negative, the planes do not intersect //if the signs are not equal... bool signsAreSame = true; if (!signsAreSame) { //distance from the face2 vertices to the face1 plane //distances signs from the face2 vertices to the face1 plane //if the signs are not equal... if (!signsAreSame) { // split all intersecting mesh edges // get all splits and sort them along the line // split the face at every pair of edge splits } } } } }
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; }
public void SplitOnAllEdgeIntersections(CsgAcceleratedMesh meshWidthEdges) { AxisAlignedBoundingBox boundsForFaces = this.mesh.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox boundsForEdges = meshWidthEdges.mesh.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox faceEdgeBoundsIntersection = AxisAlignedBoundingBox.Intersection(boundsForEdges, boundsForFaces); foreach (var meshEdge in meshWidthEdges.GetMeshEdgesTouching(faceEdgeBoundsIntersection)) { // Check the mesh edge bounds agains all polygons. If there is an intersection // subdivide the mesh edge and if the face that is hit. If hit face on an edge only split the edge. Vector3 end0 = meshEdge.VertexOnEnd[0].Position; Vector3 end1 = meshEdge.VertexOnEnd[1].Position; Ray ray = new Ray(end0, (end1 - end0).GetNormal()); AxisAlignedBoundingBox edgeBounds = new AxisAlignedBoundingBox(Vector3.ComponentMin(end0, end1), Vector3.ComponentMax(end0, end1)); foreach (Face face in GetFacesTouching(edgeBounds)) { Vector3 intersectionPosition; // intersect the face with the edge switch (face.Intersection(ray, out intersectionPosition)) { case FaceHelper.IntersectionType.Vertex: break; case FaceHelper.IntersectionType.MeshEdge: { SplitMeshEdge(meshEdge, intersectionPosition); // split the face at intersectionPosition SplitMeshEdgeAtPosition(face, intersectionPosition); } break; case FaceHelper.IntersectionType.Face: { SplitMeshEdge(meshEdge, intersectionPosition); // split the face at intersectionPosition SplitFaceAtPosition(face, intersectionPosition); } break; } } } }
public override AxisAlignedBoundingBox GetAxisAlignedBoundingBox() { return(AxisAlignedBoundingBox.Intersection(a.GetAxisAlignedBoundingBox(), b.GetAxisAlignedBoundingBox())); }