示例#1
0
        public void Difference()
        {
            this.Name = "CSG_Difference";
            var profile = _profileFactory.GetProfileByType(HSSPipeProfileType.HSS10_000x0_188);

            var path = new Arc(Vector3.Origin, 5, 0, 270);
            var s1   = new Sweep(profile, path, 0, 0, 0, true);
            var csg  = s1.Solid.ToCsg();

            var s2 = new Extrude(new Circle(Vector3.Origin, 6).ToPolygon(20), 1, Vector3.ZAxis, false);

            csg = csg.Substract(s2.Solid.ToCsg());

            for (var i = 0.0; i < 1.0; i += 0.05)
            {
                var pt   = path.PointAt(i);
                var hole = new Extrude(new Circle(Vector3.Origin, 0.05).ToPolygon(), 3, Vector3.ZAxis, false);
                csg = csg.Substract(hole.Solid.ToCsg().Transform(new Transform(pt + new Vector3(0, 0, -2)).ToMatrix4x4()));
            }

            var result = new Mesh();

            csg.Tessellate(ref result);

            var me2 = new MeshElement(result);

            this.Model.AddElement(me2);
        }
示例#2
0
        private MeshElement ConstructExampleMesh()
        {
            var mesh     = new Mesh();
            var gridSize = 10;

            for (var u = 0; u < gridSize; u += 1)
            {
                for (var v = 0; v < gridSize; v += 1)
                {
                    var sinu   = Math.Sin(-Math.PI + 2 * ((double)u / (double)gridSize * Math.PI));
                    var sinv   = Math.Sin(-Math.PI + 2 * ((double)v / (double)gridSize * Math.PI));
                    var z      = sinu + sinv;
                    var vertex = new Geometry.Vertex(new Vector3(u, v, z), color: Colors.Mint);
                    mesh.AddVertex(vertex);

                    if (u > 0 && v > 0)
                    {
                        var index = u * gridSize + v;
                        var a     = mesh.Vertices[index];
                        var b     = mesh.Vertices[index - gridSize];
                        var c     = mesh.Vertices[index - 1];
                        var d     = mesh.Vertices[index - gridSize - 1];
                        var tri1  = new Triangle(a, b, c);
                        var tri2  = new Triangle(c, b, d);

                        mesh.AddTriangle(tri1);
                        mesh.AddTriangle(tri2);
                    }
                }
            }
            mesh.ComputeNormals();
            var meshElement = new MeshElement(mesh, new Material("Lime", Colors.Lime), new Transform(new Vector3(-7, -8, 0), new Vector3(-5, 3, 2)));

            return(meshElement);
        }
示例#3
0
        /// <summary>
        /// The RhinoComputeExample function.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A RhinoComputeExampleOutputs instance containing computed results and the model with any new elements.</returns>
        public static RhinoComputeExampleOutputs Execute(Dictionary <string, Model> inputModels, RhinoComputeExampleInputs input)
        {
            // set up a model to hold elements
            var model = new Model();

            // Call rhino methods with regular rhino calls, or Rhino.Compute calls if required methods are unavailable
            var box1        = rg.Brep.CreateFromBox(new rg.BoundingBox(new rg.Point3d(0, 0, 0), new rg.Point3d(input.Radius, input.Radius, input.Radius)));
            var box2        = rg.Brep.CreateFromBox(new rg.BoundingBox(new rg.Point3d(input.Radius * 0.5, input.Radius * 0.5, input.Radius * 0.5), new rg.Point3d(input.Radius * 1.5, input.Radius * 1.5, input.Radius * 1.5)));
            var booleanDiff = Rhino.Compute.BrepCompute.CreateBooleanDifference(box1, box2, 0.1).First();

            var boundaryCurves = booleanDiff.Faces.Select(f => f.OuterLoop.To3dCurve());

            // Use conversion extension methods from HyRhi / Conversion.cs
            var elementsSphereMesh = booleanDiff.ToMesh();
            var elementsCrvs       = boundaryCurves.Select(c => c.ToPolygon());

            // create Hypar Elements from resulting geometry
            var meshElement   = new MeshElement(elementsSphereMesh, BuiltInMaterials.Glass);
            var curveElements = elementsCrvs.Select(c => new ModelCurve(c));

            // add elements to model
            model.AddElement(meshElement);
            model.AddElements(curveElements);

            // construct output object
            var output = new RhinoComputeExampleOutputs();

            // add model to output
            output.Model = model;

            // return output
            return(output);
        }
        public static Vector3 MeshCentroid(MeshElement mesh)
        {
            var verts    = mesh.Mesh.Vertices;
            var centroid = AverageVert(verts);

            return(centroid);
        }
示例#5
0
        public bool start(string path)
        {
            if (Provider.Provider.OpenConnection())
            {
                if (Provider.Provider.openProject(path))
                {
                    Element elems = new Element();
                    elems.saveToDataBase(elems.getData(), new element(), new DataModel());

                    MeshPoint nodes = new MeshPoint();
                    nodes.saveToDataBase(nodes.getData(), new nodes(), new DataModel());

                    Moments mts = new Moments();
                    mts.saveToDataBase(mts.getData(), new moment(), new DataModel());

                    MeshElement element = new MeshElement();
                    element.saveToDataBase(element.getData(), new meshele(), new DataModel());

                    Provider.Provider.CloseConnection();
                    return(true);
                }
                else
                {
                    MessageBox.Show("Nie wczytano pliku ...");
                    return(false);
                }
            }
            else
            {
                MessageBox.Show("Nie polaczono ...");
                return(false);
            }
        }
