コード例 #1
0
        public override void Update()
        {
            base.begin_update();
            int start_timestamp = this.CurrentInputTimestamp;

            if (MeshSource == null)
            {
                throw new Exception("ReprojectOp: must set valid MeshSource to compute!");
            }

            try {
                if (ReprojectMode == ReprojectModes.SmoothSurfaceFlow)
                {
                    ResultMesh = compute_smooth();
                }
                else if (ReprojectMode == ReprojectModes.SharpEdgesFlow)
                {
                    ResultMesh = compute_sharp_edge_flow();
                }
                else
                {
                    ResultMesh = compute_bounded_distance();
                }

                base.complete_update();
            } catch (Exception e) {
                PostOnOperatorException(e);
                ResultMesh = base.make_failure_output(MeshSource.GetDMeshUnsafe());
                base.complete_update();
            }
        }
コード例 #2
0
        public virtual void Update()
        {
            base.begin_update();

            if (MeshSource == null)
            {
                throw new Exception("ExtrudeMeshOp: must set valid MeshSource to compute!");
            }

            IMesh meshIn = MeshSource.GetIMesh();

            //ISpatial spatialIn = MeshSource.GetSpatial();

            ExtrudedMesh = new DMesh3(meshIn, MeshHints.None);

            MeshExtrudeMesh extrude = new MeshExtrudeMesh(ExtrudedMesh);

            extrude.ExtrudedPositionF = (v, n, vid) => {
                return(v + extrude_dist * (Vector3d)n);
            };
            extrude.Extrude();

            ApplyModifiers(ExtrudedMesh);

            base.complete_update();
        }
コード例 #3
0
        public virtual void Update()
        {
            base.begin_update();
            int start_timestamp = this.CurrentInputTimestamp;

            if (MeshSource == null)
            {
                throw new Exception("GenerateClosedMeshOp: must set valid MeshSource to compute!");
            }

            try {
                DMesh3   inputmesh    = MeshSource.GetDMeshUnsafe();
                ISpatial inputSpatial = MeshSource.HasSpatial ? MeshSource.GetSpatial() : null;

                DMeshAABBTree3 spatial = (inputSpatial != null && inputSpatial is DMeshAABBTree3) ?
                                         inputSpatial as DMeshAABBTree3 : get_cached_spatial(inputmesh);
                DMesh3 meshIn = new DMesh3(inputmesh);

                MeshRepairOrientation repair = new MeshRepairOrientation(meshIn, spatial);
                repair.OrientComponents();
                repair.SolveGlobalOrientation();

                if (invert_result)
                {
                    meshIn.ReverseOrientation(true);
                }

                ResultMesh = meshIn;
                base.complete_update();
            } catch (Exception e) {
                PostOnOperatorException(e);
                ResultMesh = base.make_failure_output(MeshSource.GetDMeshUnsafe());
                base.complete_update();
            }
        }
コード例 #4
0
        public virtual void Update()
        {
            base.begin_update();

            if (MeshSource == null)
            {
                throw new Exception("MeshDeformationOp: must set valid MeshSource to compute!");
            }

            IMesh meshIn = MeshSource.GetIMesh();

            DMesh3 mesh = new DMesh3(meshIn, MeshHints.None);

            MeshNormals.QuickCompute(mesh);

            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v      = mesh.GetVertex(vid);
                Vector3f n      = mesh.GetVertexNormal(vid);
                Vector3d newPos = deformF(v, n, vid);
                mesh.SetVertex(vid, newPos);
            }

            MeshNormals.QuickCompute(mesh);

            DisplacedMesh = mesh;

            base.complete_update();
        }
コード例 #5
0
            private List <SegaSaturnPoint> GetPoints()
            {
                MeshSource positionSource = this.MeshSources.FirstOrDefault(item => item.MeshSourceKind == MeshSource.MeshSourceKindEnum.Position);

                if (positionSource == null)
                {
                    throw new InvalidOperationException("no Position source in Collada");
                }
                List <SegaSaturnPoint> toReturn = new List <SegaSaturnPoint>();

                float coef = 1.0f;
                float max  = positionSource.Floats.Max();

                if (max < 50.0f)
                {
                    coef = 50.0f / max;
                }
                else
                {
                    coef = max / 50.0f;
                }
                for (int i = 0; i < positionSource.Floats.Count; i += 3)
                {
                    toReturn.Add(new SegaSaturnPoint(positionSource.Floats[i + 0] * coef, positionSource.Floats[i + 1] * coef, positionSource.Floats[i + 2] * coef));
                }
                return(toReturn);
            }
コード例 #6
0
        public virtual void Update()
        {
            base.begin_update();

            if (MeshSource == null)
            {
                throw new Exception("TrimMeshFromCurveOp: must set valid MeshSource to compute!");
            }
            if (CurveSource == null)
            {
                throw new Exception("TrimMeshFromCurveOp: must set valid CurveSource to compute!");
            }

            IMesh meshIn = MeshSource.GetIMesh();
            //ISpatial spatialIn = MeshSource.GetSpatial();

            DCurve3 curve = new DCurve3(CurveSource.GetICurve());

            TrimmedMesh = new DMesh3(meshIn, MeshHints.None);

            AxisAlignedBox3d bounds = TrimmedMesh.CachedBounds;
            Vector3d         seed   = bounds.Center + bounds.Extents.y * Vector3d.AxisY;

            MeshTrimLoop trim = new MeshTrimLoop(TrimmedMesh, curve, seed, null);

            trim.Trim();

            ApplyModifiers(TrimmedMesh);

            base.complete_update();
        }
