コード例 #1
0
        public static AxisAlignedBox3d BoundsT(IMesh mesh, int [] triangleIndices, Func <Vector3D, Vector3D> TransformF = null)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (int tid in triangleIndices)
                {
                    Index3i tri = mesh.GetTriangle(tid);
                    for (int j = 0; j < 3; ++j)
                    {
                        bounds.Contain(mesh.GetVertex(tri[j]));
                    }
                }
            }
            else
            {
                foreach (int tid in triangleIndices)
                {
                    Index3i tri = mesh.GetTriangle(tid);
                    for (int j = 0; j < 3; ++j)
                    {
                        bounds.Contain(TransformF(mesh.GetVertex(tri[j])));
                    }
                }
            }
            return(bounds);
        }
コード例 #2
0
        public static void Center(FScene scene, IEnumerable <DMeshSO> objects, bool bInteractive)
        {
            AxisAlignedBox3d all_bounds = AxisAlignedBox3d.Empty;

            foreach (var so in objects)
            {
                TransformSequence seq    = SceneTransforms.ObjectToSceneXForm(so);
                AxisAlignedBox3d  bounds = BoundsUtil.Bounds(so.Mesh.Vertices(), seq);
                all_bounds.Contain(bounds);
            }
            Vector3f c = (Vector3f)all_bounds.Center;

            c.y = 0;

            foreach (var so in objects)
            {
                Frame3f curFrameS = so.GetLocalFrame(CoordSpace.SceneCoords);
                Frame3f newFrameS = curFrameS;
                newFrameS.Origin = curFrameS.Origin - c;
                TransformSOChange change = new TransformSOChange(so, curFrameS, newFrameS, CoordSpace.SceneCoords);
                scene.History.PushChange(change, false);
            }
            if (bInteractive)
            {
                scene.History.PushInteractionCheckpoint();
            }
        }
コード例 #3
0
ファイル: PurgeSpiralTool.cs プロジェクト: tomleetv/Cotangent
        public virtual void Setup()
        {
            // push history stream, so that we can do undo/redo internal to tool,
            // that will not end up in external history
            push_history_stream();

            if (OnApplyF == null)
            {
                OnApplyF = this.add_so_to_scene;
            }

            if (PreviewMaterial == null)
            {
                PreviewMaterial = SOMaterial.CreateFlatShaded("tool_generated", Colorf.DimGrey);
            }

            // clear selection here
            inputSelection = new List <SceneObject>(Scene.Selected);
            set_allow_selection_changes(true);
            Scene.ClearSelection();
            set_allow_selection_changes(false);

            scene_bounds = AxisAlignedBox3d.Empty;
            foreach (var so in CC.Objects.PrintMeshes)
            {
                if (so.Settings.ObjectType == PrintMeshSettings.ObjectTypes.Solid ||
                    so.Settings.ObjectType == PrintMeshSettings.ObjectTypes.Support)
                {
                    var seq = SceneTransforms.ObjectToSceneXForm(so);
                    foreach (Vector3d p in so.Mesh.Vertices())
                    {
                        Vector3d ps = seq.TransformP(p);
                        if (ps.y >= 0)
                        {
                            scene_bounds.Contain(ps);
                        }
                    }
                }
            }
            scene_bounds.Min.y = 0;
            if (scene_bounds.Width <= 0)
            {
                scene_bounds.Min.x = scene_bounds.Max.x = 0;
            }
            if (scene_bounds.Depth <= 0)
            {
                scene_bounds.Min.z = scene_bounds.Max.z = 0;
            }
            Height = scene_bounds.Height;

            PreviewSO = new DMeshSO();
            PreviewSO.Create(new DMesh3(), PreviewMaterial);
            Scene.AddSceneObject(PreviewSO);
            PreviewSO.Name = "Purge Spiral";

            initialize_parameters();
        }