示例#6
0
        private SolidAnalysisObject(MeshElement meshElement)
        {
            Dictionary <string, long> edgeLookup = new Dictionary <string, long>();

            long edgeIdx = 0;

            foreach (var vertex in meshElement.Mesh.Vertices)
            {
                var key   = vertex.Index;
                var point = GeoUtilities.TransformedPoint(vertex.Position, meshElement.Transform);
                this.Points.Add(key, point);
                this._maxVertexKey = Math.Max(this._maxVertexKey, key);
            }

            var tIdx = 0;

            foreach (var triangle in meshElement.Mesh.Triangles)
            {
                var vertices = triangle.Vertices.ToList();
                var edges    = new List <AnalysisEdge>();

                var vIdx = 0;

                // Only add points where face is not sitting on Z = 0
                var pointNotZero = false;

                foreach (var startVertex in vertices)
                {
                    var endVertex = vIdx == vertices.Count - 1 ? vertices[0] : vertices[vIdx + 1];

                    var lowerVertex  = startVertex.Index < endVertex.Index ? startVertex : endVertex;
                    var higherVertex = startVertex.Index > endVertex.Index ? startVertex : endVertex;

                    var lineIdUniq = $"{lowerVertex.Index}_{higherVertex.Index}";

                    pointNotZero = pointNotZero || (this.Points[lowerVertex.Index].Z != 0.0 || this.Points[higherVertex.Index].Z != 0.0);

                    if (!edgeLookup.ContainsKey(lineIdUniq))
                    {
                        this.AddEdge(edgeIdx, lowerVertex.Index, higherVertex.Index);
                        edgeLookup.Add(lineIdUniq, edgeIdx);
                        edgeIdx += 1;
                    }

                    if (edgeLookup.TryGetValue(lineIdUniq, out long addedOrExistingEdgeIdx))
                    {
                        var isReversed = startVertex.Index != lowerVertex.Index;
                        edges.Add(new AnalysisEdge(addedOrExistingEdgeIdx, isReversed));
                    }

                    vIdx += 1;
                }
                if (pointNotZero)
                {
                    this.Surfaces.Add(edges);
                }
                tIdx += 1;
            }
        }
        public void NodeInterpolationTest(string meshFileName, CircularValueTypes cvt = CircularValueTypes.Normal)
        {
            // Source mesh
            MeshFile meshFile = MeshFile.ReadMesh(meshFileName);
            MeshData mesh     = meshFile.ToMeshData();

            // Allow for extrapolation on boundary nodes (disable clipping)
            MeshNodeInterpolation interpolation = new MeshNodeInterpolation(mesh)
            {
                AllowExtrapolation = true,
            };

            interpolation.Setup();
            Interpolator nodeInterpolator = interpolation.NodeInterpolator;

            nodeInterpolator.CircularType = cvt;

            // Find reference x and y value as the smallest x and y value
            double xMin = mesh.Nodes.Select(mn => mn.X).Min();
            double xMax = mesh.Nodes.Select(mn => mn.X).Max();
            double yMin = mesh.Nodes.Select(mn => mn.Y).Min();
            double yMax = mesh.Nodes.Select(mn => mn.Y).Max();

            // Function over the (x,y) plane.
            Func <double, double, double> function = ValueFunction(cvt, xMin, yMin, xMax, yMax);

            // Calculate element center values
            double[] elmtVals = new double[mesh.Elements.Count];
            for (int i = 0; i < mesh.Elements.Count; i++)
            {
                MeshElement elmt = mesh.Elements[i];
                elmtVals[i] = function(elmt.XCenter, elmt.YCenter);
            }

            // Write out bounds, to check we got things right
            Console.Out.WriteLine("{0,10} (min,max) = ({1},{2})", cvt, elmtVals.Min(), elmtVals.Max());

            // Interpolate to nodes
            double[] nodeValues = new double[mesh.Nodes.Count];
            nodeInterpolator.Interpolate(elmtVals, nodeValues);

            // Check node values
            for (int i = 0; i < mesh.Nodes.Count; i++)
            {
                MeshNode node        = mesh.Nodes[i];
                double   exactValue  = function(node.X, node.Y);
                double   interpValue = nodeValues[i];
                double   diff        = exactValue - interpValue;
                // It can only extrapolate when there is at least three elements per node.
                // When there is two or less elements, the inverse distance weighting takes over
                // and the results are not correct, so we skip the check here.
                if (node.Elements.Count > 2 && diff > 1e-6)
                {
                    string msg = string.Format("{0,2} {6}: {1}-{2}={3} ({4},{5})", i, exactValue, interpValue, diff, node.X, node.Y, node.Elements.Count);
                    Console.Out.WriteLine(msg);
                    Assert.Fail(msg);
                }
            }
        }
