// Use this for initialization void Start() { meshGO = GameObject.Find("sample_mesh"); Mesh unityMesh = meshGO.GetComponent <MeshFilter>().mesh; startMesh = g3UnityUtils.UnityMeshToDMesh(unityMesh); double height = startMesh.CachedBounds.Height; // find path to sample file if (LoadSampleMesh) { string curPath = Application.dataPath; string filePath = Path.Combine(curPath, Path.Combine("..\\sample_files", SampleFileName)); // load sample file, convert to unity coordinate system, translate and scale to origin startMesh = StandardMeshReader.ReadMesh(filePath); if (startMesh == null) { startMesh = new Sphere3Generator_NormalizedCube().Generate().MakeDMesh(); } if (FlipLeftRight) { MeshTransforms.FlipLeftRightCoordSystems(startMesh); } MeshTransforms.Scale(startMesh, height / startMesh.CachedBounds.Height); MeshTransforms.Translate(startMesh, -startMesh.CachedBounds.Center); MeshNormals.QuickCompute(startMesh); g3UnityUtils.SetGOMesh(meshGO, startMesh); } }
void apply_scene_scale(TargetObject obj, Vector3f scale) { // construct scaled scene frame and update SO Frame3f f = obj.sceneFrame; f.Origin = scale * (f.Origin - sharedOriginS) + sharedOriginS; obj.curSceneFrame = f; obj.SO.SetLocalFrame(f, CoordSpace.SceneCoords); Frame3f fL = obj.SO.GetLocalFrame(CoordSpace.ObjectCoords); // transform is to map from original obj frame into scene, scale, and then map into scaled obj frame TransformSequence seq = new TransformSequence(); seq.AppendFromFrame(obj.objFrame); seq.AppendScale(scale, sharedOriginS); seq.AppendToFrame(fL); obj.SO.EditAndUpdateMesh((mesh) => { // restore original positions mesh.VerticesBuffer.copy(obj.InputMeshV); if (obj.InputMeshN != null && mesh.HasVertexNormals) { mesh.NormalsBuffer.copy(obj.InputMeshN); } // apply xform MeshTransforms.PerVertexTransform(mesh, seq); }, GeometryEditTypes.VertexDeformation); }
private static void LoadAssetsAsMeshes(IList <Asset> assets, int trianglesLimit, double scale, Dictionary <Asset, DMesh3> destination) { if (destination == null) { return; } var meshBuilder = new DMesh3Builder() { NonManifoldTriBehavior = DMesh3Builder.AddTriangleFailBehaviors.DiscardTriangle }; var objReader = new OBJFormatReader(); var reader = new StandardMeshReader() { MeshBuilder = meshBuilder, ReadInvariantCulture = true }; //reader.AddFormatHandler(objReader); foreach (var asset in assets) { //var isMeshLoaded = objReader.ReadFile(asset.OpenAssetFile(), meshBuilder, null, new ParsingMessagesHandler((s, o) => {; })); var isMeshLoaded = reader.Read(asset.OpenAssetFile(), asset.FileFormat.ToString(), ReadOptions.Defaults); if (isMeshLoaded.code == IOCode.Ok) { var mesh = meshBuilder.Meshes.Last(); Reducer r = new Reducer(mesh) { PreserveBoundaryShape = true, }; r.ReduceToTriangleCount(trianglesLimit); MeshTransforms.Scale(mesh, scale); destination[asset] = mesh; } } }
// update visible triangles for this chunk void update_triangles(OrderedChunk chunk, float max_scalar) { if (chunk.mesh == null) { chunk.mesh = new MeshChunk(); } int count = 0; foreach (int idx in chunk.order_range) { if (tri_ordering[idx].scalar < max_scalar) { count++; } } // if we have the same count, we can keep it if (chunk.mesh.current_count == count) { chunk.mesh.submesh.SetVisible(true); return; } // find subset triangles int[] triangles = new int[count]; for (int k = 0; k < count; ++k) { int idx = chunk.order_range.a + k; triangles[k] = tri_ordering[idx].tid; } // find submesh // [TODO] faster variant of this? Also could be computing these in background... DSubmesh3 submesh = new DSubmesh3(Mesh, triangles); MeshTransforms.VertexNormalOffset(submesh.SubMesh, NormalOffsetDistance); fMesh umesh = UnityUtil.DMeshToUnityMesh(submesh.SubMesh, false); // create or update GO if (chunk.mesh.submesh == null) { chunk.mesh.submesh = new fMeshGameObject(umesh, true, false); if (ChunkMeshMaterial != null) { chunk.mesh.submesh.SetMaterial(ChunkMeshMaterial); } if (ChunkMeshParent != null) { ChunkMeshParent.AddChild(chunk.mesh.submesh, false); } } else { chunk.mesh.submesh.UpdateMesh(umesh, true, false); } chunk.mesh.submesh.SetVisible(true); chunk.mesh.current_count = count; }
internal static void test_MeshMeshCut_CutInSingleTriangle() { Console.WriteLine($"test_MeshMeshCut_CutInSingleTriangle."); var shape = test_Bool.MakeBox( center: new Vector3d(5, 5, 0), size: new Vector3d(10, 10, 2) ); var tool = test_Bool.MakeBox( center: new Vector3d(2.5, 7.5, 1), size: new Vector3d(.5, .5, .5) ); MeshTransforms.Translate(shape, new Vector3d(1, 1, 1)); MeshTransforms.Translate(tool, new Vector3d(1, 1, 1)); var error = false; DMesh3 ret; using (var c = new ConsoleColorController()) { var meshCut = new MeshMeshCut(); meshCut.Target = shape; meshCut.CutMesh = tool; meshCut.Compute(); } }
/// <summary> /// Generates a row of cylinders tessellated w/ different chord lengths /// eg 10x1cm : CalibrationModelGenerator.MakePrintStepSizeTest(10.0f, 10.0f, 0.1, 1.0, 10); /// </summary> public static DMesh3 MakePrintStepSizeTest(double cylDiam, double cylHeight, double lowStep, double highStep, int nSteps) { double spacing = 2.0f; float r = (float)cylDiam * 0.5f; double cx = 0.5 * (nSteps * cylDiam + (nSteps - 1) * spacing); DMesh3 accumMesh = new DMesh3(); double cur_x = -cx + cylDiam / 2; for (int k = 0; k < nSteps; ++k) { double t = (double)k / (double)(nSteps - 1); double chord_len = (1.0 - t) * lowStep + (t) * highStep; int slices = (int)((MathUtil.TwoPI * r) / chord_len); CappedCylinderGenerator cylgen = new CappedCylinderGenerator() { BaseRadius = r, TopRadius = r, Height = (float)cylHeight, Slices = slices, NoSharedVertices = false }; DMesh3 cylMesh = cylgen.Generate().MakeDMesh(); MeshTransforms.Translate(cylMesh, -cylMesh.CachedBounds.Min.y * Vector3d.AxisY); MeshTransforms.Translate(cylMesh, cur_x * Vector3d.AxisX); cur_x += cylDiam + spacing; MeshEditor.Append(accumMesh, cylMesh); } MeshTransforms.ConvertYUpToZUp(accumMesh); return(accumMesh); }
public SliceFeature(Mesh input) { MeshCheck meshCheck = new MeshCheck(); meshCheck.setMesh(input); DMesh3 mesh = meshCheck.ToUnityWatertightMesh().ToDMesh3(); if (!mesh.IsClosed()) { return; } // center mesh above origin AxisAlignedBox3d bounds = mesh.CachedBounds; Vector3d baseCenterPt = bounds.Center - bounds.Extents.z * Vector3d.AxisZ; MeshTransforms.Translate(mesh, -baseCenterPt); // create print mesh set meshes = new PrintMeshAssembly(); meshes.AddMesh(mesh, PrintMeshOptions.Default()); // create settings //MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2); //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus); //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2); settings = new RepRapSettings(RepRap.Models.Unknown); }
/// <summary> /// available after call to UpdateSection() /// </summary> public DMesh3 GetSectionMesh(double simplifyTol = 0.01) { DMesh3 mesh = new DMesh3(); if (localCurves.Loops == null) { return(mesh); } List <GeneralPolygon2d> solids = GetSolids(); foreach (GeneralPolygon2d poly in solids) { poly.Simplify(simplifyTol, simplifyTol / 10, true); TriangulatedPolygonGenerator gen = new TriangulatedPolygonGenerator() { Polygon = poly }; DMesh3 polyMesh = gen.Generate().MakeDMesh(); MeshTransforms.PerVertexTransform(polyMesh, (uv) => { return(frameL.FromPlaneUV((Vector2f)uv.xy, 2)); }); MeshEditor.Append(mesh, polyMesh); } if (OutputSpace != CoordSpace.ObjectCoords) { MeshTransforms.PerVertexTransform(mesh, (v) => { return(SceneTransforms.TransformTo((Vector3f)v, SO, CoordSpace.ObjectCoords, OutputSpace)); }); } return(mesh); }
public override fMesh MakeGeometry(AxisGizmoFlags widget) { switch (widget) { case AxisGizmoFlags.AxisTranslateY: if (MyAxisTranslateY == null) { Radial3DArrowGenerator arrowGen = new Radial3DArrowGenerator() { HeadLength = 2.0f, TipRadius = 0.1f, StickLength = 1.5f, Clockwise = true }; DMesh3 mesh = arrowGen.Generate().MakeDMesh(); MeshNormals.QuickCompute(mesh); MeshTransforms.Translate(mesh, 0.5 * Vector3d.AxisY); DMesh3 flip = new DMesh3(mesh); MeshTransforms.Rotate(flip, Vector3d.Zero, Quaterniond.AxisAngleD(Vector3d.AxisX, 180)); MeshEditor.Append(mesh, flip); MyAxisTranslateY = new fMesh(mesh); } return(MyAxisTranslateY); default: return(null); } }
/// <summary> /// Initialize the data model to the new-imported-scan state, with the given mesh (presumably loaded from file?) /// </summary> public static void InitializeScan(DMesh3 mesh) { AxisAlignedBox3d bounds = mesh.CachedBounds; Vector3d translate = -bounds.Center; double dy = 0.5 * bounds.Height; MeshTransforms.Translate(mesh, translate); ScanSO scanSO = new ScanSO(); scanSO.Create(mesh, OrthogenMaterials.ScanMaterial); OG.Scene.AddSceneObject(scanSO); Frame3f f = scanSO.GetLocalFrame(CoordSpace.SceneCoords); f.Translate((float)dy * Vector3f.AxisY); scanSO.SetLocalFrame(f, CoordSpace.SceneCoords); OG.Model.InitializeScan(scanSO); OG.Model.Workflow.SetInitialState(ScanState.Identifier); // reposition camera Vector3f c = scanSO.GetLocalFrame(CoordSpace.WorldCoords).Origin; //OG.Context.ActiveCamera.Animator().PanFocus(c); OG.Context.ActiveCamera.Manipulator().ScenePanFocus( OG.Context.Scene, OG.Context.ActiveCamera, c, false); // [TODO] this should happen via a transition, I think... // set up xforms/etc OG.Context.TransformManager.SetActiveGizmoType(AxisTransformGizmo.DefaultName); }
public override bool BuildOnMesh(DMesh3Builder meshBuilder) { var doorCopy = new DMesh3(Mesh, bCompact: true); if (FrontNormal == -Vector3d.AxisZ) { // trick to prevent 180 rotation FrontNormal += new Vector3d(0.0000001, 0.0, 0.0); } var meshWidth = doorCopy.GetBounds().Width; var meshHeight = doorCopy.GetBounds().Height; var widthScale = WidthLimit / meshWidth; var heightScale = HeightLimit / meshHeight; Quaterniond orientingQuaternion = new Quaterniond(Vector3d.AxisZ, FrontNormal); MeshTransforms.Rotate(doorCopy, Vector3d.Zero, orientingQuaternion); MeshTransforms.Scale(doorCopy, Math.Min(widthScale, heightScale)); MeshTransforms.Translate(doorCopy, Origin); meshBuilder.AppendNewMesh(doorCopy); meshBuilder.SetActiveMesh(0); return(true); }
fPolylineGameObject make_path <T>(LinearToolpath3 <T> path, fMaterial material, float width, Vector3d origin) where T : IToolpathVertex { Vector3d prev = Vector3d.Zero; tempPolyLine.Clear(); foreach (T vtx in path) { Vector3d v = origin + vtx.Position; v = MeshTransforms.ConvertZUpToYUp(v); v = MeshTransforms.FlipLeftRightCoordSystems(v); // [RMS] because of the sharp turns we make, unity polyline will get twisted up unless we put // in some duplicate vertices =\ if (tempPolyLine.Count > 0) { tempPolyLine.Add((Vector3f)Vector3d.Lerp(prev, v, 0.001)); tempPolyLine.Add((Vector3f)Vector3d.Lerp(prev, v, 0.998)); tempPolyLine.Add((Vector3f)Vector3d.Lerp(prev, v, 0.999)); } tempPolyLine.Add((Vector3f)v); prev = v; } fPolylineGameObject go = PolylinePool.Allocate(); go.SetMaterial(material, true); go.SetLineWidth(width); go.SetVertices(tempPolyLine.ToArray(), false, true); return(go); }
void bake_hole_mesh() { CavityPreviewSO.EditAndUpdateMesh((mesh) => { MeshTransforms.Scale(mesh, new Vector3d(HoleSize, HoleSize, (float)CurHoleDepth), Vector3d.Zero); }, GeometryEditTypes.VertexDeformation); CavityPreviewSO.SetLocalScale(Vector3f.One); }
/// <summary> /// compute offset meshes as simple extrusions /// </summary> void compute_offset_meshes_nosdf() { if (cached_inner_sdf_offset != inner_offset) { InnerOffsetMesh = new DMesh3(cachedInputMesh); MeshTransforms.FromFrame(InnerOffsetMesh, cachedInputsTransform); MeshNormals.QuickCompute(InnerOffsetMesh); MeshTransforms.VertexNormalOffset(InnerOffsetMesh, inner_offset); Reducer reducer = new Reducer(InnerOffsetMesh); reducer.ReduceToTriangleCount(5000); InnerOffsetMeshSpatial = new DMeshAABBTree3(InnerOffsetMesh, true); cached_inner_sdf_offset = inner_offset; } double max_offset = inner_offset + thickness; if (cached_outer_sdf_offset != max_offset) { OuterOffsetMesh = new DMesh3(cachedInputMesh); MeshTransforms.FromFrame(OuterOffsetMesh, cachedInputsTransform); MeshNormals.QuickCompute(OuterOffsetMesh); MeshTransforms.VertexNormalOffset(OuterOffsetMesh, max_offset); Reducer reducer = new Reducer(OuterOffsetMesh); reducer.ReduceToTriangleCount(5000); 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"); }
public static void ExportSocket() { if (OG.Model.HasSocket() == false) { return; } string filename = null; if (ShowExportDialogInEditor || FPlatform.InUnityEditor() == false) { filename = FPlatform.GetSaveFileName("Export Socket", Path.Combine(ExportSocketPath, "socket.obj"), new string[] { "*.obj" }, "Mesh Files (*.OBJ)"); } else { filename = Path.Combine(ExportSocketPath, "socket.obj"); } if (filename == null) { return; } DMesh3 SocketMesh = new DMesh3(OG.Socket.Socket.Mesh); AxisAlignedBox3d bounds = SocketMesh.CachedBounds; MeshTransforms.Translate(SocketMesh, -bounds.Min.y * Vector3d.AxisZ); MeshTransforms.FlipLeftRightCoordSystems(SocketMesh); // convert from unity coordinate system WriteOptions opt = WriteOptions.Defaults; opt.bWriteGroups = true; StandardMeshWriter.WriteMesh(filename, SocketMesh, opt); }
// parse file and create a set of MeshSO objects public bool ReadFile(string sPath) { sSourcePath = sPath; SomeMeshesTooLargeForUnityWarning = false; // read the input file DMesh3Builder build = new DMesh3Builder(); StandardMeshReader reader = new StandardMeshReader() { MeshBuilder = build }; reader.warningEvent += on_warning; ReadOptions options = new ReadOptions(); options.ReadMaterials = true; LastReadResult = reader.Read(sPath, options); if (LastReadResult.code != IOCode.Ok) { return(false); } // create the material set List <SOMaterial> vSOMaterials = new List <SOMaterial>(); for (int k = 0; k < build.Materials.Count; ++k) { SOMaterial m = build_material(sPath, build.Materials[k]); vSOMaterials.Add(m); } // convert the read meshes into unity meshes SceneObjects = new List <ImportedObject>(); for (int k = 0; k < build.Meshes.Count; ++k) { DMesh3 mesh = build.Meshes[k]; int matID = build.MaterialAssignment[k]; SOMaterial soMaterial = (matID < 0 || matID >= vSOMaterials.Count) ? null : vSOMaterials[matID]; if (SwapLeftRight) { MeshTransforms.FlipLeftRightCoordSystems(mesh); } SceneObjects.Add(new ImportedObject() { mesh = mesh, material = soMaterial }); } return(SceneObjects.Count > 0); }
void OrientationCentre(DMesh3 mesh) { double x = mesh.CachedBounds.Center.x * -1; double y = mesh.CachedBounds.Center.y * -1; double z = mesh.CachedBounds.Center.z * -1; MeshTransforms.Translate(mesh, x, y, z); }
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.CreateMesh("tool_generated", Colorf.DimGrey); } if (ErrorMaterial == null) { ErrorMaterial = SOMaterial.CreateMesh("tool_generated_error", Colorf.VideoRed); } // 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); MeshSourceOps = new List <ConstantMeshSourceOp>(); SceneMeshes = new List <DMesh3>(); foreach (var so in InputSOs) { var xform = SceneTransforms.ObjectToSceneXForm(so); DMesh3 sceneMesh = new DMesh3(so.Mesh); MeshTransforms.PerVertexTransform(sceneMesh, xform); SceneMeshes.Add(sceneMesh); MeshSourceOps.Add( new ConstantMeshSourceOp(sceneMesh, false, true)); } EditOp = edit_op_factory(MeshSourceOps.Cast <DMeshSourceOp>()); ComputeOp = new ThreadedMeshComputeOp() { MeshSource = EditOp }; PreviewSO = new DMeshSO() { EnableSpatial = EnablePreviewSpatial }; PreviewSO.Create(new DMesh3(), PreviewMaterial); Scene.AddSceneObject(PreviewSO); postprocess_target_objects(); base_initialize_parameters(); }
public override OpStatus Apply() { Target.EditAndUpdateMesh( (mesh) => { MeshTransforms.Scale(mesh, LocalScale.x, LocalScale.y, LocalScale.z); Target.SetLocalScale(Vector3f.One); }, GeometryEditTypes.VertexDeformation ); return(OpStatus.Success); }
public override OpStatus Revert() { Target.EditAndUpdateMesh( (mesh) => { MeshTransforms.Scale(mesh, 1.0 / LocalScale.x, 1.0 / LocalScale.y, 1.0 / LocalScale.z); Target.SetLocalScale(LocalScale); }, GeometryEditTypes.VertexDeformation ); return(OpStatus.Success); }
protected void generate(float fDiameter, float fHeight, float fWallThickness, float fBaseThickness) { base.reset_holes(); CappedCylinderGenerator outer_cylgen = new CappedCylinderGenerator() { BaseRadius = fDiameter / 2, TopRadius = fDiameter / 2, Height = fHeight + 10, Slices = 60, Clockwise = true }; DMesh3 outer_mesh = outer_cylgen.Generate().MakeDMesh(); float fInnerDiam = fDiameter - 2 * fWallThickness; CappedCylinderGenerator inner_cylgen = new CappedCylinderGenerator() { BaseRadius = fInnerDiam / 2, TopRadius = fInnerDiam / 2, Height = fHeight + 10, Slices = 60, Clockwise = false }; DMesh3 inner_mesh = inner_cylgen.Generate().MakeDMesh(); MeshTransforms.Translate(inner_mesh, fBaseThickness * Vector3d.AxisY); DMesh3[] meshes = new DMesh3[2] { outer_mesh, inner_mesh }; foreach (DMesh3 mesh in meshes) { Remesher r = new Remesher(mesh); r.SetTargetEdgeLength(TargetEdgeLength); r.SmoothSpeedT = 0.5f; r.SetExternalConstraints(new MeshConstraints()); MeshConstraintUtil.FixAllGroupBoundaryEdges(r.Constraints, mesh, true); r.SetProjectionTarget(MeshProjectionTarget.Auto(mesh)); for (int k = 0; k < 10; ++k) { r.BasicRemeshPass(); } } Vector3d vCutPos = new Vector3d(0, fHeight, 0); Vector3d vCutNormal = Vector3d.AxisY; foreach (DMesh3 mesh in meshes) { MeshPlaneCut cut = new MeshPlaneCut(mesh, new Vector3d(0, fHeight, 0), Vector3d.AxisY); cut.Cut(); } base.set_output_meshes(inner_mesh, outer_mesh); }
/// <summary> /// Converts g3.SimpleMesh to UnityEngine.Mesh /// </summary> /// <param name="simpleMesh">SimpleMesh</param> /// <returns>UnityEngine.Mesh</returns> public static Mesh ToMesh(this SimpleMesh simpleMesh) { Mesh unityMesh = new Mesh(); MeshTransforms.ConvertZUpToYUp(simpleMesh); Vector3[] vertices = new Vector3[simpleMesh.VertexCount]; Color[] colors = new Color[simpleMesh.VertexCount]; Vector2[] uvs = new Vector2[simpleMesh.VertexCount]; Vector3[] normals = new Vector3[simpleMesh.VertexCount]; NewVertexInfo data; for (int i = 0; i < simpleMesh.VertexCount; i++) { data = simpleMesh.GetVertexAll(i); vertices[i] = (Vector3)data.v; if (data.bHaveC) { colors[i] = (Color)data.c; } if (data.bHaveUV) { uvs[i] = (Vector2)data.uv; } if (data.bHaveN) { normals[i] = (Vector3)data.n; } } unityMesh.vertices = vertices; if (simpleMesh.HasVertexColors) { unityMesh.colors = colors; } if (simpleMesh.HasVertexUVs) { unityMesh.uv = uvs; } if (simpleMesh.HasVertexNormals) { unityMesh.normals = normals; } int[] triangles = new int[simpleMesh.TriangleCount * 3]; int j = 0; foreach (Index3i tri in simpleMesh.TrianglesItr()) { triangles[j * 3] = tri.a; triangles[j * 3 + 1] = tri.b; triangles[j * 3 + 2] = tri.c; j++; } unityMesh.triangles = triangles; return(unityMesh); }
void update_hole_mesh() { CappedCylinderGenerator cylgen = new CappedCylinderGenerator() { BaseRadius = 0.5f, TopRadius = 0.5f, Height = 1, Slices = this.subdivisions, Clockwise = true }; DMesh3 mesh = cylgen.Generate().MakeDMesh(); MeshTransforms.Rotate(mesh, Vector3d.Zero, Quaterniond.AxisAngleD(Vector3d.AxisX, 90)); CavityPreviewSO.ReplaceMesh(mesh, true); }
public static void test_AABBTree_TriTriIntr() { System.Console.WriteLine("test_AABBTree_TriTriIntr()"); Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube() { Radius = 1, EdgeVertices = 25 }; DMesh3 sphereMesh = gen.Generate().MakeDMesh(); Reducer reducer = new Reducer(sphereMesh); reducer.ReduceToTriangleCount(77); int hit_count = 0; Random r = new Random(31337); for (int iter = 0; iter < 5000; ++iter) { DMesh3 sphere1 = new DMesh3(sphereMesh), sphere2 = new DMesh3(sphereMesh); Vector3d[] pts = TestUtil.RandomPoints3(3, r, Vector3d.Zero, 10); // at 10, about half of the spheres intersect Vector3d p1 = pts[0], p2 = pts[1]; double r1 = 5, r2 = 10; double eps = (r1 + r2) * 0.5 * 0.001; MeshTransforms.Scale(sphere1, r1); MeshTransforms.Translate(sphere1, p1); MeshTransforms.Scale(sphere2, r2); MeshTransforms.Translate(sphere2, p2); DMeshAABBTree3 tree1 = new DMeshAABBTree3(sphere1, true); DMeshAABBTree3 tree2 = new DMeshAABBTree3(sphere2, true); bool spheres_intersect = p1.Distance(p2) < (r1 + r2 + 2 * eps); if (spheres_intersect && p1.Distance(p2) + Math.Min(r1, r2) < Math.Max(r1, r2) * 0.9) { spheres_intersect = false; } Index2i hitBrute = MeshQueries.FindIntersectingTriangles_LinearSearch(sphere1, sphere2); bool bHitBrute = hitBrute != Index2i.Max; if (bHitBrute) { hit_count++; } // [RMS] not reliable because of tesselation //Util.gDevAssert(bHitBrute == spheres_intersect); bool bHitTree1 = tree1.TestIntersection(tree2); bool bHitTree2 = tree2.TestIntersection(tree1); Util.gDevAssert(bHitBrute == bHitTree1 && bHitTree1 == bHitTree2); } System.Console.WriteLine(hit_count.ToString()); }
public static void test_AABBTree_TriTriDist() { System.Console.WriteLine("test_AABBTree_TriTriDist()"); Sphere3Generator_NormalizedCube gen = new Sphere3Generator_NormalizedCube() { Radius = 1, EdgeVertices = 6 }; DMesh3 sphereMesh = gen.Generate().MakeDMesh(); Reducer reducer = new Reducer(sphereMesh); reducer.ReduceToTriangleCount(77); Random r = new Random(31337); for (int iter = 0; iter < 1000; ++iter) { DMesh3 sphere1 = new DMesh3(sphereMesh), sphere2 = new DMesh3(sphereMesh); Vector3d[] pts = TestUtil.RandomPoints3(3, r, Vector3d.Zero, 100); Vector3d p1 = pts[0], p2 = pts[1]; double r1 = 5, r2 = 10; MeshTransforms.Scale(sphere1, r1); MeshTransforms.Translate(sphere1, p1); MeshTransforms.Scale(sphere2, r2); MeshTransforms.Translate(sphere2, p2); DMeshAABBTree3 tree1 = new DMeshAABBTree3(sphere1, true); DMeshAABBTree3 tree2 = new DMeshAABBTree3(sphere2, true); double sphere_dist = p1.Distance(p2) - (r1 + r2); double distBrute = double.MaxValue; Index2i nearestBrute = MeshQueries.FindNearestTriangles_LinearSearch(sphere1, sphere2, out distBrute); DistTriangle3Triangle3 qBrute = MeshQueries.TrianglesDistance(sphere1, nearestBrute.a, sphere2, nearestBrute.b); double distTree = double.MaxValue; Index2i nearestTree = tree1.FindNearestTriangles(tree2, null, out distTree); DistTriangle3Triangle3 qTree = MeshQueries.TrianglesDistance(sphere1, nearestTree.a, sphere2, nearestTree.b); double distTree2 = double.MaxValue; Index2i nearestTree2 = tree2.FindNearestTriangles(tree1, null, out distTree2); // pairs are unstable if we are on an edge if (qBrute.Triangle0BaryCoords.x < 0.99 && qBrute.Triangle0BaryCoords.y < 0.99 && qBrute.Triangle0BaryCoords.z < 0.99 && qBrute.Triangle1BaryCoords.x < 0.99 && qBrute.Triangle1BaryCoords.y < 0.99 && qBrute.Triangle1BaryCoords.z < 0.99) { Util.gDevAssert(nearestBrute.a == nearestTree.a && nearestBrute.b == nearestTree.b); Util.gDevAssert(nearestBrute.b == nearestTree2.a && nearestBrute.a == nearestTree.b); } Util.gDevAssert(Math.Abs(distBrute - distTree) < MathUtil.Epsilonf && Math.Abs(distBrute - distTree2) < MathUtil.Epsilonf); } }
void compute_slice_polylines() { // fMaterial mat1 = MaterialUtil.CreateFlatMaterialF(Colorf.Black); // fMaterial mat2 = MaterialUtil.CreateFlatMaterialF(Colorf.BlueMetal); // [TODO] do we need to hold data_lock here? seems like no since main thread is blocked, // then it would never be the case that we are setting SliceSet = null // create geometry int slice_i = 0; //SlicePolylines = new List<fPolylineGameObject>(); foreach (PlanarSlice slice in SliceSet.Slices) { //DebugUtil.Log(2, "Slice has {0} solids", slice.Solids.Count); Colorf slice_color = (slice_i % 2 == 0) ? Colorf.Black : Colorf.BlueMetal; // fMaterial slice_mat = (slice_i % 2 == 0) ? mat1 : mat2; slice_i++; foreach (GeneralPolygon2d poly in slice.Solids) { List <Vector3f> polyLine = new List <Vector3f>(); for (int pi = 0; pi <= poly.Outer.VertexCount; ++pi) { int i = pi % poly.Outer.VertexCount; Vector2d v2 = poly.Outer[i]; Vector2d n2 = poly.Outer.GetTangent(i).Perp; Vector3d v3 = new Vector3d(v2.x, v2.y, slice.Z); v3 = MeshTransforms.ConvertZUpToYUp(v3); v3 = MeshTransforms.FlipLeftRightCoordSystems(v3); Vector3d n3 = MeshTransforms.ConvertZUpToYUp(new Vector3d(n2.x, n2.y, 0)); n3 = MeshTransforms.FlipLeftRightCoordSystems(n3); n3.Normalize(); v3 += 0.1f * n3; polyLine.Add((Vector3f)v3); } // Do something with polyline.... Console.WriteLine(polyLine); ////DebugUtil.Log(2, "Polyline has {0} vertiecs", polyLine.Count); //fPolylineGameObject go = GameObjectFactory.CreatePolylineGO( // "slice_outer", polyLine, slice_color, 0.1f, LineWidthType.World); //go.SetMaterial(slice_mat, true); //CC.ActiveScene.RootGameObject.AddChild(go, false); //SlicePolylines.Add(go); } } }
static void Main(string[] args) { CappedCylinderGenerator cylgen = new CappedCylinderGenerator() { BaseRadius = 10, TopRadius = 5, Height = 20, Slices = 32 }; DMesh3 mesh = cylgen.Generate().MakeDMesh(); MeshTransforms.ConvertYUpToZUp(mesh); // g3 meshes are usually Y-up // center mesh above origin AxisAlignedBox3d bounds = mesh.CachedBounds; Vector3d baseCenterPt = bounds.Center - bounds.Extents.z * Vector3d.AxisZ; MeshTransforms.Translate(mesh, -baseCenterPt); // create print mesh set PrintMeshAssembly meshes = new PrintMeshAssembly(); meshes.AddMesh(mesh, PrintMeshOptions.Default()); // create settings //MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2); //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus); //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2); RepRapSettings settings = new RepRapSettings(RepRap.Models.Unknown); // do slicing MeshPlanarSlicer slicer = new MeshPlanarSlicer() { LayerHeightMM = settings.LayerHeightMM }; slicer.Add(meshes); PlanarSliceStack slices = slicer.Compute(); // run print generator SingleMaterialFFFPrintGenerator printGen = new SingleMaterialFFFPrintGenerator(meshes, slices, settings); if (printGen.Generate()) { // export gcode GCodeFile gcode = printGen.Result; using (StreamWriter w = new StreamWriter("c:\\demo\\cone.gcode")) { StandardGCodeWriter writer = new StandardGCodeWriter(); writer.WriteFile(gcode, w); } } }
protected override void SolveInstance(IGH_DataAccess DA) { DMesh3_goo dMsh_goo = null; Rhino.Geometry.Vector3d vec = new Rhino.Geometry.Vector3d(0, 0, 0); DA.GetData(0, ref dMsh_goo); DA.GetData(1, ref vec); DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value); MeshTransforms.Translate(dMsh_copy, vec.ToVec3d()); DA.SetData(0, dMsh_copy); }
public void Calculate(DMesh3Builder mesh) { var icp = ICP(mesh); DMesh3 source = mesh.Meshes[1]; //Func<Vector3d, Vector3d> TransformVector = (x, f) => //{ // return (Vector3d) //}; Func <Vector3d, Vector3d> TransformF = (v1) => { return(v1 += icp.Translation); }; MeshTransforms.PerVertexTransform(source, TransformF); }
public void Transform(Vector3D axis, double angle) { Vector3d _axis = new Vector3d(axis.X, axis.Y, axis.Z); Quaterniond rotation = new Quaterniond(_axis, angle); MeshTransforms.Rotate(_mesh, new Vector3d(0, 0, 0), rotation); if (_smoothMesh != null) { MeshTransforms.Rotate(_smoothMesh, new Vector3d(0, 0, 0), rotation); _displayMesh = DMeshToMeshGeometry(_smoothMesh); } else { _displayMesh = DMeshToMeshGeometry(_mesh); } }