コード例 #4
0
ファイル: SetDimensionsTool.cs プロジェクト: tomleetv/gsTools
        public virtual void Setup()
        {
            // push history stream, so that we can do undo/redo internal to tool,
            // that will not end up in external history
            push_history_stream();

            // clear selection here so that multi-select GroupSO goes away, otherwise
            // when we copy frmaes below, they are relative to that GroupSO, and things move
            inputSelection = new List <SceneObject>(Scene.Selected);
            set_allow_selection_changes(true);
            Scene.ClearSelection();
            set_allow_selection_changes(false);

            objects = new List <TargetObject>();
            foreach (var so in InputSOs)
            {
                TargetObject o = new TargetObject();

                o.SO         = so;
                o.InputMeshV = new DVector <double>(o.SO.Mesh.VerticesBuffer);
                if (o.SO.Mesh.HasVertexNormals)
                {
                    o.InputMeshN = new DVector <float>(o.SO.Mesh.NormalsBuffer);
                }
                o.objFrame            = so.GetLocalFrame(CoordSpace.ObjectCoords);
                o.sceneFrame          = so.GetLocalFrame(CoordSpace.SceneCoords);
                o.sceneToObjUnitScale = SceneTransforms.SceneToObject(o.SO, 1.0f);

                o.localScale  = so.GetLocalScale();
                o.localBounds = so.GetLocalBoundingBox();
                Box3f sb = so.GetBoundingBox(CoordSpace.SceneCoords);
                o.sceneBounds = sb.ToAABB();

                o.curLocalScale = o.localScale;
                o.curSceneFrame = o.sceneFrame;

                objects.Add(o);
            }

            if (false && objects.Count == 1)
            {
                originalDims = objects[0].localBounds;
            }
            else
            {
                originalDims = objects[0].sceneBounds;
                for (int k = 1; k < objects.Count; ++k)
                {
                    originalDims.Contain(objects[k].sceneBounds);
                }
            }
            currentDims   = originalDims;
            sharedOriginS = (Vector3f)originalDims.Point(0, -1, 0);

            initialize_parameters();
        }
コード例 #5
0
        public AxisAlignedBox3d GetBounds()
        {
            AxisAlignedBox3d box = AxisAlignedBox3d.Empty;

            for (int i = 0; i < Vertices.Length; ++i)
            {
                box.Contain(Mesh.GetVertex(Vertices[i]));
            }
            return(box);
        }
コード例 #6
0
        public static AxisAlignedBox3d Bounds(IMesh mesh, Func <Vector3D, Vector3D> TransformF)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (int vID in mesh.VertexIndices())
                {
                    bounds.Contain(mesh.GetVertex(vID));
                }
            }
            else
            {
                foreach (int vID in mesh.VertexIndices())
                {
                    Vector3D vT = TransformF(mesh.GetVertex(vID));
                    bounds.Contain(vT);
                }
            }
            return(bounds);
        }
コード例 #7
0
        public AxisAlignedBox3d GetBoundingBox()
        {
            // [RMS] problem w/ readonly because vector is a class...
            //AxisAlignedBox3d box = AxisAlignedBox3d.Empty;
            AxisAlignedBox3d box = new AxisAlignedBox3d(false);

            foreach (Vector3D v in vertices)
            {
                box.Contain(v);
            }
            return(box);
        }
コード例 #8
0
        public static AxisAlignedBox3d Bounds(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, Func <Vector3D, Vector3D> TransformF)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            if (TransformF == null)
            {
                foreach (Vector3D v in mesh.Vertices())
                {
                    bounds.Contain(v);
                }
            }
            else
            {
                foreach (Vector3D v in mesh.Vertices())
                {
                    Vector3D vT = TransformF(v);
                    bounds.Contain(vT);
                }
            }
            return(bounds);
        }
コード例 #9
0
        public AxisAlignedBox3d GetBounds()
        {
            if (vertices.Count == 0)
            {
                return(AxisAlignedBox3d.Empty);
            }
            AxisAlignedBox3d box = new AxisAlignedBox3d(vertices[0]);

            for (int i = 1; i < vertices.Count; ++i)
            {
                box.Contain(vertices[i]);
            }
            return(box);
        }
コード例 #10
0
        public override void postprocess_target_objects()
        {
            AxisAlignedBox3d bounds = SceneMeshes[0].CachedBounds;

            for (int k = 1; k < InputSOs.Count; ++k)
            {
                bounds.Contain(SceneMeshes[k].CachedBounds);
            }
            MaxDimension = bounds.MaxDim;

            double cell_size = ToolDefaults.DefaultVoxelSceneSizeF(new AxisAlignedBox3d(MaxDimension, MaxDimension, MaxDimension));;

            set_grid_cell_size(cell_size);
            set_mesh_cell_size(cell_size);
            set_min_comp_size(2.0);
        }