示例#8
0
        protected override bool ImportStandtradShapeData()
        {
            var MeshPolygons = MeshElement.Sphere(0.5);

            for (int i = 0; i < MeshPolygons.Length; i++)
            {
                //GL.Normal3(MeshPolygons[i].Normal);
                for (int j = 0; j < MeshPolygons[i].Vertices.Length; j++)
                {
                    LocalVertices.Add(MeshPolygons[i].Vertices[j]);
                }
            }
            return(base.ImportStandtradShapeData());
        }
示例#9
0
        public void Union()
        {
            this.Name = "CSG_Union";
            var s1  = new Extrude(Polygon.Rectangle(1, 1), 1, Vector3.ZAxis, false);
            var csg = s1.Solid.ToCsg();

            var s2 = new Extrude(Polygon.L(1.0, 2.0, 0.5), 1, Vector3.ZAxis, false);

            csg = csg.Union(s2.Solid.ToCsg());

            var result = new Mesh();

            csg.Tessellate(ref result);

            var me = new MeshElement(result);

            this.Model.AddElement(me);
        }
        public static List <Envelope> SliceAtHeight(MeshElement meshElement, double cutHeight, Boolean showDebugGeometry)
        {
            var bbox   = new BBox3(TransformedVertices(meshElement.Mesh.Vertices, meshElement.Transform));
            var bottom = bbox.Min.Z;
            var top    = bbox.Max.Z;
            var solids = new List <Elements.Geometry.Solids.SolidOperation>();
            var solid  = new Elements.Geometry.Solids.Solid();

            foreach (var face in meshElement.Mesh.Triangles)
            {
                var vertices = TransformedVertices(face.Vertices, meshElement.Transform);
                solid.AddFace(new Polygon(vertices));
            }
            solids.Add(new Elements.Geometry.Solids.ConstructedSolid(solid));
            var rep = new Representation(solids);
            var env = new Envelope(Polygon.Rectangle(new Vector3(bbox.Min.X, bbox.Min.Y), new Vector3(bbox.Max.X, bbox.Max.Y)), bottom, top - bottom, Vector3.ZAxis, 0, new Transform(), _debugMaterial, rep, false, Guid.NewGuid(), "");

            return(SliceAtHeight(env, cutHeight, showDebugGeometry));
        }
示例#11
0
        public void ElementIncludesTest()
        {
            MeshElement element = new MeshElement();

            element.Nodes = new List <MeshNode>(3);
            element.Nodes.Add(new MeshNode()
            {
                X = 1.1, Y = 1.0
            });
            element.Nodes.Add(new MeshNode()
            {
                X = 2.2, Y = 1.1
            });
            element.Nodes.Add(new MeshNode()
            {
                X = 1.6, Y = 2.0
            });

            // Corner points are inside
            Assert.True(element.Includes(1.1, 1.0));
            Assert.True(element.Includes(2.2, 1.1));
            Assert.True(element.Includes(1.6, 2.0));

            // Points on face lines are inside
            // Mid point, first face
            Assert.True(element.Includes(1.65, 1.05));
            Assert.True(element.Includes(1.65, 1.05 + 0.0000001));
            Assert.False(element.Includes(1.65, 1.05 - 0.0000001));

            // Mid point, second face
            Assert.True(element.Includes(1.9, 1.55));
            Assert.True(element.Includes(1.9, 1.55 - 0.00000001));
            Assert.False(element.Includes(1.9, 1.55 + 0.00000001));

            // Mid point, third face
            Assert.True(element.Includes(1.35, 1.5));
            Assert.True(element.Includes(1.35, 1.5 - 0.000000001));
            Assert.False(element.Includes(1.35, 1.5 + 0.000000001));
        }
示例#12
0
        public void MeshElement()
        {
            this.Name = "Elements_MeshElement";
            // <example>
            var mesh     = new Mesh();
            var gridSize = 10;

            for (var u = 0; u < gridSize; u += 1)
            {
                for (var v = 0; v < gridSize; v += 1)
                {
                    var sinu   = Math.Sin(-Math.PI + 2 * ((double)u / (double)gridSize * Math.PI));
                    var sinv   = Math.Sin(-Math.PI + 2 * ((double)v / (double)gridSize * Math.PI));
                    var z      = sinu + sinv;
                    var vertex = new Vertex(new Vector3(u, v, z), color: Colors.Mint);
                    mesh.AddVertex(vertex);

                    if (u > 0 && v > 0)
                    {
                        var index = u * gridSize + v;
                        var a     = mesh.Vertices[index];
                        var b     = mesh.Vertices[index - gridSize];
                        var c     = mesh.Vertices[index - 1];
                        var d     = mesh.Vertices[index - gridSize - 1];
                        var tri1  = new Triangle(a, b, c);
                        var tri2  = new Triangle(c, b, d);

                        mesh.AddTriangle(tri1);
                        mesh.AddTriangle(tri2);
                    }
                }
            }
            mesh.ComputeNormals();
            var meshElement = new MeshElement(mesh, new Material("Lime", Colors.Lime));

            //</example>
            this.Model.AddElement(meshElement);
        }
