@stelmashchuk/autocad-dxf
Version:
A module which can be used to parse AutoCAD dxf files and to make programmatic and geometric operations on the AutoCAD drawing entities.
177 lines (160 loc) • 7.2 kB
JavaScript
const Intersection = require("./Intersection");
const ErrorMessages = require("./ErrorMessages.json");
module.exports = (entity, etypes, plane, entities, getAxes, tolerance) => {
if (typeof entity != "object" || typeof entities != "object") {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
let [ax1, ax2] = getAxes(plane);
if (plane && ax1 === undefined && ax2 === undefined) {
throw new Error(ErrorMessages.INCORRECT_PARAMS);
return;
}
const txt = JSON.stringify(entity);
let filtered;
if (etypes && Array.isArray(etypes)) {
filtered = entities.filter((item, index) => {
if (JSON.stringify(item) == txt) return false;
return (etypes && Array.isArray(etypes) && etypes.filter((en) => (("acdb" + en.toLowerCase()) == item.subclass.toLowerCase()) || (item.specific_type && ("acdb" + en.toLowerCase()) == item.specific_type.toLowerCase())).length > 0);
});
} else {
filtered = entities;
}
let crossing = [];
const etype = entity.etype;
filtered.forEach((item) => {
const points = Intersection(entity, item, plane, getAxes, tolerance);
if (points && points.length > 0) {
if (etype == "LINE") {
for (let i = 0; i < points.length; i++) {
if (crossing.indexOf(item) != -1) continue;
if ((Math.abs(points[i][ax1] - entity[`start_${ax1}`]) > tolerance || Math.abs(points[i][ax2] - entity[`start_${ax2}`]) > tolerance) &&
(Math.abs(points[i][ax1] - entity[`end_${ax1}`]) > tolerance || Math.abs(points[i][ax2] - entity[`end_${ax2}`]) > tolerance)) {
crossing.push(item);
break;
}
}
} else if (etype == "LWPOLYLINE") {
for (let i = 0; i < points.length; i++) {
if (crossing.indexOf(item) != -1) continue;
const temp = entity.vertices.filter((v) => {
return (Math.abs(points[i][ax1] - v[ax1]) < tolerance && Math.abs(points[i][ax2] - v[ax2]) < tolerance);
});
const vertices = JSON.parse(JSON.stringify(entity.vertices));
if (entity.type == "Closed") {
vertices.push(vertices[0]);
}
for (let j = 1; j < vertices.length; j++) {
const x0 = vertices[j - 1][ax1];
const y0 = vertices[j - 1][ax2];
const x1 = vertices[j][ax1];
const y1 = vertices[j][ax2];
if (Math.abs(points[i][ax1] - x0) < tolerance && Math.abs(points[i][ax2] - y0) < tolerance) {
continue;
}
if ((j == (vertices.length - 1)) && Math.abs(points[i][ax1] - x1) < tolerance && Math.abs(points[i][ax2] - y1) < tolerance) {
continue;
}
const slope = (y1 - y0)/(x1 - x0);
if (Math.abs(slope) == Infinity && Math.abs(x1 - points[i][ax1]) < tolerance) {
continue;
} else {
if (Math.abs((slope*points[i][ax1] - slope*x0 + y0) - points[i][ax2]) < tolerance) {
continue;
}
}
if ((Math.abs(points[0][ax1] - x0) > tolerance || Math.abs(points[0][ax2] - y0) > tolerance) &&
(Math.abs(points[0][ax1] - x1) > tolerance || Math.abs(points[0][ax2] - x1) > tolerance)) {
if (item.etype == "LINE") {
if ((Math.abs(item[`start_${ax1}`] - points[i][ax1]) > tolerance ||
Math.abs(item[`start_${ax2}`] - points[i][ax2]) > tolerance) &&
(Math.abs(item[`end_${ax1}`] - points[i][ax1]) > tolerance ||
Math.abs(item[`end_${ax2}`] - points[i][ax2]) > tolerance)) {
crossing.push(item);
break;
}
} else if (item.etype == "LWPOLYLINE") {
const v = JSON.parse(JSON.stringify(item.vertices));
if (item.type == "Closed") {
v.push(vertices[0]);
}
for (let j = 1; j < v.length; j++) {
if (crossing.indexOf(item) != -1) break;
const x02 = v[j - 1][ax1];
const y02 = v[j - 1][ax2];
const x12 = v[j][ax1];
const y12 = v[j][ax2];
if ((Math.abs(points[0][ax1] - x02) > tolerance || Math.abs(points[0][ax2] - y02) > tolerance) &&
(Math.abs(points[0][ax1] - x12) > tolerance || Math.abs(points[0][ax2] - x12) > tolerance)) {
crossing.push(item);
break;
}
}
} else if (item.etype == "CIRCLE" || item.etype == "ARC") {
const slope = (y0 - y1)/(x0 - x1);
if ((Math.abs(slope) == Infinity && Math.abs(item[`{ax1}`] - points[i][ax1]) < item.radius)) {
crossing.push(item);
break;
} else if (Math.abs(slope*item[`${ax1}`] - slope*x0 + y0 - item[`${ax2}`]) < item.radius) {
crossing.push(item);
break;
}
}
}
}
/* if (temp.length == 0) {
crossing.push(item);
break;
} */
}
} else if ((etype == "CIRCLE" || etype == "ARC") && crossing.indexOf(item) == -1) {
if ((item.etype == "CIRCLE" || item.etype == "ARC") && points.length > 1) {
crossing.push(item);
} else if ((item.etype == "ARC") && points.length == 1) {
const d = Math.sqrt((entity[ax1] - item[ax1])*(entity[ax1] - item[ax1]) + (entity[ax2] - item[ax2])*(entity[ax2] - item[ax2]));
if ((entity.radius + item.radius - d) > tolerance) {
crossing.push(item);
}
} else if (item.etype == "LINE" && points.length > 1) {
crossing.push(item);
} else if (item.etype == "LINE" && points.length == 1) {
if ((Math.abs(points[0][ax1] - item[`start_${ax1}`]) > tolerance || Math.abs(points[0][ax2] - item[`start_${ax2}`]) > tolerance) &&
(Math.abs(points[0][ax1] - item[`end_${ax1}`]) > tolerance || Math.abs(points[0][ax2] - item[`end_${ax2}`]) > tolerance)) {
const slope = (item[`start_${ax2}`] - item[`end_${ax2}`])/(item[`start_${ax1}`] - item[`end_${ax1}`]);
if (Math.abs(slope) == Infinity && Math.abs(Math.abs(entity[ax1] - points[0][ax1]) - entity.radius) > tolerance) {
crossing.push(item);
} else if (Math.abs((-slope*entity[ax1] + entity[ax2] + slope*item[`start_${ax1}`] - item[`start_${ax2}`])/(Math.sqrt(1 + slope*slope))) < entity.radius) {
crossing.push(item);
}
}
} else if (item.etype == "LWPOLYLINE") {
const vertices = JSON.parse(JSON.stringify(item.vertices));
if (item.type == "Closed") {
vertices.push(vertices[0]);
}
for (let i = 1; i < vertices.length; i++) {
const x0 = vertices[i - 1][ax1];
const y0 = vertices[i - 1][ax2];
const x1 = vertices[i][ax1];
const y1 = vertices[i][ax2];
for (let j = 0; j < points.length; j++) {
if (crossing.indexOf(item) != -1) break;
if ((Math.abs(points[j][ax1] - x0) > tolerance || Math.abs(points[j][ax2] - y0) > tolerance) &&
(Math.abs(points[j][ax1] - x1) > tolerance || Math.abs(points[j][ax2] - x1) > tolerance)) {
const slope = (y1 - y0)/(x1 - x0);
if (Math.abs(slope) == Infinity && Math.abs(Math.abs(entity[ax1] - x0) - entity.radius) > tolerance) {
crossing.push(item);
break;
} else if (Math.abs((-slope*entity[ax1] + entity[ax2] + slope*x0 - y0)/(Math.sqrt(1 + slope*slope)) - entity.radius) > tolerance) {
crossing.push(item);
break;
}
}
}
}
}
}
}
});
return crossing;
};