コード例 #11
0
        public virtual void Update()
        {
            base.begin_update();
            int start_timestamp = this.CurrentInputTimestamp;

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

            try {
                ResultMesh = null;

                if (source_edge_stats == null)
                {
                    source_edge_stats = new List <Vector3d>();
                    source_bounds     = AxisAlignedBox3d.Empty;
                    foreach (DMeshSourceOp op in mesh_sources)
                    {
                        Vector3d einfo = new Vector3d();
                        MeshQueries.EdgeLengthStats(op.GetDMeshUnsafe(), out einfo.x, out einfo.y, out einfo.z);
                        source_edge_stats.Add(einfo);
                        source_bounds.Contain(op.GetDMeshUnsafe().CachedBounds);
                    }
                }

                //ResultMesh = compute_blend();
                //ResultMesh = compute_blend_bounded();
                ResultMesh = compute_blend_analytic();

                if (ResultMesh.TriangleCount == 0)
                {
                    ResultMesh = base.make_failure_output(null);
                }

                base.complete_update();
            } catch (Exception e) {
                PostOnOperatorException(e);
                ResultMesh = base.make_failure_output(mesh_sources[0].GetDMeshUnsafe());
                base.complete_update();
            }
        }
コード例 #12
0
ファイル: Actions_View.cs プロジェクト: tomleetv/Cotangent
        public static void FitCurrentSelectionToView()
        {
            AxisAlignedBox3d fitBox = AxisAlignedBox3d.Zero;

            if (CC.ActiveScene.Selected.Count == 0)
            {
                fitBox = CC.Objects.GetPrintMeshesBounds(false);
            }
            else
            {
                fitBox = AxisAlignedBox3d.Empty;
                foreach (var so in CC.ActiveScene.Selected)
                {
                    fitBox.Contain(so.GetBoundingBox(CoordSpace.SceneCoords).ToAABB());
                }
            }

            double height = 3 * fitBox.Height;

            if (height < 10.0f)
            {
                height = 10.0f;
            }
            double   width  = 1.5 * Math.Sqrt(fitBox.Width * fitBox.Width + fitBox.Depth * fitBox.Depth);
            Vector3d center = fitBox.Center;

            if (width > height)
            {
                CC.ActiveScene.ActiveCamera.Animator().AnimateFitWidthToView((Vector3f)center, (float)width, CoordSpace.SceneCoords, 0.5f);
            }
            else
            {
                CC.ActiveScene.ActiveCamera.Animator().AnimateFitHeightToView((Vector3f)center, (float)height, CoordSpace.SceneCoords, 0.5f);
            }

            UpdateViewClippingBounds();
        }
コード例 #13
0
        protected void set_output_meshes(DMesh3 inner, DMesh3 outer)
        {
            InnerMesh = inner;
            OuterMesh = outer;

            AxisAlignedBox3d bounds = OuterMesh.CachedBounds;

            if (InnerMesh != null)
            {
                bounds.Contain(InnerMesh.CachedBounds);
            }

            // position center-top at origin
            Vector3d top = bounds.Center + bounds.Extents[1] * Vector3d.AxisY;

            if (InnerMesh != null)
            {
                MeshTransforms.Translate(InnerMesh, -top);
            }
            MeshTransforms.Translate(OuterMesh, -top);

            CombinedBounds = OuterMesh.CachedBounds;
            if (InnerMesh != null)
            {
                CombinedBounds.Contain(InnerMesh.CachedBounds);
            }

            if (InnerMesh != null)
            {
                var innerLoops = new MeshBoundaryLoops(InnerMesh);
                InnerLoop = innerLoops[0];
            }
            var outerLoops = new MeshBoundaryLoops(OuterMesh);

            OuterLoop = outerLoops[0];
        }
