tarikjabiri / js-dxf

JavaScript DXF writer
MIT License
179 stars 76 forks source link

Add support for splines and version of protocol #11

Closed kriffe closed 3 years ago

kriffe commented 5 years ago

I have started an implementation of the spline feature (https://www.autodesk.com/techpubs/autocad/acad2000/dxf/spline_dxf_06.htm) in a branch but I think it fails due to some missing defaults in the header (no header in project). Therefore I suggest that a minimal header should be added.

ognjen-petrovic commented 5 years ago

Great.

I have no idea which variables are needed for the minimal header. Add all and then trim or just leave all?

2013 is fine.

ognjen-petrovic commented 5 years ago

LibreCad draws spline without header parameters: image

kriffe commented 5 years ago

Thats very interesting. If we can skip the header it would be very nice. But it would be good to check with AutoCAD and a few other platforms also to ensure that it works on wide front

ericman314 commented 3 years ago

I am also interested in having support for splines. Is there anything I can do to help?

ognjen-petrovic commented 3 years ago

I am also interested in having support for splines. Is there anything I can do to help?

Hi Eric,

Seems that issue was with missing headers, although Libre CAD works. For the begging, If you have AutoCAD or some other CAD software you could try with it. Here is the generated file

Regards

ericman314 commented 3 years ago

The file does render in LibreCAD, but I have seen it render splines incorrectly many times, so I wouldn't trust it.

When I parse that generated file with this library (which I have tested extensively), I get: Error: Bad knot vector length, expected 7 but got 6.

Here is the parsed spline:

  {
    type: 'SPLINE',
    controlPoints: [
      { x: 0, y: 0, z: 0 },
      { x: 10, y: 10, z: 0 },
      { x: 20, y: 10, z: 0 },
      { x: 30, y: 0, z: 0 }
    ],
    knots: [ 0, 0, 0, 1, 1, 1 ],
    layer: '0',
    extrusionX: 0,
    extrusionY: 0,
    extrusionZ: 1,
    flag: 12,
    closed: false,
    degree: 2,
    numberOfKnots: 6,
    numberOfControlPoints: 4,
    numberOfFitPoints: 0,
    knotTolerance: 0.000001,
    controlPointTolerance: 0.000001,
    transforms: []
  }

The number of knots should be the number of control points, plus the degree, plus 1. So that could be part of the problem.

I have taken a look at the implementation of drawSplineFromControlPoints. For my purposes, in addition to specifying the control points I would also need to be able to specify the degree, knot vector, and possibly others. I realize this is overkill for most people so I wonder if the API could allow some optional parameters to specify those. Something like:

drawSpline(controlPoints, degree=3, knotVector=null, weights=null, fitPoints=[])

If knotVector or weights is null, the library would provide suitable defaults, and could also throw an error if the user's supplied knot vector is wrong.

I've got time to work on this if you would like.

ognjen-petrovic commented 3 years ago

Hi @ericman314

Sure, no problem, just do it.

Thanks,

kriffe commented 3 years ago

@ericman314 I created a draft for Spline back when this issue was created. Please see below if you want to use for start.

The lack of header stopped my progress there.

src/Spline.js

class Spline
{
    /**
     * @param {array} controlPoints - Array of points like [ [x1, y1], [x2, y2]... ]
     */
    constructor(type, degree, controlPoints, knots, fitPoints)
    {
        this.controlPoints = controlPoints
        this.knots = knots
        this.fitPoints = fitPoints
        this.type = type
        this.degree = degree

        // const closed = 0
        // const periodic = 0
        // const rational = 1
        // const planar = 1
        // const linear = 0
        // const splineType = 1024 * closed + 128 * periodic + 8 * rational + 4 * planar + 2 * linear

    }

    toDxfString()
    {
      // https://www.autodesk.com/techpubs/autocad/acad2000/dxf/spline_dxf_06.htm
        let s = `0\nSPLINE\n`
        s += `8\n${this.layer.name}\n`
        s += `100\nAcDbSpline\n`
        s += `210\n0.0\n220\n0.0\n230\n1.0\n`

        s+= `70\n${this.type}\n`
        s+= `71\n${this.degree}\n`
        s+= `72\n${this.knots.length}\n`
        s+= `73\n${this.controlPoints.length}\n`
        s+= `74\n${this.fitPoints.length}\n`
        s+= `42\n1e-6\n`
        s+= `43\n1e-6\n`

        for (let i = 0; i < this.knots.length; ++i)
        {
            s += `40\n${this.knots[i]}\n`
        }

        for (let i = 0; i < this.controlPoints.length; ++i)
        {
            s += `10\n${this.controlPoints[i][0]}\n`
            s += `20\n${this.controlPoints[i][1]}\n`
            s += `30\n0\n`
        }

        return s;
    }
}

module.exports = Spline

Added method of Drawing.js class

class Drawing
...
drawSplineFromControlPoints(points) {
      const knots = [0,0,0,1,1,1]
      const degree = 2

      // ToDo: Calculate knots and degree automatic
      const closed = 0
      const periodic = 0
      const rational = 1
      const planar = 1
      const linear = 0
      const splineType = 1024 * closed + 128 * periodic + 8 * rational + 4 * planar + 2 * linear
      this.activeLayer.addShape(new Spline(splineType, degree, points, knots, []))

 }

There is still a branch with this solution whit test file in Examples/browser/spline.html (not working without header thou): https://github.com/kriffe/js-dxf/tree/Spline_features

ognjen-petrovic commented 3 years ago

There is also "spline" branch on this repo, it has the Spline class and method, it has been created from the kriffes's branch. I have just updated it so it is up to date with the master.

ericman314 commented 3 years ago

Perfect. I will work on it this weekend.

kriffe commented 3 years ago

Regarding the protocol version part of this issue, and getting a wider usage than LibreCAD, I have created a separate issue to discuss this https://github.com/ognjen-petrovic/js-dxf/issues/33

ognjen-petrovic commented 3 years ago

I closed issue, minimal header and version issue are moved to https://github.com/ognjen-petrovic/js-dxf/issues/33

forresto commented 1 year ago

(Moved question to #97)