public override void CreateMesh() { var box = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_BOX_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_BOX_COORDINATES); var sphere = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_COORDINATES); sphere.scale(0.68, 0.68, 0.68); var cylinder1 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES); cylinder1.scale(0.38, 1, 0.38); var cylinder2 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES); cylinder2.scale(0.38, 1, 0.38); cylinder2.rotate(Math.PI / 2, 0); var cylinder3 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES); cylinder3.scale(0.38, 1, 0.38); cylinder3.rotate(Math.PI / 2, 0); cylinder3.rotate(0, Math.PI / 2); //-- //mesh = s; //-- // var modeller = new Net3dBool.BooleanModeller(b, c1); // mesh = modeller.getDifference(); //-- var modeller = new Net3dBool.BooleanModeller(box, sphere); var tmp = modeller.GetIntersection(); modeller = new Net3dBool.BooleanModeller(tmp, cylinder1); tmp = modeller.GetDifference(); modeller = new Net3dBool.BooleanModeller(tmp, cylinder2); tmp = modeller.GetDifference(); modeller = new Net3dBool.BooleanModeller(tmp, cylinder3); tmp = modeller.GetDifference(); mesh = tmp; }
public override void CreateMesh() { var start = DateTime.UtcNow; Console.Write("Generate mesh..."); var box = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_BOX_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_BOX_COORDINATES); var sphere = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_COORDINATES); sphere.scale(0.68, 0.68, 0.68); var cylinder1 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES); cylinder1.scale(0.38, 1, 0.38); var cylinder2 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES); cylinder2.scale(0.38, 1, 0.38); cylinder2.rotate(Math.PI / 2, 0); var cylinder3 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES); cylinder3.scale(0.38, 1, 0.38); cylinder3.rotate(Math.PI / 2, 0); cylinder3.rotate(0, Math.PI / 2); var modeller = new Net3dBool.BooleanModeller(box, sphere); var tmp = modeller.GetIntersection(); modeller = new Net3dBool.BooleanModeller(tmp, cylinder1); tmp = modeller.GetDifference(); modeller = new Net3dBool.BooleanModeller(tmp, cylinder2); tmp = modeller.GetDifference(); modeller = new Net3dBool.BooleanModeller(tmp, cylinder3); tmp = modeller.GetDifference(); mesh = tmp; var elapsed = DateTime.UtcNow - start; Console.WriteLine("done."); Console.WriteLine("Consumed time: {0}", elapsed); }
public static void BoolActionExecute(Component_MeshInSpace firstMeshInSpace, Component_MeshInSpace secondMeshInSpace, UndoMultiAction undo, DocumentInstance document, BoolActionEnum boolAction) { //the first operand of the union operation must be a single geometry, otherwise duplicate parts will be made. if (boolAction == BoolActionEnum.Union && 1 < firstMeshInSpace.Mesh.Value.GetComponents <Component_MeshGeometry>().Length) { MergeGeometries(firstMeshInSpace.Mesh, document, undo); } bool needUndoForNextActions = true; CommonFunctions.ConvertProceduralMeshGeometries(document, firstMeshInSpace.Mesh, undo, ref needUndoForNextActions); List <(Vector3F[] positions, int[] indices)> data1List = GetData(firstMeshInSpace); (Vector3F[] positions, int[] indices)data2 = MergeData(GetData(secondMeshInSpace)); //convert the second mesh in space, to the transform of first mesh in space var matrix = firstMeshInSpace.Transform.Value.ToMatrix4().GetInverse() * secondMeshInSpace.Transform.Value.ToMatrix4(); Net3dBool.Vector3[] vertices2 = new Net3dBool.Vector3[data2.positions.Length]; for (int i = 0; i < data2.positions.Length; i++) { vertices2[i] = ToNet3DBoolVector3((matrix * data2.positions[i]).ToVector3F()); } var operand2 = new Net3dBool.Solid(vertices2, data2.indices); var geometries = firstMeshInSpace.Mesh.Value.GetComponents <Component_MeshGeometry>(); var resultGeometries = new List <(Vector3F[] positions, int[] indices, MeshData.MeshGeometryFormat format)>(); var geometriesToDelete = new List <Component_MeshGeometry>(); for (int geomIndex = 0; geomIndex < data1List.Count; geomIndex++) { var data1 = data1List[geomIndex]; Net3dBool.Vector3[] vertices1 = data1.positions.Select(ToNet3DBoolVector3).ToArray(); var modeller = new Net3dBool.BooleanModeller(new Net3dBool.Solid(vertices1, data1.indices), operand2); //Большую часть времени на вычисления занимает эта сторка Net3dBool.Solid result = null; switch (boolAction) { case BoolActionEnum.Union: result = modeller.GetUnion(); break; case BoolActionEnum.Intersect: result = modeller.GetIntersection(); break; case BoolActionEnum.Subtract: result = modeller.GetDifference(); break; default: return; } var newVertices = result.getVertices().Select(ToVector3F).ToArray(); if (0 < newVertices.Length) { resultGeometries.Add((newVertices, result.getIndices(), new MeshData.MeshGeometryFormat(geometries[geomIndex].VertexStructure))); } else { geometriesToDelete.Add(geometries[geomIndex]); } } foreach (var g in resultGeometries) { if (!CheckValid(g.positions, g.indices)) { throw new Exception(); } } //delete empty mesh geometry // if (0 < geometriesToDelete.Count) { undo?.AddAction(new UndoActionComponentCreateDelete(document, geometriesToDelete.ToArray(), create: false)); } var meshData = MeshData.BuildFromRaw(resultGeometries); meshData?.Save(firstMeshInSpace.Mesh.Value, needUndoForNextActions ? undo : null, null); //??? No selection? firstMeshInSpace.Mesh.Value?.RebuildStructure(); }
private StaticMeshComponent CreateMesh() { var mesh = Mesh.CreateCube().ToPrimitive(MeshFaceType.Triangle); mesh.CreateFacesAndIndicies(); mesh.Scale(10); var ind = mesh.GetIndiciesArray(); var vert = mesh.GetComponent <MeshPosition3Component>().ToArray().Select(s => new Vector3d(s.X, s.Y, s.Z)).ToArray(); var box = new Net3dBool.Solid(vert, ind); mesh = Mesh.CreateCube().ToPrimitive(MeshFaceType.Triangle); mesh.CreateFacesAndIndicies(); mesh.Scale(3); ind = mesh.GetIndiciesArray(); vert = mesh.GetComponent <MeshPosition3Component>().ToArray().Select(s => new Vector3d(s.X, s.Y, s.Z)).ToArray(); var box2 = new Net3dBool.Solid(vert, ind); mesh = Mesh.CreateCube().ToPrimitive(MeshFaceType.Triangle); mesh.CreateFacesAndIndicies(); mesh.Scale(2); mesh.Translate(1, 0, 0); ind = mesh.GetIndiciesArray(); vert = mesh.GetComponent <MeshPosition3Component>().ToArray().Select(s => new Vector3d(s.X, s.Y, s.Z)).ToArray(); var box3 = new Net3dBool.Solid(vert, ind); var modeller = new Net3dBool.BooleanModeller(box, box2); var tmp = modeller.GetDifference(); modeller = new Net3dBool.BooleanModeller(tmp, box3); tmp = modeller.GetDifference(); VertexDataPosNormalColor[] data = tmp.GetVertices().Select(v => new VertexDataPosNormalColor(new Vector3((float)v.X, (float)v.Y, (float)v.Z), new Vector3(1, 0, 0), new Vector4(1, 1, 0, 1))).ToArray(); for (var i = 0; i < data.Length; i++) { var face = i / 3; var vertex = i % 3; // switch (vertex) // { // case 0: // data[i].Color = new Vector4(1, 0, 0, 1); // break; // case 1: // data[i].Color = new Vector4(0, 1, 0, 1); // break; // case 2: // data[i].Color = new Vector4(0, 0, 1, 1); // break; // } data[i].Normal = Vector3.UnitX; } var meshData = Mesh.CreateFromVertices(data, tmp.GetIndices().ToArray()); meshData.Expand(); meshData.RecalculateNormals(25f); var material = new Material { Ambient = 0.5f, Color = new Vector4(1, 1, 1, 1), UseVertexColor = true, PipelineType = PipelineType.Forward, }; var comp = new StaticMeshComponent() { Name = "BoolMesh", RelativeRotation = new Vector3(0, 0, 0.5f).ToQuaternion(), RelativeScale = new Vector3(1), RelativeTranslation = new Vector3(2, 0, 0.5f), Material = material, }; comp.SetMesh(meshData); return(comp); }