コード例 #14
0
ファイル: MeshImporter.cs プロジェクト: tomleetv/Cotangent
        async Task complete_import(string sFilename, DMesh3Builder builder, Action <string> onCompletedF)
        {
            AxisAlignedBox3d bounds = AxisAlignedBox3d.Empty;

            foreach (DMesh3 mesh in builder.Meshes)
            {
                bounds.Contain(mesh.CachedBounds);
            }
            Vector3d centerPt = bounds.Center;
            Vector3d basePt   = centerPt - bounds.Height * 0.5f * Vector3d.AxisY;

            Vector3d vTranslate = basePt;
            await Task.Run(() => {
                foreach (DMesh3 mesh in builder.Meshes)
                {
                    MeshTransforms.Translate(mesh, -vTranslate);
                }
            });

            bool     bFirst        = (CC.Objects.PrintMeshes.Count == 0);
            Vector3d postTranslate = Vector3d.Zero;

            switch (CCPreferences.ImportTransformMode)
            {
            case CCPreferences.ImportTransformModes.AutoCenterAll:
                break;

            case CCPreferences.ImportTransformModes.AutoCenterFirst:
                if (bFirst)
                {
                    CCState.SceneImportTransform = vTranslate;
                }
                postTranslate = vTranslate - CCState.SceneImportTransform;
                break;

            case CCPreferences.ImportTransformModes.NoAutoCenter:
                postTranslate = vTranslate;
                break;
            }

            // compact input meshes
            await Task.Run(() => {
                gParallel.ForEach(builder.Meshes, (mesh) => {
                    MeshEditor.RemoveUnusedVertices(mesh);
                });
                gParallel.ForEach(Interval1i.Range(builder.Meshes.Count), (k) => {
                    if (builder.Meshes[k].IsCompact == false)
                    {
                        builder.Meshes[k] = new DMesh3(builder.Meshes[k], true);
                    }
                });
            });

            string sBaseName = Path.GetFileNameWithoutExtension(sFilename);

            foreach (DMesh3 mesh in builder.Meshes)
            {
                PrintMeshSO meshSO = new PrintMeshSO();
                meshSO.Create(mesh, CCMaterials.PrintMeshMaterial);
                meshSO.UpDirection = UpDirection.ZUp;

                Frame3f f = meshSO.GetLocalFrame(CoordSpace.ObjectCoords);
                f.Origin = f.Origin + (Vector3f)postTranslate;
                meshSO.SetLocalFrame(f, CoordSpace.ObjectCoords);

                // if only one mesh, we can keep a reference
                if (builder.Meshes.Count == 1)
                {
                    meshSO.SourceFilePath        = sFilename;
                    meshSO.LastReadFileTimestamp = File.GetLastWriteTime(SourceFilePath).Ticks;
                }

                meshSO.Name = UniqueNames.GetNext(sBaseName);

                CCActions.AddNewPrintMesh(meshSO);
            }

            if (onCompletedF != null)
            {
                onCompletedF(sFilename);
            }
        }
コード例 #15
0
 protected void add_to_bounds(Vector3f v)
 {
     localBounds.Contain(v);
 }
コード例 #16
0
ファイル: MeshImporter.cs プロジェクト: tomleetv/Cotangent
        public async Task ImportInteractive(string sFilename, Action <string> onCompletedF)
        {
            SourceFilePath = sFilename;

            DMesh3Builder      builder = new DMesh3Builder();
            StandardMeshReader reader  = new StandardMeshReader()
            {
                MeshBuilder = builder
            };

            await Task.Run(() => {
                IOReadResult result = reader.Read(SourceFilePath, ReadOptions.Defaults);
                if (result.code != IOCode.Ok)
                {
                    ErrorMessage = "MeshImporter.Import: failed with message " + result.message;
                    return;
                }
            });

            if (builder.Meshes.Count == 0)
            {
                ErrorMessage = "MeshImporter.Import: no meshes in file!";
                return;
            }

            await Task.Run(() => {
                // apply unity xforms
                foreach (DMesh3 mesh in builder.Meshes)
                {
                    MeshTransforms.ConvertZUpToYUp(mesh);
                    MeshTransforms.FlipLeftRightCoordSystems(mesh);
                }

                TriCount = 0;
                Bounds   = AxisAlignedBox3d.Empty;
                foreach (var m in builder.Meshes)
                {
                    TriCount += m.TriangleCount;
                    Bounds.Contain(m.CachedBounds);
                }
            });

            bool   bSmall    = (Bounds.MaxDim < HeightMinThreshold);
            bool   bTall     = (Bounds.Height > CC.Settings.BedSizeYMM);
            double maxXZ     = Math.Max(Bounds.Width, Bounds.Depth);
            double bedMin    = Math.Min(CC.Settings.BedSizeXMM, CC.Settings.BedSizeZMM);
            bool   bLarge    = (Bounds.Width > 2 * CC.Settings.BedSizeXMM) || (maxXZ > 2 * bedMin);
            bool   bTriCount = (TriCount > TriCountThreshold);

            switch (CCPreferences.ImportAssistantMode)
            {
            case CCPreferences.ImportAssistantModes.PhysicalSizeOnly:
                bTriCount = false; break;

            case CCPreferences.ImportAssistantModes.MeshSizeOnly:
                bLarge = bSmall = bTall = false; break;

            case CCPreferences.ImportAssistantModes.Disabled:
                bLarge = bSmall = bTall = bTriCount = false; break;
            }

            if (bTriCount || bSmall || bLarge)
            {
                ImportMeshDialog.Show(CotangentUI.MainUICanvas,
                                      bSmall, bTall, bLarge, Bounds.Height,
                                      bTriCount, TriCount,
                                      async(scale, tricount) => { await process_and_complete_import(SourceFilePath, builder, scale, tricount, onCompletedF); },
                                      async() => { await complete_import(SourceFilePath, builder, onCompletedF); }
                                      );
            }
            else
            {
                await complete_import(SourceFilePath, builder, onCompletedF);
            }
        }