示例#13
0
        public Dictionary <string, object> Handler(Dictionary <string, object> input, ILambdaContext context)
        {
            var width        = float.Parse(input["width"].ToString());
            var height       = float.Parse(input["height"].ToString());
            var aspect_ratio = float.Parse(input["aspectRatio"].ToString());
            var features     = ((JArray)input["boundary"]).ToObject <Feature[]>();
            var outline      = (Polygon)features[0].Geometry;
            var origin       = outline.Coordinates[0][0];
            var offset       = origin.ToVectorMeters();
            var plines       = outline.ToPolylines();
            var pline        = plines[0];
            var boundary     = new Polyline(pline.Vertices.Select(v => new Vector3(v.X - offset.X, v.Y - offset.Y, v.Z)));

            var building = Building.Make(boundary.ToArray(), width, height, aspect_ratio);

            var model = new Model();

            model.Origin = origin;
            var mesh = new MeshElement(Mesh.Extrude(building.Polylines, height));

            model.AddElement(mesh);
            return(model.ToHypar());
        }
示例#14
0
        public void Test()
        {
            Vector3[] boundary =
            {
                new Vector3(0.0f,     0.0f),
                new Vector3(200.0f,   0.0f),
                new Vector3(200.0f, 200.0f),
                new Vector3(0.0f,   200.0f),
            };
            var height   = 40.0f;
            var building = Building.Make(boundary, 60.0f, height, 0.5f);

            for (int i = 0; i < building.Polylines.Count; ++i)
            {
                Console.WriteLine(building.Polylines[i].ToString());
            }

            var model = new Model();
            var mesh  = new MeshElement(Mesh.Extrude(building.Polylines, height));

            model.AddElement(mesh);
            model.SaveGlb("test.glb");
        }
        void UpdateAnimation()
        {
            if (loaded && a3d != null && channelObjects != null & subObjects != null)
            {
                if (currentFrame >= a3d.num_onlyFrames)
                {
                    currentFrame %= a3d.num_onlyFrames;
                }
                // First pass: reset TRS for all sub objects
                for (int i = 0; i < channelParents.Length; i++)
                {
                    channelParents[i] = false;
                }
                AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + currentFrame];
                // Create hierarchy for this frame
                for (int i = of.start_hierarchies_for_frame;
                     i < of.start_hierarchies_for_frame + of.num_hierarchies_for_frame; i++)
                {
                    AnimHierarchy h = a3d.hierarchies[i];

                    if (Controller.Settings.engineVersion <= Settings.EngineVersion.TT)
                    {
                        channelObjects[h.childChannelID].transform.SetParent(channelObjects[h.parentChannelID].transform);
                        channelParents[h.childChannelID] = true;
                    }
                    else
                    {
                        if (!channelIDDictionary.ContainsKey(h.childChannelID) || !channelIDDictionary.ContainsKey(h.parentChannelID))
                        {
                            continue;
                        }
                        List <int> ch_child_list  = GetChannelByID(h.childChannelID);
                        List <int> ch_parent_list = GetChannelByID(h.parentChannelID);
                        foreach (int ch_child in ch_child_list)
                        {
                            foreach (int ch_parent in ch_parent_list)
                            {
                                channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform);
                                channelParents[ch_child] = true;
                            }
                        }
                    }

                    //channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform);
                }
                // Final pass
                for (int i = 0; i < a3d.num_channels; i++)
                {
                    AnimChannel       ch        = a3d.channels[a3d.start_channels + i];
                    AnimFramesKFIndex kfi       = a3d.framesKFIndex[currentFrame + ch.framesKF];
                    AnimKeyframe      kf        = a3d.keyframes[kfi.kf];
                    AnimVector        pos       = a3d.vectors[kf.positionVector];
                    AnimQuaternion    qua       = a3d.quaternions[kf.quaternion];
                    AnimVector        scl       = a3d.vectors[kf.scaleVector];
                    AnimNumOfNTTO     numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                    AnimNTTO          ntto      = a3d.ntto[numOfNTTO.numOfNTTO];
                    //if (ntto.IsBoneNTTO) continue;
                    int            poNum          = numOfNTTO.numOfNTTO - a3d.start_NTTO;
                    PhysicalObject physicalObject = subObjects[i][poNum];
                    Vector3        vector         = pos.vector;
                    Quaternion     quaternion     = qua.quaternion;
                    Vector3        scale          = scl.vector;
                    int            framesSinceKF  = (int)currentFrame - (int)kf.frame;
                    AnimKeyframe   nextKF         = null;
                    int            framesDifference;
                    float          interpolation;
                    if (kf.IsEndKeyframe)
                    {
                        AnimFramesKFIndex next_kfi = a3d.framesKFIndex[0 + ch.framesKF];
                        nextKF           = a3d.keyframes[next_kfi.kf];
                        framesDifference = a3d.num_onlyFrames - 1 + (int)nextKF.frame - (int)kf.frame;
                        if (framesDifference == 0)
                        {
                            interpolation = 0;
                        }
                        else
                        {
                            //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor);
                            interpolation = framesSinceKF / (float)framesDifference;
                        }
                    }
                    else
                    {
                        nextKF           = a3d.keyframes[kfi.kf + 1];
                        framesDifference = (int)nextKF.frame - (int)kf.frame;
                        //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor);
                        interpolation = framesSinceKF / (float)framesDifference;
                    }
                    //print(interpolation);
                    //print(a3d.vectors.Length + " - " + nextKF.positionVector);
                    AnimVector     pos2 = a3d.vectors[nextKF.positionVector];
                    AnimQuaternion qua2 = a3d.quaternions[nextKF.quaternion];
                    AnimVector     scl2 = a3d.vectors[nextKF.scaleVector];
                    vector     = Vector3.Lerp(pos.vector, pos2.vector, interpolation);
                    quaternion = Quaternion.Lerp(qua.quaternion, qua2.quaternion, interpolation);
                    scale      = Vector3.Lerp(scl.vector, scl2.vector, interpolation);
                    float positionMultiplier = Mathf.Lerp(kf.positionMultiplier, nextKF.positionMultiplier, interpolation);

                    if (poNum != currentActivePO[i])
                    {
                        if (currentActivePO[i] == -2 && fullMorphPOs != null && fullMorphPOs[i] != null)
                        {
                            foreach (PhysicalObject morphPO in fullMorphPOs[i].Values)
                            {
                                if (morphPO.Gao.activeSelf)
                                {
                                    morphPO.Gao.SetActive(false);
                                }
                            }
                        }
                        if (currentActivePO[i] >= 0 && subObjects[i][currentActivePO[i]] != null)
                        {
                            subObjects[i][currentActivePO[i]].Gao.SetActive(false);
                        }
                        currentActivePO[i] = poNum;
                        if (physicalObject != null)
                        {
                            physicalObject.Gao.SetActive(true);
                        }
                    }
                    if (!channelParents[i])
                    {
                        channelObjects[i].transform.SetParent(perso.gameObject.transform);
                    }
                    channelObjects[i].transform.localPosition = vector * positionMultiplier;
                    channelObjects[i].transform.localRotation = quaternion;
                    channelObjects[i].transform.localScale    = scale;

                    if (physicalObject != null && a3d.num_morphData > 0 && morphDataArray != null && i < morphDataArray.GetLength(0) && currentFrame < morphDataArray.GetLength(1))
                    {
                        AnimMorphData morphData = morphDataArray[i, currentFrame];

                        if (morphData != null && morphData.morphProgress != 0 && morphData.morphProgress != 100)
                        {
                            PhysicalObject morphToPO  = perso.Perso3dData.ObjectList.entries[morphData.objectIndexTo].po;
                            Vector3[]      morphVerts = null;

                            for (int j = 0; j < physicalObject.visualSet.Length; j++)
                            {
                                IGeometricObject obj = physicalObject.visualSet[j].obj;
                                if (obj == null || obj as MeshObject == null)
                                {
                                    continue;
                                }
                                MeshObject fromM = obj as MeshObject;
                                MeshObject toM   = morphToPO.visualSet[j].obj as MeshObject;
                                if (toM == null)
                                {
                                    continue;
                                }
                                if (fromM.vertices.Length != toM.vertices.Length)
                                {
                                    // For those special cases like the mistake in the Clark cinematic
                                    continue;
                                }
                                int numVertices = fromM.vertices.Length;
                                morphVerts = new Vector3[numVertices];
                                for (int vi = 0; vi < numVertices; vi++)
                                {
                                    morphVerts[vi] = Vector3.Lerp(fromM.vertices[vi], toM.vertices[vi], morphData.morphProgressFloat);
                                }
                                for (int k = 0; k < fromM.num_subblocks; k++)
                                {
                                    if (fromM.subblocks[k] == null || fromM.subblock_types[k] != 1)
                                    {
                                        continue;
                                    }
                                    MeshElement el = (MeshElement)fromM.subblocks[k];
                                    if (el != null)
                                    {
                                        el.UpdateMeshVertices(morphVerts);
                                    }
                                }
                            }
                        }
                        else if (morphData != null && morphData.morphProgress == 100)
                        {
                            physicalObject.Gao.SetActive(false);
                            PhysicalObject c = fullMorphPOs[i][morphData.objectIndexTo];
                            c.Gao.transform.localScale    = c.scaleMultiplier.HasValue ? c.scaleMultiplier.Value : Vector3.one;
                            c.Gao.transform.localPosition = Vector3.zero;
                            c.Gao.transform.localRotation = Quaternion.identity;
                            c.Gao.SetActive(true);
                            currentActivePO[i] = -2;
                        }
                        else
                        {
                            for (int j = 0; j < physicalObject.visualSet.Length; j++)
                            {
                                IGeometricObject obj = physicalObject.visualSet[j].obj;
                                if (obj == null || obj as MeshObject == null)
                                {
                                    continue;
                                }
                                MeshObject fromM = obj as MeshObject;
                                for (int k = 0; k < fromM.num_subblocks; k++)
                                {
                                    if (fromM.subblocks[k] == null || fromM.subblock_types[k] != 1)
                                    {
                                        continue;
                                    }
                                    MeshElement el = (MeshElement)fromM.subblocks[k];
                                    if (el != null)
                                    {
                                        el.ResetVertices();
                                    }
                                }
                            }
                        }
                    }
                }
                if (hasBones)
                {
                    for (int i = 0; i < a3d.num_channels; i++)
                    {
                        AnimChannel    ch = a3d.channels[a3d.start_channels + i];
                        Transform      baseChannelTransform = channelObjects[i].transform;
                        Vector3        invertedScale        = new Vector3(1f / baseChannelTransform.localScale.x, 1f / baseChannelTransform.localScale.y, 1f / baseChannelTransform.localScale.z);
                        AnimNumOfNTTO  numOfNTTO            = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                        AnimNTTO       ntto           = a3d.ntto[numOfNTTO.numOfNTTO];
                        PhysicalObject physicalObject = subObjects[i][numOfNTTO.numOfNTTO - a3d.start_NTTO];
                        if (physicalObject == null)
                        {
                            continue;
                        }
                        DeformSet bones = physicalObject.Bones;
                        // Deformations
                        if (bones != null)
                        {
                            for (int j = 0; j < a3d.num_deformations; j++)
                            {
                                AnimDeformation d = a3d.deformations[a3d.start_deformations + j];
                                if (d.channel < ch.id)
                                {
                                    continue;
                                }
                                if (d.channel > ch.id)
                                {
                                    break;
                                }
                                if (!channelIDDictionary.ContainsKey(d.linkChannel))
                                {
                                    continue;
                                }
                                List <int> ind_linkChannel_list = GetChannelByID(d.linkChannel);
                                foreach (int ind_linkChannel in ind_linkChannel_list)
                                {
                                    AnimChannel    ch_link             = a3d.channels[a3d.start_channels + ind_linkChannel];
                                    AnimNumOfNTTO  numOfNTTO_link      = a3d.numOfNTTO[ch_link.numOfNTTO + of.numOfNTTO];
                                    AnimNTTO       ntto_link           = a3d.ntto[numOfNTTO_link.numOfNTTO];
                                    PhysicalObject physicalObject_link = subObjects[ind_linkChannel][numOfNTTO_link.numOfNTTO - a3d.start_NTTO];
                                    if (physicalObject_link == null)
                                    {
                                        continue;
                                    }
                                    if (bones == null || bones.bones.Length <= d.bone + 1)
                                    {
                                        continue;
                                    }
                                    DeformBone bone = bones.r3bones[d.bone + 1];
                                    if (bone != null)
                                    {
                                        Transform channelTransform = channelObjects[ind_linkChannel].transform;
                                        bone.UnityBone.transform.SetParent(channelTransform);
                                        bone.UnityBone.localPosition = Vector3.zero;
                                        bone.UnityBone.localRotation = Quaternion.identity;
                                        bone.UnityBone.localScale    = Vector3.one;

                                        /*bone.UnityBone.position = channelTransform.position;
                                         * bone.UnityBone.rotation = channelTransform.rotation;
                                         * //bone.UnityBone.localScale = Vector3.one;
                                         * bone.UnityBone.localScale = channelTransform.localScale;*/
                                    }
                                }
                            }
                        }
                    }
                }
                //this.currentFrame = (currentFrame + 1) % a3d.num_onlyFrames;
            }
        }