コード例 #7
0
ファイル: MeshSourceTests.cs プロジェクト: p1x/TheIslands
        public void BuildingWithZeroMaxTriangles_ProducesEmptyMesh()
        {
            using (var meshSource = new MeshSource(0)) {
                using (var builder = meshSource.GetBuilder())
                    builder.AddTriangle(Vector3.zero, Vector3.forward, Vector3.one);

                AssertEmptyMesh(meshSource.Mesh);
            }
        }
コード例 #8
0
            private List <SegaSaturnTexture> GetTextures(List <Texture> textureLibrary, List <SegaSaturnAttribute> attributes, int maxTextureSize)
            {
                if (textureLibrary == null || textureLibrary.Count <= 0)
                {
                    return(new List <SegaSaturnTexture>());
                }
                if (textureLibrary.Count > 1)
                {
                    MessageBox.Show("Sorry, only one texture per file are supported yet :'(", Editor.Instance.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw new InvalidOperationException("Too many textures");
                }
                MeshSource textureSource = this.MeshSources.FirstOrDefault(item => item.MeshSourceKind == MeshSource.MeshSourceKindEnum.Texcoord);

                if (textureSource == null)
                {
                    return(new List <SegaSaturnTexture>());
                }
                List <SegaSaturnTexture> toReturn            = new List <SegaSaturnTexture>();
                Dictionary <string, SegaSaturnTexture>  dict = new Dictionary <string, SegaSaturnTexture>();
                List <SegaSaturnTextureVerticesIndexes> list = this.GetTextureVerticesIndexes();
                Texture tmp = textureLibrary.First();
                Bitmap  img = JoMapEditorTools.GetBitmap(tmp.Path);

                if (img.Width > maxTextureSize && img.Height > maxTextureSize)
                {
                    img = JoMapEditorTools.ResizeImage(img, maxTextureSize, maxTextureSize);
                }
                else if (img.Width > maxTextureSize)
                {
                    img = JoMapEditorTools.ResizeImage(img, maxTextureSize, img.Height);
                }
                else if (img.Height > maxTextureSize)
                {
                    img = JoMapEditorTools.ResizeImage(img, img.Width, maxTextureSize);
                }
                for (int i = 0; i < list.Count; ++i)
                {
                    SegaSaturnTextureCoordinates p1 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice1);
                    SegaSaturnTextureCoordinates p2 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice2);
                    SegaSaturnTextureCoordinates p3 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice3);
                    SegaSaturnTextureCoordinates p4 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice4);
                    if (p1.Hash == p2.Hash && p2.Hash == p3.Hash)
                    {
                        continue;
                    }
                    SegaSaturnTexture texture = SegaSaturnTexture.ConvertFrom(img, tmp.Name ?? Path.GetFileNameWithoutExtension(tmp.Path), p1, p2, p3, p4, list[i].IsTriangleMapping);
                    if (!dict.ContainsKey(texture.Hash))
                    {
                        texture.Name += toReturn.Count.ToString();
                        dict.Add(texture.Hash, texture);
                        toReturn.Add(texture);
                    }
                    attributes[i].SpriteIndex = toReturn.FindIndex(item => item.Hash == texture.Hash);
                    attributes[i].Color       = null;
                }
                return(toReturn);
            }
コード例 #9
0
ファイル: MeshSmooth.cs プロジェクト: z3nth10n/unity-themes
 public void OnEnable()
 {
     this.source = this.GetMeshSource();
     if (this.original.IsNull())
     {
         this.original = this.GetMesh();
     }
     this.needsUpdate = true;
 }
コード例 #10
0
ファイル: MeshSourceTests.cs プロジェクト: p1x/TheIslands
        public void BuildingWithExcessiveMaxTriangles_ProducesValidMesh()
        {
            using (var meshSource = new MeshSource(24)) {
                var bounds = new Bounds(new Vector3(0.5f, 0.5f, 0.5f), Vector3.one);
                using (var builder = meshSource.GetBuilder()) {
                    builder.Bounds = bounds;
                    builder.AddTriangle(Vector3.zero, Vector3.forward, Vector3.one);
                }

                AssertValidMesh(meshSource.Mesh, 3, 3, bounds);
            }
        }
コード例 #11
0
            private List <SegaSaturnNormal> GetNormals()
            {
                MeshSource normalSource = this.MeshSources.FirstOrDefault(item => item.MeshSourceKind == MeshSource.MeshSourceKindEnum.Normal);

                if (normalSource == null)
                {
                    List <SegaSaturnNormal> toReturn = new List <SegaSaturnNormal>();
                    for (int i = 0; i < this.PolygonCount; ++i)
                    {
                        toReturn.Add(new SegaSaturnNormal(0.0f, 1.0f, 0.0f));
                    }
                    return(toReturn);
                }
                if (this.GeometryType == GeometryTypeEnum.QuadPolylist)
                {
                    List <SegaSaturnNormal> toReturn = new List <SegaSaturnNormal>();
                    int i = normalSource.IndexOffset;
                    while (i < this.VertexIndexes.Count)
                    {
                        int index = this.VertexIndexes[i];
                        toReturn.Add(new SegaSaturnNormal(normalSource.Floats[index], normalSource.Floats[index + 1], normalSource.Floats[index + 2]));
                        i += (this.IndexOffsetRange + 1) * 4;
                    }
                    return(toReturn);
                }
                if (this.GeometryType == GeometryTypeEnum.Polygons)
                {
                    int vcountIndex = 0;
                    List <SegaSaturnNormal> toReturn = new List <SegaSaturnNormal>();
                    int i = normalSource.IndexOffset;
                    while (i < this.VertexIndexes.Count)
                    {
                        int index = this.VertexIndexes[i];
                        toReturn.Add(new SegaSaturnNormal(normalSource.Floats[index], normalSource.Floats[index + 1], normalSource.Floats[index + 2]));
                        i += (this.IndexOffsetRange + 1) * this.VertexCount[vcountIndex];
                        ++vcountIndex;
                    }
                    return(toReturn);
                }
                else
                {
                    List <SegaSaturnNormal> toReturn = new List <SegaSaturnNormal>();
                    int i = normalSource.IndexOffset;
                    while (i < this.VertexIndexes.Count)
                    {
                        int index = this.VertexIndexes[i];
                        toReturn.Add(new SegaSaturnNormal(normalSource.Floats[index], normalSource.Floats[index + 1], normalSource.Floats[index + 2]));
                        i += (this.IndexOffsetRange + 1) * 3;
                    }
                    return(toReturn);
                }
            }
