|
||
| Правила | Регистрация | Пользователи | Сообщения за день | | Поиск | | Справка по форуму | Файлообменник | |
Поиск по форуму |
Расширенный поиск |
Найти все сообщения с благодарностями |
К странице... |
|
Поиск в этой теме |
13.07.2021, 11:12 | #1 | |
JavaScript. nanoCAD 5. Экспорт в файл геометрии Gmsh
Инженер-философ
Хабаровск
Регистрация: 24.04.2019
Сообщений: 1,876
Самое сложное при создании геометрии в Gmsh - ввести координаты точек. Намного удобнее экспортировать геометрию из када. В автокаде есть экспорт *.iges, а нанокадчикам халявной версии поможет этот скрипт.
Код:
[Выделить все]
/* * Экспорт из nanoCAD в файл геометрии GMSH * Точки экспортируются в узлы * Отрезки - в линии * Круги - в четыре дуговых сегмента * Дуги - в дуговые сегменты не более 90° каждый * Незамкнутые полилинии - в линии и дуги * Замкнутые полилинии - в плоские поверхности */ // Счетчики для нумерации объектов в файле var nPoint = 0 // Номер следующей точки var nCurve = 0 // Номер следующей кривой var nCurveLoop = 0 // Номер следующего контура var nSurface = 0 // Номер следующей поверхности /** * Переводит точку из объектной системы координат в мировую. * @param {number[2]} point Точка в объектной системе координат * @param {number} elevation Возвышение объекта * @param {Object} normal Нормаль объекта * @returns {number[3]} */ function OCSarrayToWCSarray(point, elevation, normal) { var point3D = new Array(point[0], point[1], elevation) var pointOCS = Utility.CreateTypedArrayFromJSArray(5, point3D) var pointWCS = Utility.TranslateCoordinates(pointOCS, acOCS, acWorld, false, normal) return Utility.CreateSafeArrayFromVector(pointWCS).toArray() } /** * Возвращает скалярное произведение векторов * @param {number[3]} vector1 Первый вектор * @param {number[3]} vector2 Второй вектор * @returns {number} */ function DotProduct3D(vector1, vector2) { return vector1[0] * vector2[0] + vector1[1] * vector2[1] + vector1[2] * vector2[2] } /** * Возвращает векторное произведение векторов * @param {number[3]} vector1 Первый вектор * @param {number[3]} vector2 Второй вектор * @returns {number[3]} */ function CrossProduct3D(vector1, vector2) { return [ vector1[1] * vector2[2] - vector1[2] * vector2[1], vector1[2] * vector2[0] - vector1[0] * vector2[2], vector1[0] * vector2[1] - vector1[1] * vector2[0] ] } /** * Возвращает длину вектора * @param {number[2]} vector Вектор * @returns {number} */ function Length2D(vector) { return Math.sqrt ( Math.pow(vector[0], 2) + Math.pow(vector[1], 2)) } /** * Возвращает длину вектора * @param {number[3]} vector Вектор * @returns {number} */ function Length3D(vector) { return Math.sqrt ( Math.pow(vector[0], 2) + Math.pow(vector[1], 2) + Math.pow(vector[2], 2)) } /** * Возвращает нормализованный вектор * @param {number[3]} vector Вектор * @returns {number[3]} */ function Normalize3D(vector) { Length = Length3D(vector) return [ vector[0] / Length, vector[1] / Length, vector[2] / Length ] } /** * Возвращает разность векторов * @param {number[2]} vector1 Первый вектор * @param {number[2]} vector2 Второй вектор * @returns {number[2]} */ function Substract2D(vector1, vector2) { return [ vector1[0] - vector2[0], vector1[1] - vector2[1] ] } /** * Возвращает сумму векторов * @param {number[3]} vector1 Первый вектор * @param {number[3]} vector2 Второй вектор * @returns {number[3]} */ function Add3D(vector1, vector2) { return [ vector1[0] + vector2[0], vector1[1] + vector2[1], vector1[2] + vector2[2], ] } /** * Возвращает произведение вектора на множитель * @param {number} scalar Масштабный множитель * @param {number[3]} vector Вектор * @returns {number[3]} */ function Scale3D(scalar, vector) { return [ scalar * vector[0], scalar * vector[1], scalar * vector[2] ] } /** * Возвращает произведение матрицы на вектор * @param {number[3][3]} matrix Матрица * @param {number[3]} vector Вектор * @returns {number[3]} */ function Multiply3D(matrix, vector) { return [ matrix[0][0] * vector[0] + matrix[0][1] * vector[1] + matrix[0][2] * vector[2], matrix[1][0] * vector[0] + matrix[1][1] * vector[1] + matrix[1][2] * vector[2], matrix[2][0] * vector[0] + matrix[2][1] * vector[1] + matrix[2][2] * vector[2] ] } /** * Возвращает матрицу поворота вокруг заданной оси на заданный угол * @param {number[3]} axis Ось вращения * @param {number} angle Угол поворота * @returns {number[3][3]} */ function AxisRotationMatrix(axis, angle) { var x = axis[0] var y = axis[1] var z = axis[2] var cos = Math.cos(angle) var sin = Math.sin(angle) return [ [(1 - cos) * x * x + cos, (1 - cos) * x * y - sin * z, (1 - cos) * x * z + sin * y], [(1 - cos) * x * y + sin * z, (1 - cos) * y * y + cos, (1 - cos) * y * z - sin * x], [(1 - cos) * x * z - sin * y, (1 - cos) * y * z + sin * x, (1 - cos) * z * z + cos ] ] } /** * Возвращает результат поворота точки вокруг оси относительно центра * @param {number[3]} center Центр поворота * @param {number[3]} axis Ось поворота * @param {number[3]} point Точка * @param {number} angle Угол поворота * @returns {number[3]} */ function RotateCenterAxis3D(center, axis, point, angle) { return Add3D( center, Multiply3D(AxisRotationMatrix(axis, angle), point) ) } /** * Возвращает начальную ось объекта * @param {number[3]} normal Нормаль объекта * @returns {number[3]} */ function ArbitraryAxisX(normal) { if(Math.abs(normal[0]) < 1.0/64.0 && Math.abs(normal[1]) < 1.0/64.0) { var y = [0.0, 1.0, 0.0] return Normalize3D(CrossProduct3D(y, normal)) } else { var z = [0.0, 0.0, 1.0] return Normalize3D(CrossProduct3D(z, normal)) } } /** * Записывает точку в файл геометрии. Возвращает номер точи. * @param {number[3]} point Координаты точки * @returns {number} */ function WritePoint(point) { file.Write("Point(" + ++nPoint + ") = {" + point[0] + ", " + point[1] + ", " + point[2] + "};\n") return nPoint } /** * Записывает линию в файл геометрии. Возвращает номер линии. * @param {number} nStartPoint Номер начальной точки * @param {number} nEndPoint Номер конечной точки * @returns {number} */ function WriteLine(nStartPoint, nEndPoint) { file.Write("Line(" + ++nCurve + ") = {" + nStartPoint + ", " + nEndPoint + "};\n") return nCurve } /** * Записывает круговой сегмент в файл геометрии. Возвращает номер кругового сегмента. * @param {number} nStartPoint Номер начальной точки * @param {number} nCenterPoint Номер точки центра круга * @param {number} nEndPoint Номер конечной точки * @returns {number} */ function WriteCircle(nStartPoint, nCenterPoint, nEndPoint) { file.Write("Circle(" + ++nCurve + ") = {" + nStartPoint + ", " + nCenterPoint + ", " + nEndPoint + "};\n") return nCurve } /** * Записывает контур в файл геометрии. Возвращает номер контура. * @param {number[]} nCurves Массив номеров сегментов контура * @returns {number} */ function WriteCurveLoop(nCurves) { file.Write("Curve Loop(" + ++nCurveLoop + ") = {" + nCurves + "};\n") return nCurveLoop } /** * Записывает плоскую поверхность в файл геометрии. Возвращает номер поверхности. * @param {number} nCurveLoop Номер контура поверхности * @returns {number} */ function WritePlaneSurface(nCurveLoop) { file.Write("Plane Surface(" + ++nSurface + ") = {" + nCurveLoop + "};\n") return nSurface } /** * Экспортирует точку в файл геометрии * @param {AcDbPoint} point Точка */ function ExportPoint(point) { WritePoint(Utility.CreateSafeArrayFromVector(point.Coordinates).toArray()) } /** * Экспортирует отрезок в файл геометрии * @param {AcDbLine} line Отрезок */ function ExportLine(line) { WriteLine( WritePoint(Utility.CreateSafeArrayFromVector(line.StartPoint).toArray()), WritePoint(Utility.CreateSafeArrayFromVector(line.EndPoint).toArray()) ) } /** * Возвращает направление из центра на первую точку круга * @param {number[3]} normal Нормаль круга * @returns {number[3]} */ function CircleDirection1(normal) { if (normal[0] == 0) // Если нормаль в плоскости YOZ - направление вдоль Х return [1.0, 0.0, 0.0] if (normal[1] == 0) // Если нормаль в плоскости XOZ - направление вдоль Y return [0.0, 1.0, 0.0] // В остальных случаях - в плоскости XOY перпендикулярно нормали if (normal[0] / normal[1] <= 1) { var k = normal[0] / normal[1] var L = Math.sqrt(1 + k * k) return [1/L, -k/L, 0.0] } else { var k = normal[1] / normal[0] var L = Math.sqrt(1 + k * k) return [-k/L, 1/L, 0.0] } } /** * Возвращает направление из центра на вторую точку круга * @param {number[3]} normal Нормаль круга * @param {number[3]} direction1 Направление на первую точку * @returns {number[3]} */ function CircleDirection2(normal, direction1) { return CrossProduct3D(normal, direction1) } /** * Возвращает направление из центра на третью точку круга * @param {number[3]} direction1 Направление на первую точку * @returns {number[3]} */ function CircleDirection3(direction1) { return Scale3D(-1, direction1) } /** * Возвращает направление из центра на четвертую точку круга * @param {number[3]} direction2 Направление на вторую точку * @returns {number[3]} */ function CircleDirection4(direction2) { return Scale3D(-1, direction2) } /** * Экспортирует круг в файл геометрии * @param {AcDbCircle} circle Круг */ function ExportCircle(circle) { var center = Utility.CreateSafeArrayFromVector(circle.Center).toArray() var normal = Utility.CreateSafeArrayFromVector(circle.Normal).toArray() var R = circle.Radius // Запись в виде четырех дуговых сегментов var direction1 = CircleDirection1(normal) var direction2 = CircleDirection2(normal, direction1) var direction3 = CircleDirection3(direction1) var direction4 = CircleDirection4(direction2) var point1 = Add3D(center, Scale3D(R, direction1)) var point2 = Add3D(center, Scale3D(R, direction2)) var point3 = Add3D(center, Scale3D(R, direction3)) var point4 = Add3D(center, Scale3D(R, direction4)) var nPointCenter = WritePoint(center) var nPoint1 = WritePoint(point1) var nPoint2 = WritePoint(point2) var nPoint3 = WritePoint(point3) var nPoint4 = WritePoint(point4) WriteCircle(nPoint1, nPointCenter, nPoint2) WriteCircle(nPoint2, nPointCenter, nPoint3) WriteCircle(nPoint3, nPointCenter, nPoint4) WriteCircle(nPoint4, nPointCenter, nPoint1) } /** * Возвращает точку центра круга дугового сегмента полилинии в объектных координатах * @param {number[2]} vertex1 Первая вешшина сегмента * @param {number[2]} vertex2 Вторая вершина сегмента * @param {number} bulge Выпуклость сегмента * @returns {number[2]} */ function ArcSegmentCenterVertex(vertex1, vertex2, bulge) { var L = Length2D(Substract2D(vertex2, vertex1)) var H = L / 4 * (1 / bulge - bulge) return [ (vertex1[0] + vertex2[0]) / 2 - (vertex2[1] - vertex1[1]) * H / L, (vertex1[1] + vertex2[1]) / 2 + (vertex2[0] - vertex1[0]) * H / L ] } /** * Возвращает среднюю точку дугового сегмента полилинии в объектных координатах * @param {number[2]} vertex1 Первая вешшина сегмента * @param {number[2]} vertex2 Вторая вершина сегмента * @param {number} bulge Выпуклость сегмента * @returns {number[2]} */ function ArcSegmentMiddleVertex(vertex1, vertex2, bulge) { var L = Length2D(Substract2D(vertex2, vertex1)) var S = L * bulge / 2 return [ (vertex1[0] + vertex2[0]) / 2 + (vertex2[1] - vertex1[1]) * S / L, (vertex1[1] + vertex2[1]) / 2 - (vertex2[0] - vertex1[0]) * S / L ] } /** * Экспортирует полилинию в файл геометрии * @param {AcDbPolyline} polyline Полилиния */ function ExportPolyline(polyline) { var nv = (Utility.CreateSafeArrayFromVector(polyline.Coordinates).ubound() + 1) / 2 var iFirst = 0 var iLast = (polyline.Closed) ? nv - 1 : nv - 2 var vertexFirst, vertex1, vertex2 var nPointFirst, nPoint1, nPoint2 var nCurves = [] // Список номеров сегментов для записи поверхности for (var iSegment = iFirst; iSegment <= iLast; iSegment++) { if (iSegment == iFirst) { // Для первого сегмента первая точка записываетя в файл vertex1 = vertexFirst = Utility.CreateSafeArrayFromVector(polyline.Coordinate(iSegment)).toArray() nPoint1 = nPointFirst = WritePoint(OCSarrayToWCSarray(vertex1, polyline.Elevation, polyline.Normal)) } else { // Для следующих сегментов первая точка - это последняя точка предыдущего сегмента vertex1 = vertex2 nPoint1 = nPoint2 } if (iSegment == iLast && polyline.Closed) { // Для последнего сегмента замкнутой полилинии последняя точка - это первая точка полилинии vertex2 = vertexFirst nPoint2 = nPointFirst } else { // Для остальных сегментов последняя точка записывается в файл vertex2 = Utility.CreateSafeArrayFromVector(polyline.Coordinate(iSegment + 1)).toArray() nPoint2 = WritePoint(OCSarrayToWCSarray(vertex2, polyline.Elevation, polyline.Normal)) } var bulge = polyline.GetBulge(iSegment) if (bulge == 0) { // Для прямолинейных сегментов записывается прямая nCurves.push(WriteLine(nPoint1, nPoint2)) } else { // Для криволинейных сегментов записывается дуга var vertexCenter = ArcSegmentCenterVertex(vertex1, vertex2, bulge) var nPointCenter = WritePoint(OCSarrayToWCSarray(vertexCenter, polyline.Elevation, polyline.Normal)) if(Math.abs(bulge) < 0.75) { // Для слабовыпуклых сегментов записывается одна дуга nCurves.push(WriteCircle(nPoint1, nPointCenter, nPoint2)) } else { // Для сильновыпуклых сегментов записываеются две дуги через промежуточную точку var vertexMiddle = ArcSegmentMiddleVertex(vertex1, vertex2, bulge) var nPointMiddle = WritePoint(OCSarrayToWCSarray(vertexMiddle, polyline.Elevation, polyline.Normal)) nCurves.push(WriteCircle(nPoint1, nPointCenter, nPointMiddle)) nCurves.push(WriteCircle(nPointMiddle, nPointCenter, nPoint2)) } } } if (polyline.Closed) // Для замкнутых полилиний записывается плоская поверхность WritePlaneSurface(WriteCurveLoop(nCurves)) } /** * Возвращает точку дуги, заданную углом от начальной оси, в мировых координатах * @param {number[3]} center Центр дуги * @param {number[3]} normal Нормаль дуги * @param {number} radius Радиус дуги * @param {number} angle Угол точки * @returns {number[3]} */ function ArcPointAtAngle(center, normal, radius, angle) { var axisX = ArbitraryAxisX(normal) var point = Scale3D(radius, axisX) return RotateCenterAxis3D(center, normal, point, angle) } /** * Экспортирует дугу в файл геометрии * @param {AcDbArc} arc Дуга */ function ExportArc(arc) { // Дуга делится на сегменты не более прямого угла var nSegments = Math.ceil(2 * arc.TotalAngle / Math.PI) // Дуга, у которой начальный угол больше конечного, строится с обратной стороны var startAngle = arc.StartAngle var endAngle = arc.EndAngle if(startAngle > endAngle) { startAngle -= 2 * Math.PI } var pStart = Utility.CreateSafeArrayFromVector(arc.StartPoint).toArray() var pCenter = Utility.CreateSafeArrayFromVector(arc.Center).toArray() var pEnd = Utility.CreateSafeArrayFromVector(arc.EndPoint).toArray() var normal = Utility.CreateSafeArrayFromVector(arc.Normal).toArray() var iFirstSegment = 0 var iLastSegment = nSegments - 1 var npStart, npEnd, npCenter for(var iSegment = 0; iSegment < nSegments; iSegment++) { if(iSegment == iFirstSegment) { // Для начального сегмента записывается центр и начальная точка дуги npCenter = WritePoint(pCenter) npStart = WritePoint(pStart) } else { // Для остальных сегментов первая точка - это последняя точна предыдущего сегмента npStart = npEnd } if(iSegment == iLastSegment) { // Для последнего сегмента последняя точка - это конечная точка дуги npEnd = WritePoint(pEnd) } else { // Для промежуточных сегментов последняя точка - это дополнительная промежуточная точка дуги var angle = startAngle * (nSegments - iSegment - 1) / nSegments + endAngle * (iSegment + 1) / nSegments npEnd = WritePoint(ArcPointAtAngle(pCenter, normal, arc.Radius, angle)) } WriteCircle(npStart, npCenter, npEnd) } } /** * Экспортирует объект в файл геометрии * @param {AcDbEntity} entity Объект чертежа */ function ExportEntity(entity) { switch (entity.ObjectName) { case "AcDbPoint": ExportPoint(entity) break case "AcDbLine": ExportLine(entity) break case "AcDbCircle": ExportCircle(entity) break case "AcDbPolyline": ExportPolyline(entity) break case "AcDbArc": ExportArc(entity) break } } /** * Возвращает имя файла, полученное от пользователя * @param {Object} fso Объект FileSystemObject * @param {String} defaultDirName Начальный путь для диалогового окна */ function GetFileName(fso, defaultDirName) { var chooseAllowNonexistent = 256 var popupYesNoCancel = 3, popupExclamation = 48 var popupCancel = 2, popupYes = 6, popupNo = 7 var filename = "" var shell = new ActiveXObject("WScript.Shell") for (; ;) { filename = Utility.ChooseFile("file", "GMSH geometry |*.geo|Все файлы|*.*", chooseAllowNonexistent, defaultDirName) if (!filename) return "" if (fso.GetExtensionName(filename).toLowerCase() != "geo") filename += ".geo" if (fso.FileExists(filename)) { var userChoice = shell.Popup(filename + "\r\nФайл уже существует. Заменить?", 0, "Подтвердить сохранение", popupYesNoCancel + popupExclamation) switch (userChoice) { case popupYes: return filename case popupCancel: return "" } } else return filename defaultDirName = fso.GetParentFolderName(filename) } } // Объект доступа к файловой системе var fso = new ActiveXObject("Scripting.FileSystemObject") // Запрос имени файла var defaultDirName = "" var filename = GetFileName(fso, defaultDirName) // Запись файла if (filename) { // Файл геометрии GMSH var file = fso.OpenTextFile(filename, 2, true) // Фильтр выбора объектов var FilterType = [0] var FilterData = ["POINT,LINE,CIRCLE,LWPOLYLINE,ARC"] FilterType = Utility.CreateTypedArrayFromJSArray(2, FilterType) FilterData = Utility.CreateTypedArrayFromJSArray(8, FilterData) // Выбор объектов Utility.Prompt("Экспорт в файл геометрии GMSH") ActiveSelectionSet.SelectOnScreen(FilterType, FilterData) // Экспорт выбранных объектов for (var i = 0; i < ActiveSelectionSet.Count; i++) ExportEntity(ActiveSelectionSet.Item(i)) // Сброс выделения ActiveSelectionSet.Clear() }
|
||
Просмотров: 2077
|
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Различные продукты nanoCAD . Помогите в выборе. | Alexandr_A | Другие CAD системы | 11 | 18.06.2015 12:42 |
Как преобразовать .dwg файл в .txt файл? | BuTeR:D | AutoCAD | 30 | 16.10.2013 10:38 |
"Файл рисунка испорчен" - не та версия Акад или реально нерабочий файл? | Ернат | Разное | 3 | 17.06.2009 09:56 |
Экспорт свойств группы объектов из AutoCAD в текстовый файл | ASh666 | AutoCAD | 2 | 02.06.2009 11:15 |
как пребразовать файл картинку типа pdf в графическй файл dwg& | stas50 | AutoCAD | 6 | 05.05.2009 13:53 |