My recorded DXF file turns up tilted when I open it in CAD

Hi,
I have found a purpose for a program I have been working on a while back. The program is based on another program I didn’t create so I don’t know all the history on how it was made and I am a beginner in programming I would say.

The program is for a physical mechanical arm that I can move around and record the points where the tip of the arm is at. I can then export the results to DFX and PDF.
The PDF is another post for later I guess… The scaling is completely off there…
The DXF however gets the dimensions correct but when I open the file in my CAD software the DXF plane turns up all tilted and way off the origin och my sketch??

Anyone worked on exporting DXF files in processing?
I dont know if there is a plugin to handle this function or how it works? I want my exported DXF file to come out clean and in level with the plane I put it on in my CAD software…

Here is the main code of the program:

import peasy.*;


//============================================================
//  3D Digitizer
//  Used with 4 Axis 3D digitizer:
//  Program based off original concept by: http://fablab.ruc.dk/diy-digitizer/
//  Modificaitons and additional features by Bryan Lord Sept 2019
//  DXF and Point Cloud export
//============================================================

import processing.serial.*;
import peasy.*;
import processing.pdf.*;
import processing.dxf.*;

float Zheight = 0;
PrintWriter output;
boolean record = false;
boolean projection = false;
int cirSize = 5;
color faceColor=color(#C9C7C7);
RawDXF dxf;

//============================================================
//-3D navigation
//============================================================
PeasyCam cam;

//============================================================
//-Digitizer
//============================================================
pointer digitizer = new pointer(this, 0);

//============================================================
//  GUI controls
//============================================================
ArrayList<control> controls = new ArrayList<control>();
control ctl_quit = new control(10, 10, 'q', "Quit", "Quit program");
control ctl_clear = new control(10, 10+1*40, 'n', "New", "New - Clear all");
control ctl_point = new control(10, 10+2*40, 'p', "Point", "Mark a point");
control ctl_circle = new control(10, 10+3*40, 'c', "Circle", "Mark a hole");
control ctl_feature = new control(10, 10+4*40, 'f', "Feature", "Start a feature." + "\n" + "Use \"Modify\" to add points");
control ctl_modify = new control(10, 10+5*40, 'm', "Modify", "Modify last figure");
control ctl_dxf = new control(10, 10+6*40, 'z', ".DXF", "Export 3D DXF file");
control ctl_PtCld = new control(10, 10+7*40, 'x', "PtCld", "Export Point Cloud");
control ctl_pdf = new control(10, 10+8*40, 'd', ".PDF", "Output PDF" + "\n" + "(Projects to flat surface)");


//============================================================
//  Objects
//============================================================
ArrayList<object> objects = new ArrayList<object>();

//============================================================
//  Setup
//============================================================
void setup()
{
  size(1200, 800, P3D);
  output = createWriter("PntCld.txt");
  //Set up visualizer
  cam = new PeasyCam(this, 300);
  cam.setMinimumDistance(50);
  cam.setMaximumDistance(1000);
  //Add GUI controls to display list
  controls.add(ctl_quit);
  controls.add(ctl_clear);
  controls.add(ctl_point); 
  controls.add(ctl_circle); 
  controls.add(ctl_feature);
  controls.add(ctl_modify);
  controls.add(ctl_dxf);
  controls.add(ctl_PtCld);
  controls.add(ctl_pdf);

  background(50);
}

//============================================================
//  Handy globals
//============================================================
float penX=0;
float penY=0;
float penZ=0;
float penA=0;
//PVector pen;

object currentObject=null; //-Last created object

//============================================================
//  Draw
//======================================================proce======

void draw()
{

  //-Get coordinated from digitizer
  digitizer.update();      //-Update globals
  background(0);

  scale(1, -1);            //Reverses the Y coordinate system
  translate(-100, -100);    // Moves the background into the window

  PVector pd=new PVector(digitizer.tip.x, digitizer.tip.y);
  penA=digitizer.rotation;

  pd.rotate(-penA);

  penX=pd.x;
  penY=pd.y;
  penZ=digitizer.tip.z;
  //  pen=digitizer.tip;

  // *********** DXF recording ***************
  if (record == true) {
    String d="DXF_"+Integer.toString(year())+"_"+Integer.toString(day())+"_"+Integer.toString(hour())+"_"+Integer.toString(minute())+"_"+Integer.toString(second())+".dxf";
    beginRaw(DXF, d); 
    scale(1, -1);
    translate(-100, -100);
  }

  //-Draw pad
  stroke(250);
  //  fill(10,10,10,128);
  noFill();
  rect(-277.5, -277.5, 277.5*2, 277.5*2);

  // Draw Tool Home Location
  stroke(100, 500, 0);
  line(-270, 250, -Zheight, -270, 270, -Zheight);  // Horizontal Line
  line(-270, 270, -Zheight, -250, 270, -Zheight);  // Vertical Line

  //-Draw Orign Triad
  stroke(255, 0, 0);  // X Axis Line Colour
  line(0, 0, 20, 0);
  stroke(0, 255, 0);  // Y Axis Line Colour
  line(0, 0, 0, 20);
  stroke(0, 0, 255);  // Z Axis Line Colour
  line(0, 0, 0, 0, 0, 20);

  rotateZ(penA);  // Used for turntable?

  /*
  //-Draw all objects flat projection
   if (projection == true)
   {
   for (object obj : objects)
   {
   obj.project();
   }
   }
   */

  //-Draw all objects
  for (object obj : objects)
  {
    obj.draw();
  }

  if (record == true) {
    endRaw();
    record = false; // Stop recording to the file
  }


  //-Draw cursor
  //  pushMatrix();
  rotateZ(-penA);
  translate(digitizer.tip.x, digitizer.tip.y, digitizer.tip.z);
  stroke(0, 255, 0);
  noFill();
  box(5);
  //  popMatrix();


  //-Draw Heads Up Display
  cam.beginHUD();  
  color faceColor=color(#C9C7C7);
  color textColor=color(75, 42, 0);
  stroke(80);
  fill(faceColor);
  rect(width-115, 10, 105, 100);  // XYZ HUD box
  textSize(15);

  //-Coordinates
  float fx = penX;          // Limits the displayed coordinates to 2 dec/pt.
  String sx = nfc(fx, 2);
  float fy = penY;
  String sy = nfc(fy, 2);
  float fz = penZ;
  String sz = nfc(fz, 2);
  fill(0); // Text Colour
  text("X: "+ sx, width-110, 30);
  fill(0); // Text Colour
  text("Y: "+ sy, width-110, 50);
  fill(0); // Text Colour
  text("Z: "+ sz, width-110, 70);
  fill(0); // Text Colour
  text("-----------", width-110, 90);
  //text("R: "+penA, width-110, 90);
  text("Circle: "+ cirSize + "mm", width-110, 104);
  pushStyle();

  //-Update GUI controls 
  if (ctl_clear.update())
  {
    objects.clear();
  }
  if (ctl_point.update())
  {
    currentObject=new gpoint(penX, penY, penZ);
    objects.add(currentObject);
    point(penX, penY, penZ);
    output.println(penX + "\t" + penY + "\t" + penZ);
  }
  if (ctl_circle.update())
  {
    currentObject=new gcircle(penX, penY, penZ);
    objects.add(currentObject);
  }
  if (ctl_feature.update())
  {
    currentObject=new gfeature(penX, penY, penZ);
    objects.add(currentObject);
  }
  if (ctl_modify.update())
  {
    if (currentObject!=null)
    {
      currentObject.modify(new PVector(penX, penY, penZ));
    }
  }
  // ***********    DXF File Save
  if (ctl_dxf.update())
  {
    record = true; // DXF record switch
  }

  // ***********    PointCloud File Save
  if (ctl_PtCld.update())
  {
    output.flush(); // Writes the remaining data to the file
    output.close(); // Finishes the file
  }

  // ***********    PDF File Save
  if (ctl_pdf.update())
  {
    String s="PDF_"+Integer.toString(year())+"_"+Integer.toString(day())+"_"+Integer.toString(hour())+"_"+Integer.toString(minute())+"_"+Integer.toString(second())+".pdf";
    beginRecord(PDF, s); 
    scale(1, -1);
    translate(400, -500);
    background(255);
    stroke(0);
    fill(0); 
    rect(-380, -250, 10, 10);
    scale(1, -1);
    fill(0); // Text Colour
    text("10mm", -390, 230);
    scale(1, -1);

    for (object obj : objects)
    {
      obj.project();
    }

    for (object obj : objects)
    {
      obj.export();
    }
    endRecord();
  }

  // *********** Exit Program
  if (ctl_quit.update())
  {
    exit(); // Stops the program
  }


  //-Draw GUI controls
  for (control ctl : controls)
  {
    if (ctl.change)
      ctl.draw();
    if (ctl.mouseOver)
      ctl.drawHelp();
  }
  popStyle();
  cam.endHUD();
}

GUI

//============================================================
//  Simple GUI controls
//  Controls are activated by key and mouse click
//  Contextual help is displayed on mouse over
//  (F)DZL 2015
//============================================================

class control
{
  //Position and size of HUD Menu windows (individual Sizes)
  int x=0;
  int y=0;
  int w=60;
  int h=35;
  //-Colors
  color faceColor=color(98, 206, 198);
  color textColor=color(75, 42, 0);
  //-Key to activate control
  char hotkey;
  //-Discriptive caption
  String caption;
  //-Mouse-over help 
  String help;
  //-Mouse and key state
  boolean clickState=false;
  boolean keyState=false;
  boolean mouseOver=false;
  //-Updated for redraw
  boolean change=false;
  //-Typematic control
  int timer=0;
  boolean typematic=false;


  //-Constructor
  control(int px, int py, char k, String c, String h)
  {
    x=px;
    y=py;
    hotkey=k;
    caption=c;
    help=h;
  }


  //-Draw
  void draw()
  {
    if (clickState||keyState)
      stroke(255, 0, 0);
    else
    stroke(100);
    fill(#C9C7C7);  // background colour of Menu
    rect(x, y, w, h);  // draws the rectangle
    fill(textColor);
    textSize(20);
    text("-"+hotkey+"-", x+5, y+17);  // First line of text
    textSize(14);
    text(caption, x+6, y+33);  // Second line of text
  }


  //-Draw help
  void drawHelp()
  {
    textSize(20);
    fill(200);
    text(help, x+w+5, y+20);
  }


  //-Update. Handles keys and mouse
  boolean update()
  {
    boolean result=false;
    mouseOver=false;
    if ((mouseX>x)&&(mouseX<(x+w)) && (mouseY>y)&&(mouseY<(y+h)))
    {
      mouseOver=true;
      if (mousePressed==true)
      {
        if (!clickState)
        {
          clickState=true;
          change=true;
        }
      } else
      {
        if (clickState==true)
        {
          result=true;
          clickState=false;
          change=true;
        }
      }
    } else
      if (mousePressed==false)
      {      
        clickState=false;
        change=true;
      }     


    if (key==hotkey)
    {
      if (keyPressed==true)
      {
        mouseOver=true;

        if (!keyState)
        {
          keyState=true;
          change=true;
          timer=millis()+500;
          result=true;
        } else
        {
          if (typematic)
          {
            if (millis()>timer)
            {
              timer+=10;
              result=true;
            }
          }
        }
      } else
      {
        if (keyState==true)
        {
          keyState=false;
          change=true;
        }
      }
    } else
      if (keyPressed==false)
      {
        keyState=false;
        change=true;
      }
    return result;
  }
}

void keyPressed() {
  if (key == '+') {
    cirSize=cirSize+1;
  }
  if (key == '-') {
    cirSize=cirSize-1;
  }
}

OBJECTS

//============================================================
//  Measuring objects for 3D digitizer
//  Objects implements function for 3D and 2D screen drawing and
//  2D export.
//  (F)DZL 2015   
//============================================================
//============================================================
// Base class for all objects
//============================================================
public abstract class object
{
  abstract void draw();  //-Draw to screen (3D)
  abstract void modify(PVector p); //-Modify object
  abstract void project(); //-Draw to 2D
  abstract void export(); //-Export (draw .PDF compatible)

};
//============================================================
// Single 3D point (1mmm box)
//============================================================
class gpoint extends object
{
  PVector pos;
  color lineColor=color(255);
  color projectColor=color(100);
  color exportColor=color(0);
  gpoint(PVector p)
  {
    pos.x=p.x;
    pos.y=p.y;
    pos.z=p.z;
  }
  gpoint(float x, float y, float z)
  {
    pos=new PVector(x, y, z);
  }
  void draw()
  {
    stroke(lineColor);
    pushMatrix();
    translate(pos.x, pos.y, pos.z);
    box(1);
    popMatrix();
  }

  void project()
  {
    stroke(projectColor);
    line(pos.x-5, pos.y, pos.x+5, pos.y);
    line(pos.x, pos.y-5, pos.x, pos.y+5);
  }

  void export()
  {
    stroke(exportColor);
    line(pos.x-5, pos.y, pos.x+5, pos.y);
    line(pos.x, pos.y-5, pos.x, pos.y+5);
  }

  void modify(PVector p)
  {
    pos.x=p.x;
    pos.y=p.y;
    pos.z=p.z;
  }
}

//============================================================
// Single circle 
//============================================================
class gcircle extends object
{
  PVector pos;
  color projectColor=color(100);
  color exportColor=color(0);
  color lineColor=color(255);
  boolean filled=true;
  gcircle(PVector p)
  {
    pos.x=p.x;
    pos.y=p.y;
    pos.z=p.z;
  }
  gcircle(float x, float y, float z)
  {
    pos=new PVector(x, y, z);
  }
  void draw()
  {
    stroke(lineColor);
    pushMatrix();
    translate(pos.x, pos.y, pos.z);
    ellipse(0, 0, cirSize, cirSize);
    popMatrix();
  }
  void project()
  {
    stroke(projectColor);
    ellipse(pos.x, pos.y, cirSize, cirSize);
  }

  void export()
  {
    if (filled)
    {
      noStroke();
      fill(exportColor);
    } else
    {
      noFill();
      stroke(exportColor);
    }
    ellipse(pos.x, pos.y, 10, 10);
  }

  void modify(PVector p)
  {
    pos.x=p.x;
    pos.y=p.y;
    pos.z=p.z;
  }
}

//============================================================
//  Open loop feature
//============================================================
class gfeature extends object
{
  boolean filled=true;
  PVector pos=new PVector(0, 0, 0);
  color projectColor=color(100);
  color exportColor=color(100, 100, 0);
  color lineColor=color(255, 255, 0);
  color anchorColor=color(0, 255, 0);
  ArrayList<PVector> figure = new ArrayList<PVector>();
  gfeature(PVector p)
  {
    pos.x=p.x;
    pos.y=p.y;
    pos.z=p.z;
    figure.add(new PVector(pos.x, pos.y, pos.z));
  }
  gfeature(float x, float y, float z)
  {
    pos=new PVector(x, y, z);
    figure.add(new PVector(pos.x, pos.y, pos.z));
  }

  void draw()
  {
    pushMatrix();
    translate(pos.x, pos.y, pos.z);
    stroke(anchorColor);
    ellipse(0, 0, 5, 5);
    popMatrix();
    float x0=pos.x;
    float y0=pos.y;
    float z0=pos.z;

    stroke(lineColor);

    for (PVector p : figure)
    {
      line(x0, y0, z0, p.x, p.y, p.z);
      x0=p.x;
      y0=p.y;
      z0=p.z;
    }
    line(x0, y0, z0, pos.x, pos.y, pos.z);
  }

  void project()
  {
    stroke(projectColor);
    float x0=pos.x;
    float y0=pos.y;
    float z0=pos.z;
    for (PVector p : figure)
    {
      line(x0, y0, p.x, p.y);
      x0=p.x;
      y0=p.y;
      z0=p.z;
    }
    line(x0, y0, pos.x, pos.y);
  }

  void export()
  {
    if (filled)
    {
      noStroke();
      fill(exportColor);
    } else
    {
      noFill();
      stroke(exportColor);
    }

    PShape loop=createShape();
    loop.beginShape();

    for (PVector p : figure)
    {
      loop.vertex(p.x, p.y);
    }
    loop.vertex(pos.x, pos.y);
    loop.endShape();
    shape(loop);
  }

  void modify(PVector p)
  {
    figure.add(new PVector(p.x, p.y, p.z));
  }
}
import processing.serial.*;

Serial myPort;  // Create object from Serial class

float PX=0;
float PY=0;
float PZ=0;
float ROT=0;

float sx=0;
float sy=0;
float sz=0;
float sa=0;

char datatype;
byte [] inData = new byte[5];
int inptr=0;
int rstate=0;

float www=0;
static final int zero = 0;
static final int one = 1;


void serialEvent(Serial myPort) 
{
  while (myPort.available ()>0)
  {
    switch(rstate)
    {
    case zero:
      datatype = myPort.readChar();
      if (datatype=='x'||datatype=='y'||datatype=='z'||datatype=='a')
      {
        rstate=1;
        inptr=0;
      }
      break;

    case one:
      inData[inptr++]=(byte)myPort.readChar();
      if (inptr==4)
      {
        int intbit = 0;
        intbit = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff);
        float f = Float.intBitsToFloat(intbit);

        switch(datatype)
        {
        case 'x': 
          sx=f;
          break;
        case 'y': 
          sy=f;
          break;
        case 'z': 
          PX=sx;
          PY=sy;
          PZ=f;
          ROT=sa;
         
          break;
        case 'a':
          sa=f;
          break;
        }
        rstate=0;
      }        
      break;
    }
  }
}


class pointer
{
  PVector tip = new PVector(0, 0, 0);
  float rotation=0;
  boolean active=false;
  boolean demoMode=false;        // = true for offline testing
  pointer(PApplet p,int index)
  {
    myPort =new Serial(p, Serial.list()[0], 19200); // Comment out for offline testing
    active=true;

  }

  void update()
  {
    if (demoMode)
    {
     // tip.x=(mouseX/2)-200;
     // tip.y=(mouseY/-2)+300;
     // tip.z=0;
    }
    else
    {
//      tip.set(PX,PY,PZ);
      tip.x=PX;
      tip.y=PY; 
      tip.z=PZ-Zheight; // Add to this value to move the pointer starting positon
      rotation=ROT;
    }
  }
}

homework policy * asking questions

Hi,
I need to bump this topic.
Maybe someone can help me almost a year after I first posted :slightly_smiling_face:

Short version of my problem above:
I’m recording points and lines using a physical arm.
Then I export the graphics as a DXF file.
When I open the DXF file in a CAD software, the “drawing” is tilted.
I am recording the points on a flat plane and that flat plane gets exported but the whole plane is tilted.

I cant seem to find any code that would make that happen or any lines for configuring this…

Anyone have a clue?

Can’t you tilt it in the CAD program and ignore the processing code?

Did you try to get rid of peasycam? Or do you need it? It also changes your coordinate system if I remember correctly.

also you have a scale call to swap y axis…?

This looks suspicious

I don’t know the digitizer arm but stuff like pd.rotate I don’t understand…

I am going to get the hardware in about two hours from now…
(I have stored it for a while cause of other projects)

As I remember, I was experimenting and found that changeing those values (scale and translate) made things work better than it did before I changed them. :crazy_face:
As the comments says they did something. It might have been the wrong way to do it however… :grimacing:

Thanks. Did you try this?

Im having a hard time getting the arm running again after this time.
I have to find the correct program and ill might try re flashing the arduino… As soon as I get it started so I can test it and see my tilted result ill check out peasycam.

But… peasycam is the thing that makes the visuals right?..

Hi,

Im getting this when I try to tun the program, any ideas??
It’s like there is something wrong with Java or processing. Not getting errors from the code…

java.lang.reflect.InvocationTargetException

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	at processing.core.PApplet.runSketch(PApplet.java:10845)
	at processing.core.PApplet.main(PApplet.java:10613)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at processing.core.PApplet.runSketch(PApplet.java:10839)
RuntimeException: java.lang.reflect.InvocationTargetException
	... 1 more
Caused by: java.lang.RuntimeException: Error opening serial port COM3: Port busy
	at processing.serial.Serial.<init>(Unknown Source)
	at processing.serial.Serial.<init>(Unknown Source)
	at GUI2_demo4_plus$pointer.<init>(GUI2_demo4_plus.java:650)
	at GUI2_demo4_plus.<init>(GUI2_demo4_plus.java:41)
	... 6 more
Copied to the clipboard. Use shift-click to search the web instead.

I’m stuck, dont know where to look for errors…
help…
:sob:

Did you disable Peasycam and try the results?

Does your arm and code run again?