Получение координат проекции точки на эскизе.

Автор VirRus77, 14.07.22, 16:09:55

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

VirRus77

Добрый день форумчане.
Имеем: эскиз в 3D детали.
Требуется: получить координаты точки (x,y) проекции в эскизе, произвольной точки (x,y,z) которая вычислена программно.
П.С. Без дополнительных построений.

p3452

1. Что делали...?
2. Что не получается...?
(четко и ясно)
3. Ваш код...?
+ Благодарностей: 2

Михаил88

Я когда читал у меня такие же вопросы, как и у р3452 были.

VirRus77

16.07.22, 01:48:23 #3 Последнее редактирование: 16.07.22, 02:02:01 от VirRus77
Код такой:
/// <summary>
/// Получить проекцию точки на эскиз.
/// </summary>
/// <param name="kompas">Объект <see cref="Kompas6API5.KompasObject"/>.</param>
/// <param name="point">Точка от которой надо получить проекцию.</param>
/// <param name="sketch">Эскиз.</param>
/// <returns>Точка проекции на эскиз.</returns>
private static (double x, double y) GetProjection(
Kompas6API5.KompasObject kompas,
(double x, double y, double z) point,
(Kompas6API5.ksSketchDefinition SketchDefinition, ksEntity Sketch) sketch
)
{
// Как получить проекцию точки (point) на эскиз (sketch).
return default;
}

Попробовал такой финт (не работает):
var doc = (ksDocument2D)sketch.SketchDefinition.BeginEdit();
var iSketch = (ISketch)kompas.TransferInterface(sketch.Sketch, ksAPITypeEnum.ksAPI7Dual);
var isComplete = iSketch.Part.Placement.GetPointProjectionToXY(
                point.x,
                point.y,
                point.z,
                out var x,
                out var y
            );
var projection1 = (x, y);
// Проекция грани, которая проецируется в точку. (Эскиз перпендикулярен грани)
var projectionRef = sketch.SketchDefinition.AddProjectionOf(kompas.TransferInterface(edge, ksAPITypeEnum.ksAPI5Auto));
// Точка проекции грани на плоскость.
var projectionPoint = (KompasAPI7.IPoint)drawingGroup.Objects[0];
var projection2 = (projectionPoint.X, projectionPoint.Y);

sketch.SketchDefinition.EndEdit();
if(projection1 != projection2) {
  throw new Exception("Не совпадает.");
}
Не совпадение в целых порядках...

Михаил88

Цитата: VirRus77 от 14.07.22, 16:09:55Добрый день форумчане.
Имеем: эскиз в 3D детали.
Требуется: получить координаты точки (x,y) проекции в эскизе, произвольной точки (x,y,z) которая вычислена программно.
П.С. Без дополнительных построений.

Если я правильно понял задачу то так

kompas_document = application.ActiveDocument
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
iPart7 = kompas_document_3d.TopPart
iModelContainer = kompas_api7_module.IModelContainer(iPart7)
sketchs = iModelContainer.Sketchs
sketch = sketchs.Sketch(0)
kompas_document_2d = sketch.BeginEdit()
isSketch = kompas_document_2d.IsSketch
views_and_layers_manager = kompas_document_2d.ViewsAndLayersManager
views = views_and_layers_manager.Views
active_view = views.ActiveView
drawing_container = kompas_api7_module.IDrawingContainer(active_view)
objects = drawing_container.Objects(kompas6_constants.ksDrPoint)
x = objects.X
y = objects.Y
print(x, y)
sketch.EndEdit()

координаты этой точки я получил
Screenshot_1.bmp
Screenshot_2.bmp
Screenshot_3.bmp

p3452

Вот, где и кто учат такому:
private static (double x, double y) GetProjection(
Kompas6API5.KompasObject kompas,
(double x, double y, double z) point,
(Kompas6API5.ksSketchDefinition SketchDefinition, ksEntity Sketch) sketch
)
???

