js-dxf
js-dxf copied to clipboard
Z-Value
Firstly, great job! thanks!
suggestion: on all entities, you have used 0 for the z coordinate, not allowing setting it like with, the x and the y. you used: "n30\n0\n" and it can easily support z the same way it support the flat coordinates.
Keep on a very good job.
Hi Elad,
Thanks. Yes, could be added...when I get time. If you have time and will, please add.
Regards, Ognjen
Hi @eladlavi !. Have you added z values yet? And @ognjen-petrovic do you planning adding it soon?
Hi @tologonkudaiberdiuulu . Actually I did in my own copy of the repository. Unfortunately , I didn't know how to do that such that @ognjen-petrovic can merge the changes. Maybe I'll figure it out because I have some more changes, for instance some geometries are missing.
@eladlavi is it possible to share it with me? Will be very grateful )
Is it possible @eladlavi ?
Yes, sure. Firstly, for every geometry that you wish to support z values, you have to update the constructor and the toDxfString() method (the only two methods in the class generally). I'll give you an example with class Point:
`class Point { constructor(x, y, z) { this.x = x; this.y = y; this.z = z; }
toDxfString()
{
//https://www.autodesk.com/techpubs/autocad/acadr14/dxf/point_al_u05_c.htm
let s = `0\nPOINT\n`;
s += `8\n${this.layer.name}\n`;
s += `10\n${this.x}\n20\n${this.y}\n30\n${this.z}\n`;
return s;
}
}
module.exports = Point;`
do you see how I replaced the original 0 with ${this.z} ? In the constructor, you can check if z is defined or undefined, so if it is undefined, you can set it to 0, so 0 will be the default value.
You make this change in every geometry you wish to support z values. It's very easy.
Maybe with some geometries it is more complicated. I'll give another example with Polyline3d:
`class Polyline3d { /** * @param {array} points - Array of points like [ [x1, y1, z1], [x2, y2, z2]... ] */ constructor(points) { this.points = points; }
toDxfString()
{
//https://www.autodesk.com/techpubs/autocad/acad2000/dxf/polyline_dxf_06.htm
//https://www.autodesk.com/techpubs/autocad/acad2000/dxf/vertex_dxf_06.htm
let s = `0\nPOLYLINE\n`;
s += `8\n${this.layer.name}\n`;
s += `66\n1\n70\n8\n`;
for (let i = 0; i < this.points.length; ++i)
{
s += `0\nVERTEX\n`;
s += `8\n${this.layer.name}\n`;
s += `70\n0\n`;
s += `10\n${this.points[i][0]}\n20\n${this.points[i][1]}\n30\n${this.points[i][2]}\n`;
}
s += `0\nSEQEND\n`;
return s;
}
}
module.exports = Polyline3d;` do you see how each point in the points array received in the constructor is expected to be an array of size 3 ? where the last value is the z value. That's why it has: ${this.points[i][2]} at the end...
There's one more thing to do. Within the Drawing.js file, you have different draw methods for each geometry. you have to modify it too. Here's an example for the Point method:
`drawPoint(x, y, z) {
this.activeLayer.addShape(new Point(x,y,z));
return this;
}`
that's it! I told you it's easy. You see how there's another parameter (z) to this method ? and it is passed to our modified constructor.
Let me know if it worked for you. In the future, I'll try to fork this reposity so the author can merge these changes.
First of all, thank you for your reply @eladlavi ! Ok, I understood with Points, but how about, say, LWPOLYLINE? It has elevation value, too. And what about extrusion values of all entities? Or I have dismissed it in source files? How I can set it? I have THREE.js entities drawn. How I can write it to DXF? Thanks in advance
Hi @tologonkudaiberdiuulu , So Polyline3d has Z value for each vertex, whereas Polyline vertices has no Z value, but the whole entity, the polyline itself, has a Z value - the elevation. Obviously you could use Polyline 3d for both cases, settings all vertices Z value to the same value. - the elevation. But if you want Polyline to support elevation, we will have to modify it like this: The constructor, as @ognjen-petrovic designed it, receives a list of points and an optional boolean that determines if the shape is close or not. Because it is optional, it is problematic to add another parameter to the constructor that will also be optional. Instead of passing a parameter to the constructor, we can use a "setter" or directly setting a Z property. If we do pass a Z value to the constructor anyway, then the boolean shouldn't be optional.
So let's go and modify the constructor as so:
constructor(points, closed = false) { this.points = points; this.closed = closed; this.z = 0; //add this line }
notice I do not receive a z value parameter in the constructor. We will set it directly as a property. Now let's modify the toDxfString() method like this:
toDxfString() { //https://www.autodesk.com/techpubs/autocad/acad2000/dxf/polyline_dxf_06.htm //https://www.autodesk.com/techpubs/autocad/acad2000/dxf/vertex_dxf_06.htm let s =
0\nPOLYLINE\n; s +=
8\n${this.layer.name}\n; s +=
66\n1\n70\n${this.closed ? 1 : 0}\n; s +=
10\n0\n; s +=
20\n0\n; s +=
30\n${this.z}\n`;
for (let i = 0; i < this.points.length; ++i)
{
s += `0\nVERTEX\n`;
s += `8\n${this.layer.name}\n`;
s += `70\n0\n`;
s += `10\n${this.points[i][0]}\n20\n${this.points[i][1]}\n`;
if (this.points[i][2] !== undefined) {
s += `42\n${this.points[i][2]}\n`;
}
}
s += `0\nSEQEND\n`;
return s;
}`
According to Autodesk documentation, this should work. Please check it out and make sure Autocad can open and present such line.
Ok. I see @eladlavi . It was bad example with LWPOLYLINE, 'cause it has z values with vertices. Say, ARC. Yes, it has z value, too. But it is related only to center of the ARC. But where normal of the ARC would be pointed? That's what I mean. In source files has ARC has only center point, startAngle and endAngle. What if ARC was rotated? How I can write it to dxf?
Because it is optional, it is problematic to add another parameter to the constructor that will also be optional. Instead of passing a parameter to the constructor,
If needed, we can change constructor signature.
@tologonkudaiberdiuulu , please don't expect such library to support geometric entities, that Autocard itself doesn't support. If Autocad supports some geometry, then it is documents in their DXF reference paper. The goal of this library, is write a DXF matching the DXF reference paper (look online for it, it is well published). Arc for example, is on page 66 of this document, and you see that Z values are for the center point. Meaning that Autocad themselves do not support such rotated/tilted arc as you are describing. It doesn't make sence that this library would support geometry that Autocad won't be able to process anyway. You see? therefor it is easy to add support for Arc too, the same way as my previous examples. If you wish, I can put here an exmaple code, but I think it is pretty clear now how to add the Z value.
Arc in DXF has extrusion direction (under code 210,220,230), maybe this is what you mean in regards to the tilt or the arc. We can add this too, but that's another story, it doesn't go by Z value, it goes by a vector that it purpendicular to the Arc's plain. This also can be added. The way the author of this library designed it, is such that it is easy to add support for such.
Arc in DXF has extrusion direction (under code 210,220,230), maybe this is what you mean in regards to the tilt or the arc.
Yes that's what I mean, extrusion directions. Ok I will try to calculate plane normal and write it to extrusion directions.
We can add this too, but that's another story, it doesn't go by Z
Yes I know that it doesn't go by Z value, instead goes with 'extrusionX', 'extrusionY' and 'extrusionZ'(As you mentioned 210, 220 and 230 code values). Thank you @eladlavi !