What is the optimal selection of mesh edges to be cut for fast fabrication and easy assembly?
This project aims to develop a program that provides an easy solution to make an object bigger than fabrication machine's print bed size, 3D printer, vinyl cutter, and laser cutter, by converting inputted 3D mesh into ready-to-print grouped 2D polygons. As a result output, the program provides an optimized 2d layout of polygons that can maximize the usage of the material for laser cutting and minimize operation time for 3D printing.
Commercial 3D printer software provides layer slicing functions that convert 3d shapes to multiple layered machine paths to print the object. The machine often allows for size re-scaling of the inputted form to adjust to the machine bed size. However, if a user wants to make a shape that has a bigger volume than the print bed size, width, length, and height, the user should do this process in other 3D softwares, such as Fusion and Rhino, to split the whole model into several parts.
Many commercial programs have existing functions for creating a mesh and unfolding or nesting 2d polygons. However, by making this from scratch, I am looking forward to learning 3D computational geometry and finding the optimal solution.
Problems to solve
Converting mesh to series of polygons
Parameters to select mesh for splitting 2D polygons
Nesting polygons in rectangles
...
Input parameters
Machine width and height
Minimum and maximum size of single piece
...
Big Question:
Assume that you are making polyhedron object with flat sheet material. Polygons can be grouped(routed), then unfolded to make a machining path. To fold gourped polygons, you must make a score line on the material using machine.
Is way of grouping and routing optimize fabrication process by reducing machining hours, manual folding and assembly hours, and material to be used ?
It is necessary to cut out some portion of flat and stiff material to fold. The below image shows sections of the folded material and cut pattern on the material before the fold.
When the desired shape has both convex and concave zones, a cutting pattern should be placed on both sides of the material. This problem could be solved by simply scoring one side of the material, then flip the sheet and score the other. However, this additional process might lead to fabrication errors or a more complex manufacturing process.
Is this problem can be solved by finding folding lines to cut, and make small pieces that only have one type of foldings?
Process | May, 2020
I created sample obj file from Rhino by drawing shpere and converted nurbs sphere into Mesh. It was possible to control number of out put faces, so I reduced number of faces into 10 to test with. All of mesh faces are set as triangle.
After exporting obj file, I tried to understand what obj file is. Wikipidea explanation helped me to understand the structure of the objfile.
# List of geometric vertices, with (x, y, z [,w]) coordinates, # w is optional and defaults to 1.0. v 0.123 0.234 0.345 1.0 # List of texture coordinates, in (u, [,v ,w]) coordinates, # these will vary between 0 and 1. v, w are optional and default to 0. vt 0.500 1 [0] # List of vertex normals in (x,y,z) form; normals might not be unit vectors. vn 0.707 0.000 0.707 # Polygonal face element f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...
Obj file in text :
# Rhino mtllib MeshSample.mtl usemtl diffuse_Black v -2.5813407897949219 -2.1889743804931641 -0.38196274638175964 v 0.65565627813339233 -2.1691322326660156 -2.2487366199493408 v 0.50404548645019531 -1.6038597822189331 0.99214035272598267 v -2.7688426971435547 0.62733733654022217 1.3206555843353271 v -3.1897687911987305 0.46314927935600281 -2.3820698261260986 v 0.60596787929534912 1.9520754814147949 0.06672561913728714 v 0.50404548645019531 -1.6038597822189331 0.99214035272598267 // == V2 v -2.7688426971435547 0.62733733654022217 1.3206555843353271 // == V3 v -0.37693735957145691 2.1796708106994629 -2.1620137691497803 v -2.7688426971435547 0.62733733654022217 1.3206555843353271 // == V3 v -3.1897687911987305 0.46314927935600281 -2.3820698261260986 // == V4 v -0.37693735957145691 2.1796708106994629 -2.1620137691497803 // == V9 v 0.65565627813339233 -2.1691322326660156 -2.2487366199493408 // == V1 vt 0.31169196963310242 0.17309394478797913 vt -0.099096514284610748 0.098736271262168884 vt 0.23367762565612793 -0.32448849081993103 vt 0.41290870308876038 0.5746234655380249 vt 0.15371593832969666 0.56317311525344849 vt 0.69271504878997803 0.76106297969818115 vt 0.63955128192901611 0.29132026433944702 vt 0.44271016120910645 1.1669238805770874 vt 0.92515802383422852 0.81010866165161133 vt 1.2472586631774902 1.3133976459503174 vt 1.3018485307693481 0.87406229972839355 vt -0.014250267297029495 0.80088096857070923 vt 0.87300461530685425 0.23866783082485199 vn -0.54257309436798096 -0.82861989736557007 0.13785308599472046 vn 0.42445772886276245 -0.69712340831756592 -0.57780152559280396 vn 0.42814129590988159 -0.8071170449256897 0.40651822090148926 vn -0.58940553665161133 0.17791260778903961 0.78800266981124878 vn -0.76695841550827026 0.12049369513988495 -0.63028252124786377 vn 0.63934534788131714 0.70599061250686646 0.30465510487556458 vn 0.55640292167663574 -0.53655987977981567 0.63444411754608154 vn -0.35942506790161133 0.65748864412307739 0.66221016645431519 vn 0.29038766026496887 0.81019431352615356 -0.50917595624923706 vn -0.51344358921051025 0.69635790586471558 0.50145930051803589 vn -0.60318517684936523 0.62943673133850098 -0.48987448215484619 vn 0.19642183184623718 0.73492246866226196 -0.6490820050239563 vn 0.64330857992172241 -0.61853975057601929 -0.45117923617362976 f 1/1/1 2/2/2 3/3/3 f 4/4/4 5/5/5 1/1/1 f 6/6/6 4/4/4 7/7/7 f 8/8/8 6/6/6 9/9/9 f 10/10/10 9/9/9 11/11/11 f 12/12/12 2/2/2 5/5/5 f 5/5/5 2/2/2 1/1/1 f 4/4/4 1/1/1 7/7/7 f 6/6/6 7/7/7 13/13/13 f 9/9/9 6/6/6 13/13/13
Convert text file into face vertex list :
The first face is made by three vertices no.1,2, and 3, and the second face is made by three vertices no.4,5,1. So, I represent each faces with nine digits on the list. Then, using some code, I made an array with all vertex coordinates corresponding to mesh faces.
var face = new Float32Array([ -2.581341,0.381963,-2.188974, // Vertex 1 XYZ 0.655656,2.248737,-2.169132, // Vertex 2 XYZ 0.504045,-0.99214,-1.60386 // Vertex 3 XYZ )]
var MeshSample_1 = new Float32Array([ -1.559738,-0.303075,-2.083298,1.677259,1.563699,-2.063456,1.525648,-1.677178,-1.498184, -1.74724,-2.005693,0.733014,-2.168166,1.697032,0.568825,-1.559738,-0.303075,-2.083298, 1.627571,-0.751763,2.057752,-1.74724,-2.005693,0.733014,1.525648,-1.677178,-1.498184, -1.74724,-2.005693,0.733014,1.627571,-0.751763,2.057752,0.644665,1.476976,2.285347, -1.74724,-2.005693,0.733014,0.644665,1.476976,2.285347,-2.168166,1.697032,0.568825, 0.644665,1.476976,2.285347,1.677259,1.563699,-2.063456,-2.168166,1.697032,0.568825, -2.168166,1.697032,0.568825,1.677259,1.563699,-2.063456,-1.559738,-0.303075,-2.083298, -1.74724,-2.005693,0.733014,-1.559738,-0.303075,-2.083298,1.525648,-1.677178,-1.498184, 1.627571,-0.751763,2.057752,1.525648,-1.677178,-1.498184,1.677259,1.563699,-2.063456, 0.644665,1.476976,2.285347,1.627571,-0.751763,2.057752,1.677259,1.563699,-2.063456 ]);
Visualization of Mesh using Javascript :
The array was used as input variable to create mesh in web environment.
vertexList = [ [-1.559738039970398, -0.30307498574256897, -2.0832979679107666], [1.6772589683532715, 1.5636990070343018, -2.0634560585021973], [1.5256479978561401, -1.6771780252456665, -1.4981839656829834], [-1.7472399473190308, -2.005692958831787, 0.7330139875411987], [-2.168165922164917, 1.6970319747924805, 0.5688250064849854], [1.6275709867477417, -0.7517629861831665, 2.0577518939971924], [0.644665002822876, 1.4769760370254517, 2.2853469848632812] ]
faceList = [ [0, 1, 2], [3, 4, 0], [5, 3, 2], [3, 5, 6], [3, 6, 4], [6, 1, 4], [4, 1, 0], [3, 0, 2], [5, 2, 1], [6, 5, 1], ]
faceCenterList = [ [0.5477229754130045, -0.13885133465131125, -1.8816459973653157], [-1.8250479698181152, -0.20391198992729187, -0.26048632462819415], [0.4686596790949504, -1.4782113234202068, 0.43086063861846924], [0.17499868075052896, -0.42682663599650067, 1.6920376221338909], [-1.0902469555536907, 0.38943835099538165, 1.1957286596298218], [0.05125268300374349, 1.5792356729507446, 0.26357197761535645], [-0.6835483312606812, 0.985885332028071, -1.1926430066426594], [-0.5937766631444296, -1.3286486566066742, -0.9494893153508505], [1.6101593176523845, -0.28841400146484375, -0.5012960433959961], [1.3164983193079631, 0.7629706859588623, 0.7598809401194254] ]
faceNormalList = [ [0.10732642824782597, -0.17570339453724929, -0.978575165711685], [-0.9835679726350891, -0.11787573564831808, -0.13674558183674032], [0.25541569741116493, -0.9374244965604681, 0.2366392502614921], [-0.28426152415731226, -0.22064112502289498, 0.9330127972500661], [-0.5220191265254702, -0.02153379510948092, 0.8526619067425072], [0.05757415980255939, 0.9977767291928138, 0.033568062266381656], [-0.39328540068367557, 0.6884366003629525, -0.6094108965958693], [-0.26675406561676607, -0.816793521426208, -0.5115570465090877], [0.9986516463062406, -0.04946506518567343, -0.015751084280541287], [0.9004346088340494, 0.3745088477650572, 0.22127050901455828] ]
faceAdjacentList = [ [6, 8, 7], [4, 6, 7], [3, 7, 8], [2, 9, 4], [3, 5, 1], [9, 6, 4], [5, 0, 1], [1, 0, 2], [2, 0, 9], [3, 8, 5] ]
faceAngleList = [ [2.0188185533233134, 1.702462942089455, 2.2337919986082024], [1.9816388231158957, 1.9703499911007138, 2.013743486100381], [1.9337285667066895, 2.1852284516704996, 1.873093235381627], [1.9337285667066895, 1.4382659488795524, 2.8198495812015745], [2.8198495812015745, 1.5478757956769436, 1.9816388231158957], [2.018554283810974, 2.2702584457312405, 1.5478757956769436], [2.2702584457312405, 2.0188185533233134, 1.9703499911007138], [2.013743486100381, 2.2337919986082024, 2.1852284516704996], [1.873093235381627, 1.702462942089455, 2.640816416182997], [1.4382659488795524, 2.640816416182997, 2.018554283810974] ]Translate, Rotate, and Translate
edgeVectorList = [ [ [0.8662572605993915, 0.49956997828012345, 0.005309920906670762], [-0.04603623354760884, -0.9840829556588391, 0.17164323925664296], [-0.9000948454319609, 0.4008649315793213, -0.17069439316134663] ], [ [-0.11284307448558513, 0.9926374005252957, -0.044016265391609834], [0.18016626900822189, -0.5922670857838293, -0.7853405723689483], [-0.05688231661820419, -0.5165219703340375, 0.8543824999485828] ], ... ... ... ]Unfolding
foldGraph = [ [0, 6, 5, 4], [0, 6, 1], [0, 8, 2, 3], [0, 8, 9], [0, 7] ]
faceTypeList = [ [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0] ]
0 : not moving,
1 : Rotate XX degree along shared edge between face 1,6
////Rotate XX degree along shared edge between face 6,0
2 : Rotate XX degree along shared edge between face 2,8
////Rotate XX degree along shared edge between face 8,0
...