1. "Эскиз" - это 2D документ.
2. "Проекцию" чего-либо, на "эскиз", получить нельзя.
3. Можно получить "проекцию" на "грань", "плоскость", "поверхность".
4. "Эскиз" - создается на "грани" или "плоскости".
5. Можно получить "проекцию" "3D точки" на плоскость "эскиза".
6. Учесть, что "3D точка" может уже находится на плоскости "эскиза".
Как-то, так... 

Михаил88

16.07.22, 15:34:23 #6 Последнее редактирование: 16.07.22, 16:02:03 от Михаил88
Сначала не совсем понял задачу. У Вас есть некая точка в 3D и Вам нужно получить ее проекцию на плоскость, на которой размещен некий эскиз.
Тогда решение такое.
kompas_document = application.ActiveDocument
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
iPart7 = kompas_document_3d.TopPart
iModelContainer = kompas_api7_module.IModelContainer(iPart7)
sketchs = iModelContainer.Sketchs
sketch = sketchs.Sketch(0)
plane = sketch.Plane

points3D = iModelContainer.Points3D
point_3D = points3D.Point3D(0)
x = point_3D.X
y = point_3D.Y
z = point_3D.Z

iPlane3D = kompas_api7_module.IPlane3D(plane)
iMathSurface3D = iPlane3D.Surface
a = 0
b = 0
print(iMathSurface3D.NearPointProjection(x, y, z, a, b, True))


Screenshot_1.bmp
Screenshot_2.bmp
Screenshot_3.bmp
+ Благодарностей: 1

p3452

Замечательно, как один из вариантов...
Но!
Мы же понимаем, что ТС может запросто заявить, что ЭТО не то, что ему нужно...
Например: ТС заявит, что ему нужно - проверить попадает ли его 3D точка, "которая вычислена программно", на контур эскиза!?
"Халява" - портит людей...

VirRus77

17.07.22, 22:51:56 #8 Последнее редактирование: 17.07.22, 23:44:45 от VirRus77
Цитата: Михаил88 от 16.07.22, 15:34:23Сначала не совсем понял задачу. У Вас есть некая точка в 3D и Вам нужно получить ее проекцию на плоскость, на которой размещен некий эскиз.
Тогда решение такое.
Спасибо. Получилось. Код такой:
/// <summary>
/// Получить проекцию точки на эскиз.
/// </summary>
/// <param name="kompas">Объект <see cref="Kompas6API5.KompasObject"/>.</param>
/// <param name="point">Точка от которой надо получить проекцию.</param>
/// <param name="sketch">Эскиз.</param>
/// <returns>Точка проекции на эскиз.</returns>
private static (double x, double y) GetProjection(
  KompasObject kompas,
  (double x, double y, double z) point,
  (Kompas6API5.ksSketchDefinition SketchDefinition, ksEntity Sketch) sketch
)
{
  var iSketch = (ISketch)kompas.TransferInterface(sketch.Sketch, ksAPITypeEnum.ksAPI7Dual);
  var iFace = (IFace)iSketch.Plane;
  if(!iFace.MathSurface.NearPointProjection(point.x, point.y, point.z, out var u, out var v, false))
  {
    throw new Exception("Не получилось");
  }

  return (u, v);
}

VirRus77

Цитата: p3452 от 16.07.22, 12:17:11Вот, где и кто учат такому:
Вам чем-то не нравится CodeStyle?
Этому не учат, к этому приходят за 14 лет в продуктовой разработке...

П.С. Попробуйте добавить эти строчки в проект. И если он у вас сбилдится, то я вас поздравляю.
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

p3452

Цитата: VirRus77 от 17.07.22, 23:00:18Этому не учат, к этому приходят за 14 лет в продуктовой разработке...
К этому?:
1. Неудобоваримый код - трудности последующего сопровождения.
2. Несоответствие кода постановке задачи - кортеж их трех переменных не есть 3D точка, кортеж из двух переменных не есть 2D точка.
3. Избыточность параметров и
4  мещанина интерфейсов - два параметра API5 использующиеся только для, преобразования к переменной API7.
5. При компиляции кода получите ошибку - в TransferInterface() должно быть три параметра.
6. После исправления первой ошибки - получите еще две...

VirRus77