コード例 #12
0
        public void ExportMesh(Mesh mesh, PrefabContext prefabContext)
        {
            if (!_engine.Options.ExportMeshes)
            {
                return;
            }
            var meshSource           = new MeshSource(mesh);
            var mdlFilePath          = EvaluateMeshName(mesh, prefabContext);
            var assetKey             = mesh.GetKey();
            var lastWriteDateTimeUtc = ExportUtils.GetLastWriteTimeUtc(mesh);

            ExportMeshModel(meshSource, mdlFilePath, assetKey, lastWriteDateTimeUtc);
        }
コード例 #13
0
ファイル: MeshSourceTests.cs プロジェクト: p1x/TheIslands
        public void BuildingWithInsufficientMaxTriangles_ProducesValidMeshWithLimitedSize()
        {
            using (var meshSource = new MeshSource(1)) {
                var bounds = new Bounds(new Vector3(0.5f, 0.5f, 0.5f), Vector3.one);
                using (var builder = meshSource.GetBuilder()) {
                    builder.Bounds = bounds;
                    builder.AddTriangle(Vector3.zero, Vector3.forward, Vector3.one);
                    builder.AddTriangle(Vector3.one, Vector3.forward + Vector3.one, Vector3.one + Vector3.one);
                }

                AssertValidMesh(meshSource.Mesh, 3, 3, bounds);
            }
        }
コード例 #14
0
 private void SetVertices(InputLocalOffset input, int[] p, int stepSize, Dictionary <string, MeshSource> sources, DAEVertexDescription[] outputVertices)
 {
     if (input.semantic.Equals("VERTEX"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].Vertex = meshSource.GetVector3(idx);
         }
     }
     else if (input.semantic.Equals("NORMAL"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].Normal = meshSource.GetVector3(idx);
         }
     }
     else if (input.semantic.Equals("TEXCOORD"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].TexCoord = meshSource.GetVector3(idx);
             outputVertices[i].TexCoord = new DAEVector3(outputVertices[i].TexCoord.X, 1 - outputVertices[i].TexCoord.Y, outputVertices[i].TexCoord.Z);
         }
     }
     else if (input.semantic.Equals("TEXTANGENT"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].TexTangent = meshSource.GetVector3(idx);
         }
     }
     else if (input.semantic.Equals("TEXBINORMAL"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].TexBinormal = meshSource.GetVector3(idx);
         }
     }
 }
コード例 #15
0
        public virtual void Update()
        {
            base.begin_update();
            int start_timestamp = this.CurrentInputTimestamp;

            if (MeshSource == null)
            {
                throw new Exception("GenerateClosedMeshOp: must set valid MeshSource to compute!");
            }

            try {
                DMesh3 inputmesh = MeshSource.GetDMeshUnsafe();

                DMesh3 meshIn = new DMesh3(inputmesh);

                MeshAutoRepair repair = new MeshAutoRepair(meshIn);
                repair.RemoveMode        = (MeshAutoRepair.RemoveModes)(int) remove_inside_mode;
                repair.MinEdgeLengthTol  = min_edge_length;
                repair.ErosionIterations = erosion_iters;
                repair.Progress          = new ProgressCancel(is_invalidated);

                bool bOK = repair.Apply();

                if (bOK && invert_result)
                {
                    meshIn.ReverseOrientation(true);
                }

                if (is_invalidated())
                {
                    meshIn = null;
                }

                if (bOK)
                {
                    ResultMesh = meshIn;
                }
                else
                {
                    ResultMesh = base.make_failure_output(inputmesh);
                }
                base.complete_update();
            } catch (Exception e) {
                PostOnOperatorException(e);
                ResultMesh = base.make_failure_output(MeshSource.GetDMeshUnsafe());
                base.complete_update();
            }
        }
コード例 #16
0
        void ComputeThreadFunc(object thread_data)
        {
            thread_timestamp data = thread_data as thread_timestamp;

            try {
                DMesh3 result = MeshSource.ExtractDMesh();
                lock (compute_thread_lock) {
                    computed_result = result;
                    computing       = false;
                }
            } catch (Exception e) {
                background_exception     = e;
                computing                = false;
                last_exception_timestamp = data.timestamp;
            }
        }
