diff options
author | kintel <kintel> | 2009-05-09 00:23:41 +0000 |
---|---|---|
committer | kintel <kintel@cb376a5e-1013-0410-a455-b6b1f9ac8223> | 2009-05-09 00:23:41 +0000 |
commit | 1cd2aa3d46088854072ce9fc1511891e4110c2d3 (patch) | |
tree | 338f64aaa0ee72ea12be42824534b214c9fd9dd8 | |
parent | 9bff0b5aade38871e31bcd3ee82d690f0c728f2f (diff) | |
download | reprap-1cd2aa3d46088854072ce9fc1511891e4110c2d3.tar.gz reprap-1cd2aa3d46088854072ce9fc1511891e4110c2d3.zip |
DXF importer - temporary living here
git-svn-id: https://reprap.svn.sourceforge.net/svnroot/reprap@2905 cb376a5e-1013-0410-a455-b6b1f9ac8223
-rw-r--r-- | trunk/users/metalab/misc/DXFImporter.java | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/trunk/users/metalab/misc/DXFImporter.java b/trunk/users/metalab/misc/DXFImporter.java new file mode 100644 index 00000000..9e1b1726 --- /dev/null +++ b/trunk/users/metalab/misc/DXFImporter.java @@ -0,0 +1,379 @@ +/* + * Import geometry information from a .DXF file + */ + +package klynn.aoi.translators; + +import klynn.aoi.util.*; + +import artofillusion.*; +import artofillusion.object.*; +import artofillusion.animation.*; +import artofillusion.math.*; + +import java.awt.*; +import java.io.*; +import java.util.*; + +import com.ysystems.ycad.lib.ydxf.*; +import com.ysystems.ycad.lib.yxxf.*; + +/** + * @see artofillusion.translators.DXFImporter + * @author klynn + */ +public class DXFImporter { + + /** + * AOI Scene into which we import + */ + private static Scene theScene = null; + private static boolean appendFlag = false; + private static boolean debug = true; + + Frame parent; + Boolean enableMeshRepair; + Vector<int[]> faces; + Vector<Vec3> vertices; + Vector<Vec3[]> polylines; + + public DXFImporter(Frame parent, Boolean enableMeshRepair) { + this.parent = parent; + this.enableMeshRepair = enableMeshRepair; + this.faces = new Vector<int[]>(); + this.vertices = new Vector<Vec3>(); + this.polylines = new Vector<Vec3[]>(); + } + + /** + * fetch DXF + * + * @param parent + * Frame Parent GUI frame + * @param inScene + * Scene Scene to append to + */ + public static void importFile(Frame parent) { + // input file setup: + FileDialog fd = new FileDialog(parent, "Import DXF File", FileDialog.LOAD); + File f; + if (ModellingApp.currentDirectory != null) fd.setDirectory(ModellingApp.currentDirectory); + fd.show(); + if (fd.getFile() == null) return; + f = new File(fd.getDirectory(), fd.getFile()); + ModellingApp.currentDirectory = fd.getDirectory(); + String objName = fd.getFile(); + if (objName.lastIndexOf('.') > 0) objName = objName.substring(0, objName.lastIndexOf('.')); + if (debug) System.out.println("Object name: " + objName); + + // ask user to enable/disable mesh repair tools: + String msgText = "WARNING: This option can be extremely slow!"; + AWTMessageDialog dialog = new AWTMessageDialog(parent, msgText, new String[] { + " Mesh Repair ON ", " Mesh Repair OFF ", " Cancel " }); + int choice = dialog.getChoice(); + boolean enableMeshRepair = false; + if (choice == 0) enableMeshRepair = true; + if (choice == 2) return; + dialog.dispose(); + + ProgressDialog pdialog = null; + /* + * KEVIN threading is backwards! This won't work pdialog = new + * ProgressDialog(parent, 100, "Importing..."); + * pdialog.setPriority(Thread.MAX_PRIORITY); pdialog.start(); + */ + + // create an AOI Scene to add objects to: + if (theScene == null) { + theScene = new Scene(); + CoordinateSystem coords = new CoordinateSystem( + new Vec3(0.0, 0.0, ModellingApp.DIST_TO_SCREEN), new Vec3(0.0, 0.0, -1.0), Vec3.vy()); + ObjectInfo info = new ObjectInfo(new SceneCamera(), coords, "Camera 1"); + info.addTrack(new PositionTrack(info), 0); + info.addTrack(new RotationTrack(info), 1); + theScene.addObject(info, null); + info = new ObjectInfo(new DirectionalLight(new RGBColor(1.0f, 1.0f, 1.0f), 0.8f), coords + .duplicate(), "Light 1"); + info.addTrack(new PositionTrack(info), 0); + info.addTrack(new RotationTrack(info), 1); + theScene.addObject(info, null); + } + + // open file: + BufferedInputStream in = null; + String line = null; + String formName = null; + try { + // read file using ycad lib: + in = new BufferedInputStream(new FileInputStream(f)); + java.util.Vector faces = new java.util.Vector(); + Yxxf drawing = new Yxxf(); + YdxfGetBuffer buffer = new YdxfGetBuffer(); + int type = YdxfGetBuffer.GET_TYPE_MAIN; // drawing (versus font) get this + // from file somehow? + buffer.setInput(type, in, drawing); + YdxfGet.get(buffer); + drawing = buffer.getDrawing(); + String blockName = drawing.secEntities.insMSpace.block.getBlockname2(); + if (debug) System.out.println("blockName: [" + blockName + "]"); + + DXFImporter importer = new DXFImporter(parent, enableMeshRepair); + for (int nextToDraw = 0;;) { + YxxfEnt ent = (YxxfEnt) drawing.secEntities.insMSpace.block.nextEntity(nextToDraw); + if (ent == null) break; + importer.addEntity(ent); + nextToDraw++; + } + + TriangleMesh mesh = importer.createMesh(objName); + Boolean curvesfound = importer.createCurve(objName); + if (mesh == null && !curvesfound) { + new AWTMessageDialog(parent, new String[] { "Import of file: [" + f + + "] failed. No supported geometry found." }); + } + + } catch (Exception ex) { + new AWTMessageDialog(parent, new String[] { + "Import of file: [" + f + "] failed with exception:", ex.getMessage() }); + return; + } finally { + try { + in.close(); + } catch (Exception ex2) { + new AWTMessageDialog(parent, new String[] { "Unable to close file: [" + f + "]. ", + ex2.getMessage() }); + } + } + if (!appendFlag) ModellingApp.newWindow(theScene); + return; + } + + private Boolean createCurve(String objName) { + for (int i=0;i<this.polylines.size();i++) { + Vec3[] verts = this.polylines.get(i); + float smoothness[] = new float[verts.length]; + Arrays.fill(smoothness, 0.0f); + Curve curve = new Curve(verts, smoothness, Mesh.NO_SMOOTHING, false); + ObjectInfo info = new ObjectInfo(curve, new CoordinateSystem(), objName + "_curve" + i); + info.setTexture(theScene.getDefaultTexture(), theScene.getDefaultTexture().getDefaultMapping(curve)); + info.addTrack(new PositionTrack(info), 0); + info.addTrack(new RotationTrack(info), 1); + theScene.addObject(info, null); + } + if (this.polylines.size() > 0) return true; + else return false; + } + + private TriangleMesh createMesh(String objName) { + int numVerts = this.vertices.size(); + if (numVerts == 0) return null; + // construct AOI scene: + double min[] = new double[] { Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE }; + double max[] = new double[] { -Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE }; + + // vertices: + Vec3 vert[] = new Vec3[numVerts], center = new Vec3(); + for (int i = 0; i < numVerts; i++) { + vert[i] = this.vertices.elementAt(i); + + // new min? + if (vert[i].x < min[0]) min[0] = vert[i].x; + if (vert[i].y < min[1]) min[1] = vert[i].y; + if (vert[i].z < min[2]) min[2] = vert[i].z; + + // new max? + if (vert[i].x > max[0]) max[0] = vert[i].x; + if (vert[i].y > max[1]) max[1] = vert[i].y; + if (vert[i].z > max[2]) max[2] = vert[i].z; + + center.add(vert[i]); + } + + // faces: + int fc[][] = new int[this.faces.size()][]; + for (int j = 0; j < this.faces.size(); j++) + fc[j] = this.faces.elementAt(j); + if (debug) System.out.println("numVerts=" + numVerts); + if (debug) System.out.println("numFaces=" + this.faces.size()); + + // scale mesh: + double maxSize = Math.max(Math.max(max[0] - min[0], max[1] - min[1]), max[2] - min[2]); + double scale = Math.pow(10.0, -Math.floor(Math.log(maxSize) / Math.log(10.0))); + for (int i = 0; i < vert.length; i++) + ((Vec3) vert[i]).scale(scale); + + // center mesh: + center.scale(1.0 / vert.length); + for (int i = 0; i < vert.length; i++) + vert[i] = vert[i].minus(center); + if (debug) System.out.println("CENTER: " + center); + + if (vert.length > 0) { + // merge duplicate points: + MeshTools mutil = new MeshTools(this.parent); + vert = mutil.mergePoints(vert, fc); + + // attempt to fix normals (SLOW!): + if (this.enableMeshRepair) mutil.fixCirality(fc); + + // add to scene: + CoordinateSystem coords = new CoordinateSystem(center, Vec3.vz(), Vec3.vy()); + // coords.setOrientation(270, 0, 0); + TriangleMesh mesh = new TriangleMesh(vert, fc); + ObjectInfo info = new ObjectInfo(mesh, coords, objName); + info.setTexture(theScene.getDefaultTexture(), theScene.getDefaultTexture() + .getDefaultMapping(mesh)); + info.addTrack(new PositionTrack(info), 0); + info.addTrack(new RotationTrack(info), 1); + theScene.addObject(info, null); + return mesh; + } + return null; + } + + /** + * fetch DXF, append to specified scene + * + * @param parent + * Frame Parent GUI frame + * @param inScene + * Scene Scene to append to + */ + public static void importFile(Frame parent, Scene inScene) { + if (inScene != null) { + theScene = inScene; + appendFlag = true; + } + importFile(parent); + } + + /** + * Try to add the entity to the faces and vertices lists + * + * @param + * @return + */ + private void addEntity(YxxfEnt ent) { + YxxfGfxMatrix m = new YxxfGfxMatrix(); + m.mtxSetIdentity(); + addEntity(ent, m); + } + + private void addEntity(YxxfEnt ent, YxxfGfxMatrix mat) { + if (ent instanceof YxxfEnt3Dface) { + // if (debug) System.out.println("Found a 3DFace"); + YxxfEnt3Dface f = (YxxfEnt3Dface) ent; + YxxfGfxPointW pt1 = f.pnt1; + YxxfGfxPointW pt2 = f.pnt2; + YxxfGfxPointW pt3 = f.pnt3; + YxxfGfxPointW pt4 = f.pnt4; + // if (debug) System.out.println("pt1: " + pt1.x + ", " + pt1.y + ", " + + // pt1.z); + // if (debug) System.out.println("pt2: " + pt2.x + ", " + pt2.y + ", " + + // pt2.z); + // if (debug) System.out.println("pt3: " + pt3.x + ", " + pt3.y + ", " + + // pt3.z); + // if (debug) System.out.println("pt4: " + pt4.x + ", " + pt4.y + ", " + + // pt4.z); + this.vertices.add(new Vec3(pt1.x, pt1.y, pt1.z)); + this.vertices.add(new Vec3(pt2.x, pt2.y, pt2.z)); + this.vertices.add(new Vec3(pt3.x, pt3.y, pt3.z)); + if (pt3.x == pt4.x && pt3.y == pt4.y && pt3.z == pt4.z) { + // 1 face + this.faces.add(new int[] { this.vertices.size() - 1, this.vertices.size() - 2, this.vertices.size() - 3 }); + } + else { + // 2 faces + this.vertices.add(new Vec3(pt4.x, pt4.y, pt4.z)); + this.faces.add(new int[] { this.vertices.size() - 1, this.vertices.size() - 2, this.vertices.size() - 3 }); + this.faces.add(new int[] { this.vertices.size() - 1, this.vertices.size() - 3, this.vertices.size() - 4 }); + } + } + else if (ent instanceof YxxfEntArc) { + YxxfEntArc a = (YxxfEntArc) ent; + if (debug) { + System.out.printf("Found an Arc: c=%.2f,%.2f,%.2f r=%.2f start=%.2f end=%.2f\n", + a.center.x,a.center.y,a.center.z,a.radius,a.entbegang,a.entendang); + + } + Vec3[] coords = createArc(mat, a.center, a.radius, a.entbegang, a.entendang); + this.polylines.add(coords); + } + else if (ent instanceof YxxfEntCircle) { + YxxfEntCircle c = (YxxfEntCircle)ent; + Vec3[] coords = createArc(mat, c.center, c.radius, 0, 360); + this.polylines.add(coords); + } + else if (ent instanceof YxxfEntInsert) { + YxxfEntInsert e = (YxxfEntInsert) ent; + if (debug) System.out.printf("Insert: %.2f,%.2f,%.2f\n", + e.inspnt.x, e.inspnt.y, e.inspnt.z); + YxxfEntBlock blk = (YxxfEntBlock)e.block; + for (int nextToDraw = 0;;) { + YxxfEnt ent2 = (YxxfEnt)blk.nextEntity(nextToDraw); + if (ent2 == null) break; + addEntity(ent2, e.M_insert); + nextToDraw++; + } + } + else if (ent instanceof YxxfEntLine) { + if (debug) System.out.println("Found an Line"); + YxxfEntLine l = (YxxfEntLine)ent; + Vec3[] polyline = new Vec3[2]; + YxxfGfxPointW p = mat.mtxTransformPoint(l.begpnt); + polyline[0] = new Vec3(p.x, p.y, p.z); + p = mat.mtxTransformPoint(l.begpnt); + polyline[1] = new Vec3(p.x, p.y, p.z); + this.polylines.add(polyline); + } + else if (ent instanceof YxxfEntLwpolyline) { + YxxfEntPolyline pl = (YxxfEntPolyline)((YxxfEntLwpolyline)ent).pline; + Vec3[] polyline = new Vec3[pl.vtxEntities.size()]; + for (int i=0;i<pl.vtxEntities.size();i++) { + YxxfGfxPointW p = mat.mtxTransformPoint(((YxxfEntVertex) pl.vtxEntities.get(i)).pnt); + polyline[i] = new Vec3(p.x, p.y, p.z); + } + this.polylines.add(polyline); + } + + else System.out.println("Skipping unknown/unsupported entity: " + ent.getClass().getName()); + + return; + } + + private Vec3[] createArc(YxxfGfxMatrix mat, + YxxfGfxPointW center, double radius, double startang, double endang) { + int num = 8; // FIXME: Calculate a suitable # of segments + double sweepang = (endang - startang)*Math.PI/180; + while (sweepang < 0) sweepang += Math.PI*2; + double delta = sweepang/num; + double angle = startang*Math.PI/180; + Vec3[] coords = new Vec3[num+1]; + for (int i = 0; i <= num; i++) { + YxxfGfxPointW p = mat.mtxTransformPoint(new YxxfGfxPointW(center.x + Math.cos(angle) * radius, + center.y + Math.sin(angle) * radius, + center.z)); + coords[i] = new Vec3(p.x, p.y, p.z); + angle += delta; + } + return coords; + } + + /** + * Separate a line into pieces divided by whitespace. + * + * @param line + * an input String + * @return String[] array of tokens + */ + private static String[] splitLine(String line) { + StringTokenizer st = new StringTokenizer(line); + Vector v = new Vector(); + + while (st.hasMoreTokens()) + v.addElement(st.nextToken()); + String result[] = new String[v.size()]; + v.copyInto(result); + return result; + } +} |