示例#16
0
        /// <summary>
        /// Calculate interpolation weights for the point (x,y) inside the <see cref="MeshElement"/>"/>
        /// <para>
        /// The weights returned can be used to calculate a value v at the point (x,y) using the
        /// <code>GetValue</code> methods
        /// </para>
        /// <para>
        /// if the point (x,y) is not inside the element, results are undefined.
        /// </para>
        /// </summary>
        /// <returns>Interpolation weights</returns>

        public static Weights InterpolationWeights(double x, double y, MeshElement element)
        {
            Weights weights = new Weights();

            // Setting "out-of-bounds" index
            weights.Element1Index = -1;

            bool found = false;

            weights.Element1Index = element.Index;

            // Check which face the point belongs to, and which "side" of the face
            bool isQuad   = element.IsQuadrilateral();
            int  numFaces = isQuad ? 4 : 3;

            for (int j = 0; j < numFaces; j++)
            {
                MeshFace elementFace = element.Faces[j];
                // From the element (x,y), looking towards the face,
                // figure out wich node is right and which is left.
                MeshNode rightNode, leftNode;
                if (elementFace.LeftElement == element)
                {
                    rightNode = elementFace.FromNode;
                    leftNode  = elementFace.ToNode;
                }
                else
                {
                    rightNode = elementFace.ToNode;
                    leftNode  = elementFace.FromNode;
                }

                double elementXCenter = element.XCenter;
                double elementYCenter = element.YCenter;
                double rightNodeX     = rightNode.X;
                double rightNodeY     = rightNode.Y;
                double leftNodeX      = leftNode.X;
                double leftNodeY      = leftNode.Y;

                // Find also the element on the other side of the face
                double      otherElementX, otherElementY;
                MeshElement otherElement = elementFace.OtherElement(element);
                if (otherElement != null)
                {
                    otherElementX         = otherElement.XCenter;
                    otherElementY         = otherElement.YCenter;
                    weights.Element2Index = otherElement.Index;
                }
                else
                {
                    // No other element - boundary face, use center of face.
                    otherElementX = 0.5 * (rightNodeX + leftNodeX);
                    otherElementY = 0.5 * (rightNodeY + leftNodeY);
                    // Use "itself" as element-2
                    weights.Element2Index = element.Index;
                }


                // Check if point is on the right side of the line between element and other-element
                if (MeshExtensions.IsPointInsideLines(x, y,
                                                      elementXCenter, elementYCenter,
                                                      rightNodeX, rightNodeY,
                                                      otherElementX, otherElementY))
                {
                    (double w1, double w2, double w3) =
                        MeshExtensions.InterpolationWeights(
                            x, y, elementXCenter, elementYCenter,
                            rightNodeX, rightNodeY, otherElementX, otherElementY);
                    weights.NodeIndex      = rightNode.Index;
                    weights.Element1Weight = w1;
                    weights.NodeWeight     = w2;
                    weights.Element2Weight = w3;
                    found = true;
                    break;
                }

                // Check if point is on the left side of the line between element and other-element
                if (MeshExtensions.IsPointInsideLines(x, y,
                                                      elementXCenter, elementYCenter,
                                                      otherElementX, otherElementY,
                                                      leftNodeX, leftNodeY))
                {
                    (double w1, double w2, double w3) =
                        MeshExtensions.InterpolationWeights(
                            x, y, elementXCenter, elementYCenter,
                            otherElementX, otherElementY, leftNodeX, leftNodeY);
                    weights.NodeIndex      = leftNode.Index;
                    weights.Element1Weight = w1;
                    weights.Element2Weight = w2;
                    weights.NodeWeight     = w3;
                    found = true;
                    break;
                }
            }

            if (!found) // Should never happen, but just in case
            {
                weights.Element1Weight = 1;
                weights.Element2Weight = 0;
                weights.NodeWeight     = 0;
                weights.Element2Index  = element.Index;
                weights.NodeIndex      = element.Nodes[0].Index;
            }

            return(weights);
        }