コード例 #17
0
        // [RMS] this only tests some basic cases...
        public static void test_RayBoxIntersect()
        {
            Random rand = new Random(316136327);

            // check that box hit works
            for (int ii = 0; ii < 1000; ++ii)
            {
                // generate random triangle
                Triangle3d       t      = new Triangle3d(rand.PointInRange(10), rand.PointInRange(10), rand.PointInRange(10));
                AxisAlignedBox3d bounds = new AxisAlignedBox3d(t.V0);
                bounds.Contain(t.V1);
                bounds.Contain(t.V2);
                Vector3d c = (t.V0 + t.V1 + t.V2) / 3.0;
                for (int jj = 0; jj < 1000; ++jj)
                {
                    Vector3d d   = rand.Direction();
                    Ray3d    ray = new Ray3d(c - 100 * d, d);
                    IntrRay3AxisAlignedBox3 bhit = new IntrRay3AxisAlignedBox3(ray, bounds);
                    Debug.Assert(bhit.Find());
                    IntrRay3Triangle3 thit = new IntrRay3Triangle3(ray, t);
                    Debug.Assert(thit.Find());
                    Debug.Assert(bhit.RayParam0 < thit.RayParameter);
                }
            }

            int N = 100;

            for (int ii = 0; ii < N; ++ii)
            {
                // generate random boxes
                Vector3d         c     = rand.PointInRange(10);
                Vector3d         e     = rand.PositivePoint();
                AxisAlignedBox3d aabox = new AxisAlignedBox3d(c - e, c + e);
                Box3d            obox  = new Box3d(c, Vector3d.AxisX, Vector3d.AxisY, Vector3d.AxisZ, e);
                double           r     = aabox.DiagonalLength;

                // center-out tests
                for (int jj = 0; jj < N; ++jj)
                {
                    Ray3d ray = new Ray3d(c, rand.Direction());
                    assert_same_hit(aabox, obox, ray, true);
                }

                // outside-in tests
                for (int jj = 0; jj < N; ++jj)
                {
                    Vector3d p   = c + 2 * r * rand.Direction();
                    Ray3d    ray = new Ray3d(p, (c - p).Normalized);
                    assert_same_hit(aabox, obox, ray, true);
                }
            }



            // random rays
            int hits   = 0;
            int InnerN = 1000;

            for (int ii = 0; ii < N; ++ii)
            {
                // generate random boxe
                Vector3d c = rand.PointInRange(10);
                Vector3d e = rand.PositivePoint();

                // every tenth box, set an axis to degenerate
                if (ii % 10 == 0)
                {
                    e[rand.Next() % 3] = 0;
                }


                AxisAlignedBox3d aabox = new AxisAlignedBox3d(c - e, c + e);
                Box3d            obox  = new Box3d(c, Vector3d.AxisX, Vector3d.AxisY, Vector3d.AxisZ, e);
                double           r     = aabox.DiagonalLength;


                TrivialBox3Generator boxgen = new TrivialBox3Generator()
                {
                    Box = obox
                };
                boxgen.Generate();
                DMesh3 mesh = new DMesh3();
                boxgen.MakeMesh(mesh);

                for (int i = 0; i < InnerN; ++i)
                {
                    Vector3d target = c + rand.PointInRange(r);
                    Vector3d o      = c + rand.PointInRange(10 * r);
                    Ray3d    ray    = new Ray3d(o, (target - o).Normalized);
                    assert_same_hit(aabox, obox, ray, false);

                    int  hitT     = MeshQueries.FindHitTriangle_LinearSearch(mesh, ray);
                    bool bMeshHit = (hitT != DMesh3.InvalidID);
                    if (bMeshHit)
                    {
                        ++hits;
                    }
                    IntrRay3AxisAlignedBox3 aabbhit = new IntrRay3AxisAlignedBox3(ray, aabox);
                    Debug.Assert(aabbhit.Find() == bMeshHit);
                    Debug.Assert(aabbhit.Test() == bMeshHit);
                }
            }

            System.Console.WriteLine("hit {0} of {1} rays", hits, N * InnerN);
        }