Title: 3D foam example · kip-hart/MicroStructPy · Discussion #68 · GitHub
Open Graph Title: 3D foam example · kip-hart/MicroStructPy · Discussion #68
X Title: 3D foam example · kip-hart/MicroStructPy · Discussion #68
Description: 3D foam example
Open Graph Description: Hello, I like to build a structure very similar to the foam example shown on the documentation page (see image). How to modify the corresponding code to built this kind of structures in 3D? It woul...
X Description: Hello, I like to build a structure very similar to the foam example shown on the documentation page (see image). How to modify the corresponding code to built this kind of structures in 3D? It woul...
Opengraph URL: https://github.com/kip-hart/MicroStructPy/discussions/68
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"QAPage","mainEntity":{"@type":"Question","name":"3D foam example","text":"\u003cp dir=\"auto\"\u003eHello,\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eI like to build a structure very similar to the foam example shown on the documentation page (see image). How to modify the corresponding code to built this kind of structures in 3D? It would be also very nice to implement a feature, where one can simply put spherical particles into a matrix of another phase and translate it directly into a voxel grid/ numpy array without the voronoi step.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://user-images.githubusercontent.com/90309466/167398414-74725aa0-21ee-4b07-96a2-a093fd2595b1.png\"\u003e\u003cimg src=\"https://user-images.githubusercontent.com/90309466/167398414-74725aa0-21ee-4b07-96a2-a093fd2595b1.png\" alt=\"image\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e","upvoteCount":1,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"\u003cp dir=\"auto\"\u003eHi \u003ca class=\"user-mention notranslate\" data-hovercard-type=\"user\" data-hovercard-url=\"/users/Kresa96/hovercard\" data-octo-click=\"hovercard-link-click\" data-octo-dimensions=\"link_type:self\" href=\"https://github.com/Kresa96\"\u003e@Kresa96\u003c/a\u003e,\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou could avoid the voronoi step by creating a list of void spheres, then test whether each voxel is inside a sphere or not.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor example, the following code would create the voids:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-python notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"import microstructpy as msp\nimport numpy as np\nimport scipy.stats\n\n# Create Voids\nmaterial_1 = {\n 'name': 'Voids',\n 'material_type': 'void',\n 'fraction': 1,\n 'shape': 'sphere',\n 'size': scipy.stats.uniform(loc=0, scale=1.5)\n}\n# Create Domain\ndomain = msp.geometry.Cube(side_length=15, corner=(0, 0))\n\n# Create List of Un-Positioned Seeds\nporosity = 0.12;\nseed_volume = porosity * domain.volume\nrng_seeds = {'size': 1}\nseeds = msp.seeding.SeedList.from_info([material_1],\n seed_volume,\n rng_seeds)\n\n# Position Seeds in Domain\nseeds.position(domain)\"\u003e\u003cpre class=\"notranslate\"\u003e\u003cspan class=\"pl-k\"\u003eimport\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emicrostructpy\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eas\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emsp\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eimport\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enumpy\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eas\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eimport\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003escipy\u003c/span\u003e.\u003cspan class=\"pl-s1\"\u003estats\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# Create Voids\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003ematerial_1\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e {\n \u003cspan class=\"pl-s\"\u003e'name'\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'Voids'\u003c/span\u003e,\n \u003cspan class=\"pl-s\"\u003e'material_type'\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'void'\u003c/span\u003e,\n \u003cspan class=\"pl-s\"\u003e'fraction'\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e,\n \u003cspan class=\"pl-s\"\u003e'shape'\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'sphere'\u003c/span\u003e,\n \u003cspan class=\"pl-s\"\u003e'size'\u003c/span\u003e: \u003cspan class=\"pl-s1\"\u003escipy\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003estats\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003euniform\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eloc\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003escale\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1.5\u003c/span\u003e)\n}\n\u003cspan class=\"pl-c\"\u003e# Create Domain\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003edomain\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emsp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003egeometry\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eCube\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eside_length\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e15\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ecorner\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e))\n\n\u003cspan class=\"pl-c\"\u003e# Create List of Un-Positioned Seeds\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eporosity\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0.12\u003c/span\u003e;\n\u003cspan class=\"pl-s1\"\u003eseed_volume\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eporosity\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edomain\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003evolume\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003erng_seeds\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e {\u003cspan class=\"pl-s\"\u003e'size'\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e}\n\u003cspan class=\"pl-s1\"\u003eseeds\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emsp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eseeding\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eSeedList\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003efrom_info\u003c/span\u003e([\u003cspan class=\"pl-s1\"\u003ematerial_1\u003c/span\u003e],\n \u003cspan class=\"pl-s1\"\u003eseed_volume\u003c/span\u003e,\n \u003cspan class=\"pl-s1\"\u003erng_seeds\u003c/span\u003e)\n\n\u003cspan class=\"pl-c\"\u003e# Position Seeds in Domain\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eseeds\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eposition\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edomain\u003c/span\u003e)\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThen to determine which voxels are within a void:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-python notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# 1. Create node and element grids\nmesh_size = 1\nmins, maxs = zip(*domain.limits)\nsides = [np.arange(lb, ub, mesh_size) for lb, ub in zip(mins, maxs)]\nmgrid = np.meshgrid(*sides)\nnodes = np.array([g.flatten() for g in mgrid]).T\nnode_nums = np.arange(mgrid[0].size).reshape(mgrid[0].shape)\n\nm, n, p = node_nums.shape\nkp1 = node_nums[:(m-1), :(n-1), :(p-1)].flatten()\nkp2 = node_nums[1:m, :(n-1), :(p-1)].flatten()\nkp3 = node_nums[1:m, 1:n, :(p-1)].flatten()\nkp4 = node_nums[:(m-1), 1:n, :(p-1)].flatten()\nkp5 = node_nums[:(m-1), :(n-1), 1:p].flatten()\nkp6 = node_nums[1:m, :(n-1), 1:p].flatten()\nkp7 = node_nums[1:m, 1:n, 1:p].flatten()\nkp8 = node_nums[:(m-1), 1:n, 1:p].flatten()\nelems = np.array([kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8]).T\n\n# 2. Compute element centers\ncens = nodes[elems[:, 0]] + 0.5 * mesh_size\n\n# 3. For each seed:\ni_remain = np.arange(cens.shape[0])\nelem_regs = np.full(cens.shape[0], -1)\nelem_atts = np.full(cens.shape[0], -1)\nfor s_num, seed in enumerate(seeds):\n # A. Create a bounding box\n [s_mins, s_maxs] = zip(*seed.geometry.limits)\n\n # B. Isolate element centers with box\n s_i_remain = np.copy(i_remain)\n for i, lb in enumerate(s_mins):\n ub = s_maxs[i]\n x = cens[s_i_remain, i]\n in_range = (x \u0026gt;= lb) \u0026amp; (x \u0026lt;= ub)\n s_i_remain = s_i_remain[in_range]\n \n # C. Assign remaining centers to seed\n elem_regs[s_i_remain] = s_num\n elem_atts[s_i_remain] = s_num\n i_remain = np.setdiff1d(i_remain, s_i_remain)\n\n# 4. Remove voids\n# Remove element\nrm_mask = elem_atts == -1\nelems = elems[rm_mask]\nelem_atts = elem_atts[rm_mask]\n\n# Re-number nodes\nnodes_mask = np.isin(np.arange(nodes.shape[0]), elems)\nn_remain = np.sum(nodes_mask)\nnode_n_conv = np.arange(nodes.shape[0])\nnode_n_conv[nodes_mask] = np.arange(n_remain)\n\nnodes = nodes[nodes_mask]\nelems = node_n_conv[elems]\"\u003e\u003cpre class=\"notranslate\"\u003e\u003cspan class=\"pl-c\"\u003e# 1. Create node and element grids\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003emesh_size\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003emins\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003emaxs\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ezip\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003edomain\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003elimits\u003c/span\u003e)\n\u003cspan class=\"pl-s1\"\u003esides\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e [\u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earange\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003elb\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eub\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003emesh_size\u003c/span\u003e) \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elb\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eub\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ein\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ezip\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003emins\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003emaxs\u003c/span\u003e)]\n\u003cspan class=\"pl-s1\"\u003emgrid\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003emeshgrid\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003esides\u003c/span\u003e)\n\u003cspan class=\"pl-s1\"\u003enodes\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earray\u003c/span\u003e([\u003cspan class=\"pl-s1\"\u003eg\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e() \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eg\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ein\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emgrid\u003c/span\u003e]).\u003cspan class=\"pl-c1\"\u003eT\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earange\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003emgrid\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e].\u003cspan class=\"pl-c1\"\u003esize\u003c/span\u003e).\u003cspan class=\"pl-c1\"\u003ereshape\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003emgrid\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e].\u003cspan class=\"pl-c1\"\u003eshape\u003c/span\u003e)\n\n\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eshape\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003ekp1\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[:(\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), :(\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), :(\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e)].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003ekp2\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e, :(\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), :(\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e)].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003ekp3\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e, :(\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e)].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003ekp4\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[:(\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e, :(\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e)].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003ekp5\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[:(\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), :(\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003ekp6\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e, :(\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003ekp7\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003ekp8\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_nums\u003c/span\u003e[:(\u003cspan class=\"pl-s1\"\u003em\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e), \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e:\u003cspan class=\"pl-s1\"\u003ep\u003c/span\u003e].\u003cspan class=\"pl-c1\"\u003eflatten\u003c/span\u003e()\n\u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earray\u003c/span\u003e([\u003cspan class=\"pl-s1\"\u003ekp1\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ekp2\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ekp3\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ekp4\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ekp5\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ekp6\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ekp7\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ekp8\u003c/span\u003e]).\u003cspan class=\"pl-c1\"\u003eT\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# 2. Compute element centers\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003ecens\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enodes\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e[:, \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e]] \u003cspan class=\"pl-c1\"\u003e+\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0.5\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emesh_size\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e# 3. For each seed:\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003ei_remain\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earange\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecens\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eshape\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e])\n\u003cspan class=\"pl-s1\"\u003eelem_regs\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003efull\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecens\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eshape\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e], \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e)\n\u003cspan class=\"pl-s1\"\u003eelem_atts\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003efull\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecens\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eshape\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e], \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e)\n\u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003es_num\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eseed\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ein\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eenumerate\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eseeds\u003c/span\u003e):\n \u003cspan class=\"pl-c\"\u003e# A. Create a bounding box\u003c/span\u003e\n [\u003cspan class=\"pl-s1\"\u003es_mins\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003es_maxs\u003c/span\u003e] \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003ezip\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eseed\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003egeometry\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003elimits\u003c/span\u003e)\n\n \u003cspan class=\"pl-c\"\u003e# B. Isolate element centers with box\u003c/span\u003e\n \u003cspan class=\"pl-s1\"\u003es_i_remain\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003ecopy\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ei_remain\u003c/span\u003e)\n \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003elb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ein\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eenumerate\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003es_mins\u003c/span\u003e):\n \u003cspan class=\"pl-s1\"\u003eub\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003es_maxs\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e]\n \u003cspan class=\"pl-s1\"\u003ex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecens\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003es_i_remain\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e]\n \u003cspan class=\"pl-s1\"\u003ein_range\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003ex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003elb\u003c/span\u003e) \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003ex\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eub\u003c/span\u003e)\n \u003cspan class=\"pl-s1\"\u003es_i_remain\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003es_i_remain\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003ein_range\u003c/span\u003e]\n \n \u003cspan class=\"pl-c\"\u003e# C. Assign remaining centers to seed\u003c/span\u003e\n \u003cspan class=\"pl-s1\"\u003eelem_regs\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003es_i_remain\u003c/span\u003e] \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003es_num\u003c/span\u003e\n \u003cspan class=\"pl-s1\"\u003eelem_atts\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003es_i_remain\u003c/span\u003e] \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003es_num\u003c/span\u003e\n \u003cspan class=\"pl-s1\"\u003ei_remain\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003esetdiff1d\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ei_remain\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003es_i_remain\u003c/span\u003e)\n\n\u003cspan class=\"pl-c\"\u003e# 4. Remove voids\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e# Remove element\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003erm_mask\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eelem_atts\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e==\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003erm_mask\u003c/span\u003e]\n\u003cspan class=\"pl-s1\"\u003eelem_atts\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eelem_atts\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003erm_mask\u003c/span\u003e]\n\n\u003cspan class=\"pl-c\"\u003e# Re-number nodes\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003enodes_mask\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eisin\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earange\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enodes\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eshape\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e]), \u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e)\n\u003cspan class=\"pl-s1\"\u003en_remain\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003esum\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enodes_mask\u003c/span\u003e)\n\u003cspan class=\"pl-s1\"\u003enode_n_conv\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earange\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enodes\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eshape\u003c/span\u003e[\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e])\n\u003cspan class=\"pl-s1\"\u003enode_n_conv\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003enodes_mask\u003c/span\u003e] \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003earange\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003en_remain\u003c/span\u003e)\n\n\u003cspan class=\"pl-s1\"\u003enodes\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enodes\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003enodes_mask\u003c/span\u003e]\n\u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode_n_conv\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e]\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eYou can then use these nodes and elements to create a RasterMesh object and take advantage of its methods.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-python notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"rmesh = msp.meshing.RasterMesh(nodes, elems)\"\u003e\u003cpre class=\"notranslate\"\u003e\u003cspan class=\"pl-s1\"\u003ermesh\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emsp\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003emeshing\u003c/span\u003e.\u003cspan class=\"pl-c1\"\u003eRasterMesh\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enodes\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eelems\u003c/span\u003e)\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOne word of caution with foam meshes is that it's very easy to create disconnected regions of material. In the example you show from the documentation, there are extra steps involved to help prevent that. You may need to play around with the scripts to make it consistently generate voxel meshes without disconnected regions.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLet me know if I can support further.\u003c/p\u003e","upvoteCount":1,"url":"https://github.com/kip-hart/MicroStructPy/discussions/68#discussioncomment-2738989"}}}
| route-pattern | /_view_fragments/Voltron::DiscussionsFragmentsController/show/:user_id/:repository/:discussion_number/discussion_layout(.:format) |
| route-controller | voltron_discussions_fragments |
| route-action | discussion_layout |
| fetch-nonce | v2:13cc1d84-8a03-e97e-efc3-0c23d0fb440a |
| current-catalog-service-hash | 9f0abe34da433c9b6db74bffa2466494a717b579a96b30a5d252e5090baea7be |
| request-id | A7D0:2FE5BE:2BDC4FB:3DD9DFA:6A4B9EBF |
| html-safe-nonce | ff56427610cf7decb9cf1a3df480d292a1c934f462eb0f4ceaed1183eedcddaf |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBN0QwOjJGRTVCRToyQkRDNEZCOjNERDlERkE6NkE0QjlFQkYiLCJ2aXNpdG9yX2lkIjoiMjY4OTg2OTYzOTA5MzgyMTExOSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 8e578effafb1d9e300c1e8baf315a9f23f16673213a885314b75aff07ab00db8 |
| hovercard-subject-tag | discussion:4061317 |
| github-keyboard-shortcuts | repository,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/Voltron::DiscussionsFragmentsController/show/kip-hart/MicroStructPy/68/discussion_layout |
| twitter:image | https://opengraph.githubassets.com/3253c69c6a242efa70209323b1428cd2f15fdafbf9f5ac2b9dda1b20f3c4ccf2/kip-hart/MicroStructPy/discussions/68 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/3253c69c6a242efa70209323b1428cd2f15fdafbf9f5ac2b9dda1b20f3c4ccf2/kip-hart/MicroStructPy/discussions/68 |
| og:image:alt | Hello, I like to build a structure very similar to the foam example shown on the documentation page (see image). How to modify the corresponding code to built this kind of structures in 3D? It woul... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | a7e470aeb8fedd833ae331b0a162f6c5a72c09b899dd94a7cd531e5e0e3a93d5 |
| turbo-cache-control | no-preview |
| go-import | github.com/kip-hart/MicroStructPy git https://github.com/kip-hart/MicroStructPy.git |
| octolytics-dimension-user_id | 41959581 |
| octolytics-dimension-user_login | kip-hart |
| octolytics-dimension-repository_id | 206468500 |
| octolytics-dimension-repository_nwo | kip-hart/MicroStructPy |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 206468500 |
| octolytics-dimension-repository_network_root_nwo | kip-hart/MicroStructPy |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 59ad79fae8b165db9a62b2142d969fa7b21eedcf |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width