示例#17
0
    public static Mesh CombineEx(MeshInstance[] combines, bool generateStrips, ref MeshElement element)
    {
        int vertexCount = 0;
        int triangleCount = 0;
        int stripCount = 0;
        for (int i = 0; i < combines.Length; i++)
        {
            if (combines[i].mesh != null)
            {
                vertexCount += combines[i].mesh.vertexCount;

                if (generateStrips)
                {
                    // SUBOPTIMAL FOR PERFORMANCE
                    int curStripCount = combines[i].mesh.GetTriangles(combines[i].subMeshIndex).Length;
                    if (curStripCount != 0)
                    {
                        if (stripCount != 0)
                        {
                            if ((stripCount & 1) == 1)
                                stripCount += 3;
                            else
                                stripCount += 2;
                        }
                        stripCount += curStripCount;
                    }
                    else
                    {
                        generateStrips = false;
                    }
                }
            }
        }

        // Precomputed how many triangles we need instead
        //在save时,这些数据全部不需要改变,要改变的只有顶点的位置.
        if (!generateStrips)
        {
            for (int i = 0; i < combines.Length; i++)
            {
                if (combines[i].mesh != null)
                {
                    triangleCount += combines[i].mesh.GetTriangles(combines[i].subMeshIndex).Length;
                }
            }
        }

        Vector3[] vertices = element.vertices;
        Vector3[] normals = element.normals;
        Vector4[] tangents = element.tangents;
        Vector2[] uv = element.uv;
        Vector2[] uv1 = element.uv1;
        Color[] colors = element.colors;
        int[] triangles = element.triangles;
        int[] strip = element.strip;

        int offset;

        offset = 0;
        for (int i = 0; i < combines.Length; i++)
        {
            if (combines[i].mesh != null)
                Copy(combines[i].mesh.vertexCount, combines[i].mesh.vertices, vertices, ref offset, combines[i].transform);
        }

        //offset = 0;
        //for (int i = 0; i < combines.Length; i++)
        //{
        //    if (combines[i].mesh != null)
        //    {
        //        Matrix4x4 invTranspose = combines[i].transform;
        //        invTranspose = invTranspose.inverse.transpose;
        //        CopyNormal(combines[i].mesh.vertexCount, combines[i].mesh.normals, normals, ref offset, invTranspose);
        //    }

        //}
        //offset = 0;
        //for (int i = 0; i < combines.Length; i++)
        //{
        //    if (combines[i].mesh != null)
        //    {
        //        Matrix4x4 invTranspose = combines[i].transform;
        //        invTranspose = invTranspose.inverse.transpose;
        //        CopyTangents(combines[i].mesh.vertexCount, combines[i].mesh.tangents, tangents, ref offset, invTranspose);
        //    }

        //}
        //offset = 0;
        //for (int i = 0; i < combines.Length; i++)
        //{
        //    if (combines[i].mesh != null)
        //        Copy(combines[i].mesh.vertexCount, combines[i].mesh.uv, uv, ref offset);
        //}

        //offset = 0;
        //for (int i = 0; i < combines.Length; i++)
        //{
        //    if (combines[i].mesh)
        //        Copy(combines[i].mesh.vertexCount, combines[i].mesh.uv2, uv1, ref offset);
        //}

        //offset = 0;
        //for (int i = 0; i < combines.Length; i++)
        //{
        //    if (combines[i].mesh)
        //        CopyColors(combines[i].mesh.vertexCount, combines[i].mesh.colors, colors, ref offset);
        //}

        //int triangleOffset = 0;
        //int stripOffset = 0;
        //int vertexOffset = 0;
        //for (int i = 0; i < combines.Length; i++)
        //{
        //    if (combines[i].mesh)
        //    {
        //        if (generateStrips)
        //        {
        //            int[] inputstrip = combines[i].mesh.GetTriangles(combines[i].subMeshIndex);
        //            if (stripOffset != 0)
        //            {
        //                if ((stripOffset & 1) == 1)
        //                {
        //                    strip[stripOffset + 0] = strip[stripOffset - 1];
        //                    strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
        //                    strip[stripOffset + 2] = inputstrip[0] + vertexOffset;
        //                    stripOffset += 3;
        //                }
        //                else
        //                {
        //                    strip[stripOffset + 0] = strip[stripOffset - 1];
        //                    strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
        //                    stripOffset += 2;
        //                }
        //            }

        //            for (int j = 0; j < inputstrip.Length; j++)
        //            {
        //                strip[j + stripOffset] = inputstrip[j] + vertexOffset;
        //            }
        //            stripOffset += inputstrip.Length;
        //        }
        //        else
        //        {
        //            int[] inputtriangles = combines[i].mesh.GetTriangles(combines[i].subMeshIndex);
        //            for (int j = 0; j < inputtriangles.Length; j++)
        //            {
        //                triangles[j + triangleOffset] = inputtriangles[j] + vertexOffset;
        //            }
        //            triangleOffset += inputtriangles.Length;
        //        }

        //        vertexOffset += combines[i].mesh.vertexCount;
        //    }
        //}

        Mesh mesh = element.mesh;
        mesh.vertices = vertices;
        //mesh.normals = normals;
        //mesh.colors = colors;
        //mesh.uv = uv;
        //mesh.uv2 = uv1;
        //mesh.tangents = tangents;
        //if (generateStrips)
        //    mesh.SetTriangles(strip, 0);
        //else
        //    mesh.triangles = triangles;
        return mesh;
    }
        public void InterpolationTest(string sourceMeshFileName, string targetMeshFileName, CircularValueTypes cvt = CircularValueTypes.Normal)
        {
            // Source mesh
            MeshFile meshFile = MeshFile.ReadMesh(sourceMeshFileName);
            MeshData mesh     = meshFile.ToMeshData();

            mesh.BuildDerivedData();

            // Mesh to interpolate to
            MeshFile targetFile = MeshFile.ReadMesh(targetMeshFileName);
            MeshData targetmesh = targetFile.ToMeshData();

            // Setup interpolator
            MeshInterpolator2D interpolator = new MeshInterpolator2D(mesh)
            {
                CircularType = cvt, AllowExtrapolation = true
            };

            interpolator.SetupNodeInterpolation();
            interpolator.SetTarget(targetmesh);

            // Find reference x and y value as the smallest x and y value
            double xMin = mesh.Nodes.Select(mn => mn.X).Min();
            double xMax = mesh.Nodes.Select(mn => mn.X).Max();
            double yMin = mesh.Nodes.Select(mn => mn.Y).Min();
            double yMax = mesh.Nodes.Select(mn => mn.Y).Max();

            // Function over the (x,y) plane.
            Func <double, double, double> function = ValueFunction(cvt, xMin, yMin, xMax, yMax);

            // Calculate element center values of function
            double[] elmtVals = new double[mesh.Elements.Count];
            for (int i = 0; i < mesh.Elements.Count; i++)
            {
                MeshElement elmt = mesh.Elements[i];
                elmtVals[i] = function(elmt.XCenter, elmt.YCenter);
            }

            // Write out bounds, to check we got things right
            Console.Out.WriteLine("{0,10} (min,max) = ({1},{2})", cvt, elmtVals.Min(), elmtVals.Max());

            // Interpolate to nodes
            double[] targetValues = new double[targetmesh.Elements.Count];
            interpolator.InterpolateToTarget(elmtVals, targetValues);

            // Check node values
            for (int i = 0; i < targetmesh.Elements.Count; i++)
            {
                MeshElement targetElmt  = targetmesh.Elements[i];
                double      exactValue  = function(targetElmt.XCenter, targetElmt.YCenter);
                double      interpValue = targetValues[i];
                double      diff        = exactValue - interpValue;

                // Check if target element has a boundary node.
                // Nodes on the boundary may not have correctly interpolated value due to
                // inverse distance interpolation on the boundary, and hence also interpolation
                // to target element value will not be exact. So only check on those elements that are
                // fully internal (no boundary nodes).
                bool internalElmt = targetElmt.Nodes.Select(node => node.Code).All(code => code == 0);

                if (internalElmt && diff > 1e-6 * Math.Max(Math.Abs(exactValue), 1))
                {
                    string msg = string.Format("{0,2} : {1}-{2}={3} ({4},{5})", i, exactValue, interpValue, diff, targetElmt.XCenter, targetElmt.YCenter);
                    Console.Out.WriteLine(msg);
                    Assert.Fail(msg);
                }
            }
        }