1. Данный код для быстрого прототипирования.
2. Кортеж был сделан для п.1, и создавать отдельный класс для работы с группой как-то жирновато будет.
3. Параметры оказались не избыточны, а как раз в самый раз.
4. Если часть работы быстрее производить через API5, то не проще его использовать?
5. Не получу, т.к. по документации есть параметры по умолчанию, и если они не вынесены в dll API, Это не значит что я не могу сделать расширение.
И работать напрямую с enum как-то проще, чем кастить каждый раз к int и вспоминать какой enum надо вставлять....
/// <summary>
    /// Расширения для <see cref="KompasObject"/>.
    /// </summary>
    public static class KompasObjectExtensions
    {
        /// <summary>
        /// Преобразовать интерфейсный объект одного типа API в интерфейсный объект API другого типа.
        /// </summary>
        /// <param name="kompas">Интерфейс API КОМПАС.</param>
        /// <param name="value">Интерфейс 3D COM, API5 Auto или API7.</param>
        /// <param name="apiNewType">Тип API, к которому преобразуется исходный интерфейс.</param>
        /// <param name="objNewType">Тип объекта в интерфейсе, к которому преобразуется исходный объект.</param>
        /// <returns>Указатель на интерфейс объекта в API заданного типа.</returns>
        public static object TransferInterface(
            this KompasObject kompas,
            object value,
            ksAPITypeEnum apiNewType,
            ksAPITypeEnum objNewType = ksAPITypeEnum.ksAPIUndef
        )
        {
            return kompas.TransferInterface(value, (int)apiNewType, (int)objNewType);
        }

        /// <summary>
        /// Преобразовать интерфейсный объект одного типа API в интерфейсный объект API другого типа.
        /// </summary>
        /// <param name="kompas">Интерфейс API КОМПАС.</param>
        /// <param name="value">Интерфейс 3D COM, API5 Auto или API7.</param>
        /// <param name="apiNewType">Тип API, к которому преобразуется исходный интерфейс.</param>
        /// <param name="objNewType">Тип объекта в интерфейсе, к которому преобразуется исходный объект.</param>
        /// <returns>Указатель на интерфейс объекта в API заданного типа.</returns>
        public static T? TransferInterface<T>(
            this KompasObject kompas,
            object value,
            ksAPITypeEnum apiNewType,
            ksAPITypeEnum objNewType = ksAPITypeEnum.ksAPIUndef
        )
            where T : class
        {
            return kompas.TransferInterface(value, apiNewType, objNewType) as T;
        }


        /// <summary>
        /// Преобразовать объект по reference из API5 в интерфейсный объект API7.
        /// </summary>
        /// <remarks>
        /// 1. Функция реализована пока для документов и объектов вида графического документа. В остальных случаях возвращается NULL.
        /// 2. Если obj - указатель на документ, параметр doc игнорируется.
        /// 3. Если параметр doc = 0, берется текущий документ.
        /// </remarks>
        /// <param name="kompas">Интерфейс API КОМПАС.</param>
        /// <param name="refObject">Указатель на объект в API5.</param>
        /// <param name="docRef">Указатель на документ, где находится объект.</param>
        /// <returns></returns>
        public static object TransferReference(this KompasObject kompas, int refObject, int docRef = 0)
        {
            return kompas.TransferReference(refObject, docRef);
        }
    }
6. По второй ошибке, не понял...

p3452

Доводы - разумные, что уже радует ("В нашем полку, прибыло!").
Хотя, можно было и так (ИМХО):
Point3D_Point2D_Sketch.png

Цитата: VirRus77 от 18.07.22, 14:44:006. По второй ошибке, не понял...
Исправление ошибок.png


VirRus77

Добавьте мой код расширения (public static class KompasObjectExtensions) отдельным файлом в проект. И получите счастье  :beer:
Безымянный.png

p3452

Цитата: VirRus77 от 18.07.22, 17:50:52Добавьте мой код расширения (public static class KompasObjectExtensions) отдельным файлом в проект.
Так мне ЭТО ненужно - интерфейсы не смешиваю...