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); }
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(); } }
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(); }
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(); }
public AxisAlignedBox3d GetBounds() { AxisAlignedBox3d box = AxisAlignedBox3d.Empty; for (int i = 0; i < Vertices.Length; ++i) { box.Contain(Mesh.GetVertex(Vertices[i])); } return(box); }
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); }
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); }
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); }
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); }
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); }
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(); } }
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(); }
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]; }
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); } }
protected void add_to_bounds(Vector3f v) { localBounds.Contain(v); }
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); } }
// [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); }