コード例 #17
0
 private void ParseMeshSource(XmlNode meshNode, Geometry geometry)
 {
     foreach (XmlNode sourceNode in meshNode.GetElementsByTagNameCaseInsensetive("source"))
     {
         MeshSource source = new MeshSource
         {
             Id             = sourceNode.GetAttributeByNameCaseInsensetive("id"),
             Name           = sourceNode.GetAttributeByNameCaseInsensetive("name"),
             MeshSourceKind = MeshSource.MeshSourceKindEnum.Unknown
         };
         XmlNode floatArrayNode = sourceNode.GetElementsByTagNameCaseInsensetive("float_array").FirstOrDefault();
         if (floatArrayNode != null)
         {
             List <string> floatArray = new List <string>(floatArrayNode.InnerText.Split(new[] { " ", "\t", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries));
             source.Floats = floatArray.ConvertAll(item => float.Parse(item, CultureInfo.InvariantCulture));
             geometry.MeshSources.Add(source);
         }
     }
     foreach (XmlNode verticesNode in meshNode.GetElementsByTagNameCaseInsensetive("vertices"))
     {
         this.ParseMeshInput(verticesNode, geometry);
     }
 }
コード例 #18
0
        public void ExportMesh(GameObject go, PrefabContext prefabContext)
        {
            if (!_engine.Options.ExportMeshes)
            {
                return;
            }
            var proBuilderMesh      = go.GetComponent <ProBuilderMesh>();
            var skinnedMeshRenderer = go.GetComponent <SkinnedMeshRenderer>();
            var meshFilter          = go.GetComponent <MeshFilter>();

            if (proBuilderMesh != null)
            {
                ExportProBuilderMeshModel(proBuilderMesh, prefabContext);
            }
            else
            {
                Mesh mesh = null;
                if (skinnedMeshRenderer != null)
                {
                    mesh = skinnedMeshRenderer.sharedMesh;
                }
                else if (meshFilter != null)
                {
                    mesh = meshFilter.sharedMesh;
                }
                var meshSource = new MeshSource(mesh, skinnedMeshRenderer);
                ExportMeshModel(meshSource, EvaluateMeshName(mesh, prefabContext), mesh.GetKey(),
                                ExportUtils.GetLastWriteTimeUtc(mesh));
            }


            for (var i = 0; i < go.transform.childCount; ++i)
            {
                ExportMesh(go.transform.GetChild(i).gameObject, prefabContext);
            }
        }
コード例 #19
0
 /// <summary>
 /// Setup constructor
 /// </summary>
 public MeshTaggedSource( MeshSource source, string semantic )
 {
     m_Semantic = semantic;
     m_Source = source;
 }
コード例 #20
0
        /// <summary>
        /// compute SDF for the scan object, and then compute offset iso-contours
        /// </summary>
        void compute_offset_meshes()
        {
            int sdf_cells  = 128;
            int mesh_cells = 128;

            double max_offset = inner_offset + thickness;

            if (max_offset > cached_sdf_max_offset)
            {
                DMesh3 meshIn = new DMesh3(MeshSource.GetIMesh(), MeshHints.IsCompact, MeshComponents.None);
                MeshTransforms.FromFrame(meshIn, cachedInputsTransform);

                // [RMS] reduce this mesh? speeds up SDF quite a bit...
                Reducer r = new Reducer(meshIn);
                r.ReduceToTriangleCount(2500);

                double cell_size           = meshIn.CachedBounds.MaxDim / sdf_cells;
                int    exact_cells         = (int)((max_offset) / cell_size) + 1;
                MeshSignedDistanceGrid sdf = new MeshSignedDistanceGrid(meshIn, cell_size)
                {
                    ExactBandWidth = exact_cells
                };
                sdf.Compute();
                cached_sdf            = sdf;
                cached_sdf_max_offset = max_offset;
                cached_sdf_bounds     = meshIn.CachedBounds;

                cached_inner_sdf_offset = 0;
                cached_outer_sdf_offset = 0;
            }

            if (cached_inner_sdf_offset != inner_offset || cached_outer_sdf_offset != max_offset)
            {
                var iso = new DenseGridTrilinearImplicit(cached_sdf.Grid, cached_sdf.GridOrigin, cached_sdf.CellSize);

                MarchingCubes c = new MarchingCubes()
                {
                    Implicit = iso
                };
                c.Bounds   = cached_sdf_bounds;
                c.CubeSize = c.Bounds.MaxDim / mesh_cells;
                c.Bounds.Expand(max_offset + 3 * c.CubeSize);

                if (cached_inner_sdf_offset != inner_offset)
                {
                    c.IsoValue = inner_offset;
                    c.Generate();
                    InnerOffsetMesh = c.Mesh;
                    Reducer reducer = new Reducer(InnerOffsetMesh);
                    reducer.ReduceToEdgeLength(c.CubeSize / 2);
                    InnerOffsetMeshSpatial  = new DMeshAABBTree3(InnerOffsetMesh, true);
                    cached_inner_sdf_offset = inner_offset;
                }

                if (cached_outer_sdf_offset != max_offset)
                {
                    c.IsoValue = inner_offset + thickness;
                    c.Generate();
                    OuterOffsetMesh = c.Mesh;
                    Reducer reducer = new Reducer(OuterOffsetMesh);
                    reducer.ReduceToEdgeLength(c.CubeSize / 2);
                    OuterOffsetMeshSpatial  = new DMeshAABBTree3(OuterOffsetMesh, true);
                    cached_outer_sdf_offset = max_offset;
                }
            }

            //Util.WriteDebugMesh(MeshSource.GetIMesh(), "c:\\scratch\\__OFFESTS_orig.obj");
            //Util.WriteDebugMesh(InnerOffsetMesh, "c:\\scratch\\__OFFESTS_inner.obj");
            //Util.WriteDebugMesh(OuterOffsetMesh, "c:\\scratch\\__OFFESTS_outer.obj");
        }
コード例 #21
0
        public virtual void Update()
        {
            base.begin_update();
            int start_timestamp = this.LastUpdateTimestamp;

            if (MeshSource == null)
            {
                throw new Exception("TrimMeshFromCurveOp: must set valid MeshSource to compute!");
            }
            if (CurveSource == null)
            {
                throw new Exception("TrimMeshFromCurveOp: must set valid CurveSource to compute!");
            }

            LocalProfiler p = new LocalProfiler();

            p.Start("offset");

            bool is_preview = false;

            // cache copy of input mesh and spatial DS
            DMesh3 inputMesh = MeshSource.GetDMeshUnsafe();

            if (cachedInputMesh == null || input_mesh_modified_counter != input_mesh_cache_timestamp)
            {
                cachedInputMesh            = new DMesh3(inputMesh, false, MeshComponents.All);
                cachedInputMeshSpatial     = new DMeshAABBTree3(cachedInputMesh, true);
                input_mesh_cache_timestamp = input_mesh_modified_counter;
            }

            // have to cache this in case it changes during compute
            // TODO: should be caching all parameters!
            cachedInputsTransform = InputsTransform;

            // discard caches
            // TODO: we still have a race condition, because we could get an invalidate() between
            // begin_update() above and here. In that case we will be losing the cache discard flag.
            // Should be using update timestamp...
            if (pending_cache_discard)
            {
                cached_sdf_max_offset   = 0;
                cached_inner_sdf_offset = 0;
                cached_outer_sdf_offset = 0;
                pending_cache_discard   = true;
            }

            try {
                //compute_offset_meshes();
                compute_offset_meshes_nosdf();
            } catch {
                // we will do nothing here, let later failures handle it
            }

            p.Stop("offset");
            p.Start("trim");

            // trimmed mesh doesn't change unless curve changed...
            try {
                compute_trimmed_mesh();
            } catch {
                set_failure_output(null);
                goto failed;
            }

            p.Stop("trim");
            p.Start("inner_wall");

            try {
                compute_inner_wall();
            } catch {
                set_failure_output(null);
                goto failed;
            }

            p.Stop("inner_wall");
            p.Start("outer_wall");

            try {
                compute_outer_wall();
            } catch {
                set_failure_output(InnerMesh);
                goto failed;
            }

            p.Stop("outer_wall");

            p.Start("base");


            is_preview = (this.CurrentInputTimestamp != start_timestamp);
            try {
                DMesh3 baseMesh    = new DMesh3(SocketMesh);
                bool   base_failed = false;
                do_base(baseMesh, is_preview, out base_failed);
                if (base_failed)
                {
                    set_failure_output(SocketMesh);
                    goto failed;
                }
                else
                {
                    SocketMesh = baseMesh;
                }
            } catch (Exception e) {
                set_failure_output(SocketMesh);
                goto failed;
            }

            p.Stop("base");
            f3.DebugUtil.Log(p.AllTimes());

            Vector3f setColor = is_preview ? PartialSocketVertexColor : SocketVertexColor;

            foreach (int vid in SocketMesh.VertexIndices())
            {
                SocketMesh.SetVertexColor(vid, setColor);
            }

            ResultMesh         = SocketMesh;
            last_result_status = (is_preview) ? ResultStatus.PreviewResult : ResultStatus.FullResult;

failed:
            base.complete_update();
        }
コード例 #22
0
        public virtual void Update()
        {
            if (MeshSource == null)
            {
                throw new Exception("EnclosedRegionOffsetOp: must set valid MeshSource to compute!");
            }
            if (MeshSource.HasSpatial == false)
            {
                throw new Exception("EnclosedRegionOffsetOp: MeshSource must have spatial data structure!");
            }

            IMesh imesh = MeshSource.GetIMesh();

            if (imesh.HasVertexNormals == false)
            {
                throw new Exception("EnclosedRegionOffsetOp: input mesh does not have surface normals...");
            }
            if (imesh is DMesh3 == false)
            {
                throw new Exception("RegionOffsetOp: in current implementation, input mesh must be a DMesh3. Ugh.");
            }
            DMesh3   mesh    = imesh as DMesh3;
            ISpatial spatial = MeshSource.GetSpatial();

            DCurve3           curve = new DCurve3(CurveSource.GetICurve());
            MeshFacesFromLoop loop  = new MeshFacesFromLoop(mesh, curve, spatial);

            // extract submesh
            RegionOperator op      = new RegionOperator(mesh, loop.InteriorTriangles);
            DMesh3         submesh = op.Region.SubMesh;

            // find boundary verts and nbr ring
            HashSet <int> boundaryV    = new HashSet <int>(MeshIterators.BoundaryEdgeVertices(submesh));
            HashSet <int> boundaryNbrs = new HashSet <int>();

            foreach (int vid in boundaryV)
            {
                foreach (int nbrvid in submesh.VtxVerticesItr(vid))
                {
                    if (boundaryV.Contains(nbrvid) == false)
                    {
                        boundaryNbrs.Add(nbrvid);
                    }
                }
            }

            // [TODO] maybe should be not using vertex normal here?
            // use an averaged normal, or a constant for patch?

            // offset mesh if requested
            if (Math.Abs(offset_distance) > 0.0001)
            {
                foreach (int vid in submesh.VertexIndices())
                {
                    if (boundaryV.Contains(vid))
                    {
                        continue;
                    }
                    // if inner ring is non-zero, then it gets preserved below, and
                    // creates a crease...
                    //double dist = boundaryNbrs.Contains(vid) ? (offset_distance / 2) : offset_distance;
                    double dist = boundaryNbrs.Contains(vid) ? 0 : offset_distance;
                    submesh.SetVertex(vid,
                                      submesh.GetVertex(vid) + (float)dist * submesh.GetVertexNormal(vid));
                }
            }


            //double t = MathUtil.Clamp(1.0 - SmoothAlpha, 0.1, 1.0);
            double t = 1.0 - SmoothAlpha;

            t = t * t;
            double boundary_t = 5.0;
            double ring_t     = 1.0;

            // smooth submesh, with boundary-ring constraints
            LaplacianMeshSmoother smoother = new LaplacianMeshSmoother(submesh);

            foreach (int vid in submesh.VertexIndices())
            {
                if (boundaryV.Contains(vid))
                {
                    smoother.SetConstraint(vid, submesh.GetVertex(vid), boundary_t, true);
                }
                else if (boundaryNbrs.Contains(vid))
                {
                    smoother.SetConstraint(vid, submesh.GetVertex(vid), ring_t);
                }
                else
                {
                    smoother.SetConstraint(vid, submesh.GetVertex(vid), t);
                }
            }
            smoother.SolveAndUpdateMesh();


            // turn into displacement vectors
            Displacement.Clear();
            Displacement.Resize(mesh.MaxVertexID);
            foreach (int subvid in op.Region.SubMesh.VertexIndices())
            {
                Vector3d subv    = op.Region.SubMesh.GetVertex(subvid);
                int      basevid = op.Region.SubToBaseV[subvid];
                Vector3d basev   = op.Region.BaseMesh.GetVertex(basevid);
                Displacement[basevid] = subv - basev;
            }


            result_valid = true;
        }
コード例 #23
0
            private List <SegaSaturnVertices> GetVertices()
            {
                MeshSource positionSource = this.MeshSources.FirstOrDefault(item => item.MeshSourceKind == MeshSource.MeshSourceKindEnum.Position);

                if (positionSource == null)
                {
                    throw new InvalidOperationException("no Position source in Collada");
                }
                if (this.GeometryType == GeometryTypeEnum.QuadPolylist)
                {
                    List <SegaSaturnVertices> toReturn = new List <SegaSaturnVertices>();
                    int i = positionSource.IndexOffset;
                    while (i < this.VertexIndexes.Count)
                    {
                        SegaSaturnVertices vertices = new SegaSaturnVertices();
                        vertices.Vertice1 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        vertices.Vertice2 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        vertices.Vertice3 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        vertices.Vertice4 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        toReturn.Add(vertices);
                    }
                    return(toReturn);
                }
                if (this.GeometryType == GeometryTypeEnum.Polygons)
                {
                    int vcountIndex = 0;
                    List <SegaSaturnVertices> toReturn = new List <SegaSaturnVertices>();
                    int i = positionSource.IndexOffset;
                    while (i < this.VertexIndexes.Count)
                    {
                        SegaSaturnVertices vertices = new SegaSaturnVertices();
                        vertices.Vertice1 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        vertices.Vertice2 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        vertices.Vertice3 = this.VertexIndexes[i];
                        if (this.VertexCount[vcountIndex] == 4)
                        {
                            i += this.IndexOffsetRange + 1;
                        }
                        vertices.Vertice4 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        toReturn.Add(vertices);
                        ++vcountIndex;
                    }
                    return(toReturn);
                }
                else
                {
                    List <SegaSaturnVertices> toReturn = new List <SegaSaturnVertices>();
                    int i = positionSource.IndexOffset;
                    while (i < this.VertexIndexes.Count)
                    {
                        SegaSaturnVertices vertices = new SegaSaturnVertices();
                        vertices.Vertice1 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        vertices.Vertice2 = this.VertexIndexes[i];
                        i += this.IndexOffsetRange + 1;
                        vertices.Vertice3 = this.VertexIndexes[i];
                        vertices.Vertice4 = this.VertexIndexes[i];/*same as previous*/
                        i += this.IndexOffsetRange + 1;
                        toReturn.Add(vertices);
                    }
                    return(toReturn);
                }
            }
コード例 #24
0
ファイル: MeshSourceTests.cs プロジェクト: p1x/TheIslands
 public void AfterCreation_ProducesEmptyMesh()
 {
     using (var meshSource = new MeshSource(0)) {
         AssertEmptyMesh(meshSource.Mesh);
     }
 }
コード例 #25
0
        protected override void Update_GenerateMap()
        {
            base.begin_update();

            if (MeshSource == null)
            {
                throw new Exception("EnclosedRegionOffsetOp: must set valid MeshSource to compute!");
            }
            if (MeshSource.HasSpatial == false)
            {
                throw new Exception("EnclosedRegionOffsetOp: MeshSource must have spatial data structure!");
            }

            IMesh imesh = MeshSource.GetIMesh();

            if (imesh.HasVertexNormals == false)
            {
                throw new Exception("EnclosedRegionOffsetOp: input mesh does not have surface normals...");
            }
            if (imesh is DMesh3 == false)
            {
                throw new Exception("EnclosedRegionOffsetOp: in current implementation, input mesh must be a DMesh3. Ugh.");
            }
            DMesh3   mesh    = imesh as DMesh3;
            ISpatial spatial = MeshSource.GetSpatial();

            DCurve3           curve = new DCurve3(CurveSource.GetICurve());
            MeshFacesFromLoop loop  = new MeshFacesFromLoop(mesh, curve, spatial);

            // [RMS] this is all f'n ugly!

            MeshVertexSelection selection = new MeshVertexSelection(mesh);

            selection.SelectTriangleVertices(loop.InteriorTriangles);


            // [TODO] do this inline w/ loop below? but then no maxdist!
            Dictionary <int, double> dists = new Dictionary <int, double>();
            double max_dist = 0;

            foreach (int vid in selection)
            {
                Vector3d v = mesh.GetVertex(vid);
                int      inearseg; double nearsegt;
                double   min_dist_sqr = curve.DistanceSquared(v, out inearseg, out nearsegt);
                min_dist_sqr = Math.Sqrt(min_dist_sqr);
                max_dist     = Math.Max(min_dist_sqr, max_dist);
                dists[vid]   = min_dist_sqr;
            }


            lock (Displacement) {
                Displacement.Clear();
                Displacement.Resize(mesh.MaxVertexID);

                // todo: can do this in parallel...
                foreach (int vid in selection)
                {
                    //Vector3d v = mesh.GetVertex(vid);

                    // [TODO]...
                    double dist    = max_dist - dists[vid];
                    double falloff = Falloff.FalloffT(dist / max_dist);

                    Vector3d n = mesh.GetVertexNormal(vid);
                    n = n - n.Dot(normal) * normal;
                    n.Normalize();

                    Displacement[vid] = falloff * offset_distance * n;
                }
            }

            // smooth it?

            base.complete_update();
        }
コード例 #26
0
        protected virtual DMesh3 compute_bounded_distance()
        {
            DMesh3   sourceMesh   = MeshSource.GetDMeshUnsafe();
            ISpatial inputSpatial = MeshSource.GetSpatial();

            DMesh3   targetMesh    = TargetSource.GetDMeshUnsafe();
            ISpatial targetSpatial = TargetSource.GetSpatial();

            double max_dist = (TargetMaxDistance == double.MaxValue) ? double.MaxValue : TargetMaxDistance;

            DMesh3 meshIn = new DMesh3(sourceMesh);

            bool target_closed           = targetMesh.IsClosed();
            MeshVertexSelection roiV     = new MeshVertexSelection(meshIn);
            SpinLock            roi_lock = new SpinLock();

            gParallel.ForEach(meshIn.VertexIndices(), (vid) => {
                Vector3d pos       = meshIn.GetVertex(vid);
                Vector3d posTarget = TransformToTarget.TransformP(pos);
                double dist        = MeshQueries.NearestPointDistance(targetMesh, targetSpatial, posTarget, max_dist);
                bool inside        = (target_closed && targetSpatial.IsInside(posTarget));
                if (dist < max_dist || inside)
                {
                    bool taken = false;
                    roi_lock.Enter(ref taken);
                    roiV.Select(vid);
                    roi_lock.Exit();
                }
            });
            if (is_invalidated())
            {
                return(null);
            }

            MeshFaceSelection roi_faces = new MeshFaceSelection(meshIn, roiV, 1);

            roi_faces.ExpandToOneRingNeighbours(3);
            roi_faces.LocalOptimize();
            if (is_invalidated())
            {
                return(null);
            }

            RegionOperator op      = new RegionOperator(meshIn, roi_faces);
            DMesh3         meshROI = op.Region.SubMesh;

            if (is_invalidated())
            {
                return(null);
            }

            RemesherPro remesher = new RemesherPro(meshROI);

            remesher.SetTargetEdgeLength(TargetEdgeLength);
            remesher.PreventNormalFlips = this.PreventNormalFlips;
            remesher.EnableFlips        = this.EnableFlips;
            remesher.EnableSplits       = this.EnableSplits;
            remesher.EnableCollapses    = this.EnableCollapses;
            remesher.EnableSmoothing    = this.EnableSmoothing;
            remesher.SmoothSpeedT       = this.SmoothingSpeed;

            BoundedProjectionTarget target = new BoundedProjectionTarget()
            {
                Source = sourceMesh, SourceSpatial = inputSpatial,
                Target = targetMesh, TargetSpatial = targetSpatial,
                SourceToTargetXForm = source_to_target,
                TargetToSourceXForm = target_to_source,
                MaxDistance         = max_dist,
                Smoothness          = transition_smoothness
            };

            remesher.SetProjectionTarget(target);

            if (remesher.Constraints == null)
            {
                remesher.SetExternalConstraints(new MeshConstraints());
            }
            MeshConstraintUtil.FixAllBoundaryEdges(remesher.Constraints, meshROI);
            if (is_invalidated())
            {
                return(null);
            }

            remesher.Progress = new ProgressCancel(is_invalidated);
            remesher.FastestRemesh(RemeshRounds);
            if (is_invalidated())
            {
                return(null);
            }

            op.BackPropropagate();

            return(meshIn);
        }
コード例 #27
0
        protected virtual DMesh3 compute_sharp_edge_flow()
        {
            DMesh3   sourceMesh   = MeshSource.GetDMeshUnsafe();
            ISpatial inputSpatial = MeshSource.GetSpatial();

            DMesh3   targetMesh    = TargetSource.GetDMeshUnsafe();
            ISpatial targetSpatial = TargetSource.GetSpatial();

            DMesh3 meshIn = new DMesh3(sourceMesh);

            if (is_invalidated())
            {
                return(null);
            }

            RemesherPro remesher = new RemesherPro(meshIn);

            remesher.SetTargetEdgeLength(TargetEdgeLength);
            remesher.PreventNormalFlips = this.PreventNormalFlips;
            remesher.EnableFlips        = this.EnableFlips;
            remesher.EnableSplits       = this.EnableSplits;
            remesher.EnableCollapses    = this.EnableCollapses;
            remesher.EnableSmoothing    = this.EnableSmoothing;
            remesher.SmoothSpeedT       = this.SmoothingSpeed;

            TransformedMeshProjectionTarget target =
                new TransformedMeshProjectionTarget(targetMesh, targetSpatial)
            {
                SourceToTargetXForm = source_to_target,
                TargetToSourceXForm = target_to_source
            };

            remesher.SetProjectionTarget(target);

            if (sourceMesh.CachedIsClosed == false)
            {
                if (remesher.Constraints == null)
                {
                    remesher.SetExternalConstraints(new MeshConstraints());
                }

                if (BoundaryMode == BoundaryModes.FreeBoundaries)
                {
                    MeshConstraintUtil.PreserveBoundaryLoops(remesher.Constraints, meshIn);
                }
                else if (BoundaryMode == BoundaryModes.FixedBoundaries)
                {
                    MeshConstraintUtil.FixAllBoundaryEdges(remesher.Constraints, meshIn);
                }
                else if (BoundaryMode == BoundaryModes.ConstrainedBoundaries)
                {
                    MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(remesher.Constraints, meshIn, 0);
                }
            }
            if (is_invalidated())
            {
                return(null);
            }

            remesher.Progress = new ProgressCancel(is_invalidated);
            remesher.SharpEdgeReprojectionRemesh(RemeshRounds, ProjectionRounds);

            if (is_invalidated())
            {
                return(null);
            }
            return(meshIn);
        }
コード例 #28
0
        public virtual void Update()
        {
            if (MeshSource == null)
            {
                throw new Exception("PlaneBandExpansionOp: must set valid MeshSource to compute!");
            }

            IMesh imesh = MeshSource.GetIMesh();

            if (imesh.HasVertexNormals == false)
            {
                throw new Exception("PlaneBandExpansionOp: input mesh does not have surface normals...");
            }
            if (imesh is DMesh3 == false)
            {
                throw new Exception("RegionOffsetOp: in current implementation, input mesh must be a DMesh3. Ugh.");
            }
            DMesh3 mesh = imesh as DMesh3;

            IList <int> faces = IndexSource.GetIndices();

            // [RMS] this is all f'n ugly!

            MeshVertexSelection selection = new MeshVertexSelection(mesh);

            selection.SelectTriangleVertices(faces);

            // ugly
            List <Vector2d> seeds = new List <Vector2d>();

            foreach (int vid in selection)
            {
                foreach (int nbrvid in mesh.VtxVerticesItr(vid))
                {
                    if (selection.IsSelected(nbrvid) == false)
                    {
                        seeds.Add(new Vector2d(vid, 0));
                        break;
                    }
                }
            }
            Func <int, int, float> distanceF = (a, b) => { return((float)mesh.GetVertex(a).Distance(mesh.GetVertex(b))); };
            Func <int, bool>       nodeF     = (vid) => { return(selection.IsSelected(vid)); };
            DijkstraGraphDistance  dijkstra  = new DijkstraGraphDistance(mesh.MaxVertexID, true, nodeF, distanceF, mesh.VtxVerticesItr, seeds);

            dijkstra.Compute();
            float maxDist = dijkstra.MaxDistance;


            Displacement.Clear();
            Displacement.Resize(mesh.MaxVertexID);


            // todo: can do this in parallel...
            foreach (int vid in selection)
            {
                //Vector3d v = mesh.GetVertex(vid);

                // [TODO]...
                double dist    = maxDist - dijkstra.GetDistance(vid);
                double falloff = MathUtil.WyvillFalloff(dist, maxDist * 0.0, maxDist);

                Vector3d n = mesh.GetVertexNormal(vid);
                n = n - n.Dot(normal) * normal;
                n.Normalize();

                Displacement[vid] = falloff * offset_distance * n;
            }

            // smooth it?

            result_valid = true;
        }
コード例 #29
0
        public virtual void Update()
        {
            base.begin_update();

            if (MeshSource == null)
            {
                throw new Exception("MeshVertexDisplacementOp: must set valid MeshSource to compute!");
            }
            if (DisplacementSource == null)
            {
                throw new Exception("MeshVertexDisplacementOp: must set valid DisplacementSource to compute!");
            }

            DMesh3 meshIn = MeshSource.GetDMeshUnsafe();
            IVectorDisplacement displace = DisplacementSource.GetDisplacement();

            if (displace.Count != 0 && displace.Count != meshIn.MaxVertexID)
            {
                throw new Exception("MeshVertexDisplacementOp: inconsistent counts " + displace.Count.ToString() + " != " + meshIn.MaxVertexID.ToString());
            }

            DMesh3 mesh = new DMesh3(meshIn, MeshHints.None);

            //if (!mesh.HasVertexNormals)
            //    MeshNormals.QuickCompute(mesh);
            if (displace.Count > 0)
            {
                gParallel.ForEach(mesh.VertexIndices(), (vid) => {
                    Vector3d dv = displace.GetDisplacementForIndex(vid);

                    //Vector3f n = mesh.GetVertexNormal(vid);
                    Vector3d v = mesh.GetVertex(vid);

                    v += dv;

                    mesh.SetVertex(vid, v);
                });

                if (enable_heat_map)
                {
                    // compute max displace len
                    ColorMap map = new ColorMap();
                    map.AddPoint(0, Colorf.CornflowerBlue);
                    float d = (float)HeatMapMaxDistance;
                    map.AddPoint(d, Colorf.Orange);
                    map.AddPoint(2 * d, Colorf.VideoYellow);
                    map.AddPoint(4 * d, Colorf.VideoRed);
                    map.AddPoint(-d, Colorf.VideoMagenta);

                    float max_displace = d;
                    gParallel.ForEach(mesh.VertexIndices(), (vid) => {
                        Vector3f dv = (Vector3f)displace.GetDisplacementForIndex(vid);

                        Vector3f n = mesh.GetVertexNormal(vid);
                        float sign = n.Dot(dv) > 0 ? 1 : -1;

                        Colorf c = map.Linear(dv.Length * sign);

                        Colorf existing_c   = mesh.GetVertexColor(vid);
                        float preserve__max = max_displace / 2;
                        float t             = MathUtil.Clamp(dv.Length / preserve__max, 0.0f, 1.0f);
                        c = (1.0f - t) * existing_c + (t) * c;

                        mesh.SetVertexColor(vid, c);

                        //float t = MathUtil.Clamp(dv.Length / max_displace, -1.0f, 1.0f);
                        //mesh.SetVertexColor(vid, t * Colorf.Orange);
                    });
                }
            }

            MeshNormals.QuickCompute(mesh);

            DisplacedMesh = mesh;
            base.complete_update();
        }