Beispiel #1
0
        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;
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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();
        }