Вобщем суть проблемы создаю 3х мерную дугу по радиусу и центру
Код:
IArc3DPtr Create3DArc(IKompasDocumentPtr & doc, IPoint3DPtr point_1,IPoint3DPtr point_2, double radius, IModelObjectPtr plane_ent)
{
IArc3DPtr arc3D = NULL;
// Получаем 3D документ
IKompasDocument3DPtr doc3D(doc);
IPart7Ptr part ( doc3D->TopPart );
if (part)
{
IAuxiliaryGeomContainerPtr auxCont(GetAuxiliaryGeomContainer(doc));
if (auxCont)
{
IArcs3DPtr arcsCol(auxCont->GetArcs3D());
arc3D = arcsCol->Add();
if (arc3D)
{
if(point_1 && point_2 && plane_ent)
{
arc3D->PutBuildingType( ksArc3DByCentre);
arc3D->PutBuildingObject(plane_ent);
arc3D->PutAssociationObject(ksArc3DCenter, part->GetDefaultObject(o3d_pointCS));
arc3D->PutAssociationObject(ksArc3DPoint1, point_1);
arc3D->PutAssociationObject(ksArc3DPoint2, point_2);
arc3D->PutDirection(false);
arc3D->put_Radius(radius);
arc3D->Update();
}
}
}
}
return arc3D;
}
В итоге точка 2 определяется с нулевым углом и дуга рисуется неправильно. Что я делаю не так?
Судя из кода должно быть ksArc3DByPoints - по трем точкам, а у Вас ksArc3DByCentre - по центру, углам и плоскости.
А как можно получить угол по точке(В сферической системе координат)? Грубо говоря две точки лежат на сфере их надо соедеинить дугой с радиусом сферы. И вроде в перечислении ksArc3DPoint1 = 1, что соответствует первому углу, а ksArc3DPoint2 = 2 второму.
А Вы не пробовали построить, по двум точкам и направлению.
arc3D->PutBuildingType(ksArc3DByDirrection);
arc3D->PutAssociationObject(ksArc3DPoint1, point_1);
arc3D->PutAssociationObject(ksArc3DPoint2, point_2);
arc3D->PutDirection(false);
arc3D->put_Radius(radius);
arc3D->Update();
Углам соответствуют свойства Angle1 и Angle2.
Нет не пробовал, завтра попробую.
Судя по перечислению
ksArc3DParameterEnum
{
ksArc3DCenter = 0,
ksArc3DPoint1 = 1,
ksArc3DPoint2 = 2,
ksArc3DPoint3 = 3,
ksArc3DAngle1 = 1,
ksArc3DAngle2 = 2,
ksArc3DRadius = 3
};
это одно и то же
Лучше использовать свойства напрямую, без буфера.
Хотя у Вас arc3D->PutAssociationObject(ksArc3DPoint1, point_1);, а должно быть
arc3D->PutAssociationObject(ksArc3DAngle1, point_1);, тогда, если я логику правильно понимаю, Компас считает угол сам, между центром и точкой.
arc3D->PutAssociationObject(ksArc3DAngle1, point_1); что arc3D->PutAssociationObject(ksArc3DPoint1, point_1); если я правильно понимаю в функцию передастся arc3D->PutAssociationObject(ksArc3DParameterEnum(1), point_1); так что особой разницы не вижу
Спорить не буду.
завтра попробую ваш вариант о результатах напишу. Еще вопрос как можно указать 3D точку как центр эскиза? Или просто получить координаты 3х мерной точки в координатах эскиза?
Если можно, картинку прикрепите, чтобы видеть с чего нужно информацию получить.
вот картинки проблемы, не цепляет точку заданную arc3D->PutAssociationObject( ksArc3DAngle1 , point_1);
Причем если задаешь просто значениями углов то все нормально строит а объект цеплять не хочет.
вот параметры созданной дуги
А можно посмотреть, как Вы получаете point_1?
IPoint3DPtr CreatePoint( IKompasDocumentPtr & doc, double a, double b, double r, wstring name = NULL )
{
IPoint3DPtr newPoint = NULL;
// Получаем 3D документ
IKompasDocument3DPtr doc3D(doc);
IPart7Ptr part ( doc3D->TopPart );
if(part)
{
// Получаем контейнер модельных объектов
IModelContainerPtr modelCont( GetModelContainer(doc) );
if ( modelCont )
{
// Получаем коллекцию точек
IPoints3DPtr pointsColl( modelCont->GetPoints3D() );
if ( pointsColl )
{
// Добавляем новую точку
newPoint = pointsColl->Add();
if ( newPoint )
{
// Задаем параметры точки
newPoint->put_Name((BSTR)name.c_str());
newPoint->Symbol = ksDotPoint;
newPoint->ParameterType = ksPSphericCoord;
IPoint3DParamBySpherePtr param = newPoint->Parameters;
param->A = a;
param->B = b;
param->R = r;
newPoint->Update();
}
}
}
}
return newPoint;
пробовал передавать в первый угол вторую точку а во второй первую. Все равно первый угол не подцепляет.
Установить опорный объект для вершины - PutAssociationObject.
Тип данных: указатель на интерфейс IModelObject.
У Вас point_1 - IPoint3D, разницу улавливаете, Вам необходимо IPoint3D преобразовать в IModelObject.
ModelObject:=Point3D as IModelObject;
ну а почему тогда вторую точку подцепляет?
Показывайте окно отладчика, чтобы видеть, на виртуальный вопрос я ответить не смогу, откуда я знаю, что у Вас в коде поменялось.
Причем при построении дуги по двум точкам и направлению или по трем точкам дуги строятся корректно. Причем класс IPoint3D наследуется от IModelObject
struct __declspec(uuid("d71aedbe-01d4-4c7d-96dc-94981f2a1c37"))
IPoint3D : IModelObject
хотя может я и неправ
Смотрим разницу.
IModelObject - Базовый интерфейс для всех модельных объектов, его размер в памяти меньше, чем интерфейс который его наследует.
изменил код на
IArc3DPtr Create3DArc(IKompasDocumentPtr & doc, IPoint3DPtr point_1,IPoint3DPtr point_2, double radius, IModelObjectPtr plane_ent)
{
IArc3DPtr arc3D = NULL;
// Получаем 3D документ
IKompasDocument3DPtr doc3D(doc);
IPart7Ptr part ( doc3D->TopPart );
if (part)
{
IAuxiliaryGeomContainerPtr auxCont(GetAuxiliaryGeomContainer(doc));
if (auxCont)
{
IArcs3DPtr arcsCol(auxCont->GetArcs3D());
arc3D = arcsCol->Add();
if (arc3D)
{
if(point_1 && point_2 && plane_ent)
{
arc3D->PutBuildingType( ksArc3DByCentre);
arc3D->PutBuildingObject(plane_ent);
arc3D->PutAssociationObject(ksArc3DCenter, part->GetDefaultObject(o3d_pointCS));
IModelObjectPtr obj_1(point_1);
IModelObjectPtr obj_2(point_2);
arc3D->PutAssociationObject(ksArc3DAngle1, obj_1);
arc3D->PutAssociationObject(ksArc3DAngle2, obj_2);
//arc3D->PutClosed(TRUE);
arc3D->PutDirection(false);
arc3D->PutRadius(radius);
arc3D->Update();
}
}
}
}
return arc3D;
}
та же фигня
arc3D->PutBuildingType(ksArc3DByDirrection);
строит дугу неправильно
дебаг случайно прикрепил
Радиус соответствует, радиусу сферы?
P.S. Если картинки прикрепляете, то не уменьшайте пожалуйста, я глаза ломать не буду.
да
максимальный размер одного файла — 200 Кбайт больше не прикрепляются, поэтому и приходится уменьшать
В 200 Кб можно много нужного показать и вырезать ненужное.
Мне нужны значения в числах, всех параметров участвующих в операции, но разбираться буду завтра, после всей работы по дому.
прошу прощения
Вы меня извините тоже, я разбираюсь в форматах, но зачем мне адреса Ваших переменных, если я к ним обращусь, то даже подумать боюсь, куда меня Windows пошлёт.
Радиус Вашей дуги 11 мм, а радиус сферы, явно больше и он у Вас не показан.
радиус сферы тоже 11
ISketchPtr sketch( CreateSketch(doc, 0, 0, 11, 90) );
ISketchPtr CreateSketch( IKompasDocumentPtr & doc, double x, double y, double r, double angle )
{
ISketchPtr new_sketch = NULL;
if ( doc )
{
IModelContainerPtr modelCont( GetModelContainer(doc) );
if ( modelCont )
{
// Получаем коллекцию эскзиов
ISketchsPtr sketchs( modelCont->GetSketchs() );
if ( sketchs )
{
// Добавляем новый эскиз
new_sketch = sketchs->Add();
if (new_sketch)
{
// Получаем 3D документ
IKompasDocument3DPtr doc3D(doc);
if (doc3D)
{
// Получаем верхнюю деталь
IPart7Ptr part ( doc3D->TopPart );
if ( part )
{
// Получаем плоскость XY
IModelObjectPtr planeXY ( part->GetDefaultObject(o3d_planeXOY) );
// Задаем базовую плоскость для эскиза
new_sketch->Plane = planeXY;
// Редактируем эскиз
new_sketch->BeginEdit();
ArcByAngle(x, y, r, 180, 0, 1, 1);
LineSeg( -r, 0, r, 0, 3 );
new_sketch->EndEdit();
}
}
new_sketch->Update();
}
}
}
}
return new_sketch;
}
при построении дуги по двум точкам и направлению по моему радиус вообще не задается
Цитироватьпри построении дуги по двум точкам и направлению по моему радиус вообще не задается
Дуга превращается в отрезок, если радиус не задаётся, мне сейчас Вашим вопросом заниматься некогда, так, что спокойной ночи, а у меня ещё есть работа.
так даже средствами Компас при построении такого типа дуги радиус не задается, а задаются только две точки и направление касательного вектора в точке дуги. Так что я подозреваю что радиус который я передаю при таком типе построения не используется.
если только как вариант строить две плоскости:
1. Через две точки и начало координат
2. Касательную к сфере в одной из точек
3. И ось по пересечению плоскостей
А затем указывать эту ось в качестве направляющей.
Но хотелось б именно строить через центр и радиус
Но хотелось б именно строить через центр и радиус
Всё тоже самое, указываем центр окружности, базовую плоскость проекции радиуса, начальную и конечную точку, радиус посчитается автоматически.
При попытке строить дугу ksArc3DByCentre без указания радиуса получаем вот такое сообщение;
Код.
да все то же самое что и было только без радиуса
arc3D->PutBuildingType( ksArc3DByCentre);
arc3D->PutBuildingObject(plane_ent);
arc3D->PutAssociationObject(ksArc3DCenter, part->GetDefaultObject(o3d_pointCS));
IModelObjectPtr obj_1 = point_1;
IModelObjectPtr obj_2 = point_2;
arc3D->PutAssociationObject(ksArc3DAngle1, obj_1);
arc3D->PutAssociationObject(ksArc3DAngle2, obj_2);
//arc3D->PutClosed(TRUE);
arc3D->PutDirection(false);
//arc3D->PutRadius(radius);
arc3D->Update();
такое ощущение что ошибка именно в интерфейсе IArc3D
Точка центра, начала и конца дуги, принадлежат плоскости plane_ent?
Также базовая плоскость, при arc3D->PutBuildingType(ksArc3DByDirrection); не проходит через центр сферы и 2 точки, т.е., чтобы доказать, что такое ощущение что ошибка именно в интерфейсе IArc3D, нужны все координаты объектов в пространстве.
плоскость построена через эти две точки и начало координат
ksEntityPtr CreatePlaneCsAnd2Point(ksDocument3DPtr& ksDoc, ksEntityPtr point1_ent, ksEntityPtr point2_ent)
{
ksEntityPtr plane_ent = NULL;
ksPartPtr part(ksDoc->GetPart(pTop_Part));
if (part)
{
//создаем плоскость
plane_ent = part->NewEntity(o3d_plane3Points);
if (plane_ent)
{
ksPlane3PointsDefinitionPtr plane_def(plane_ent->GetDefinition());
plane_def->SetPoint(1, part->GetDefaultEntity(o3d_pointCS));
plane_def->SetPoint(2, point1_ent);
plane_def->SetPoint(3, point2_ent);
plane_ent->hidden = TRUE;
plane_ent->Create();
}
}
return plane_ent;
}
Можете модель прикрепить, которая у Вас получилась.
вот такая вот вещь получается
Мне нужен файл m3d, а не картинка.
вот деталь
Попробуйте сделать так
arc3D->PutAssociationObject(ksArc3DPoint2, obj_1);
arc3D->PutAssociationObject(ksArc3DPoint3, obj_2);
вместо
arc3D->PutAssociationObject(ksArc3DAngle1, obj_1);
arc3D->PutAssociationObject(ksArc3DAngle2, obj_2);
Сделал пример похоже ошибка в интерфейсе, а точнее третью точку операции воспринимает, как радиус, из за того, что глупо тип определён.
P.S. Запишу, как ошибку в БОиП.
ну да я тоже на это обратил внимание, но он почему то игнорит точку передаваемую с параметром ksArc3DPoint1 вторую и третью(она же радиус) цепляет
так и пришлось строить дугу через две точки и направляющую, так дуга рисуется без проблем
В Компас V15, ошибку исправили.
Тестовая процедура.
//==============================================================================
procedure Shara;
var
X:Double;
pDocuments:IDocuments;
pDocument:IKompasDocument;
Doc3D:IKompasDocument3D;
pPart7:IPart7;
pModelContainer:IModelContainer;
pSketchs:ISketchs;
pSketch:ISketch;
Plane,pModelObject:IModelObject;
pRotateds:IRotateds;
pRotated:IRotated;
pThinParameters:IThinParameters;
pPoints3D:IPoints3D;
pPoint1,pPoint2:IPoint3D;
pDoc3DApi5:IDocument3D;
pPart:IPart;
pEntity,pEntity1,pEntity2,pEntity3:IEntity;
Plane3Points:IPlane3PointsDefinition;
pAuxiliaryGeomContainer:IAuxiliaryGeomContainer;
pArcs3D:IArcs3D;
pArc3D:IArc3D;
Disp:=IDispatch;
begin
Disp:=IDispatch(CreateKompasApplication);
NewKompasApi:=Disp as IApplication;
if NewKompasApi<>nil then pDocuments:=NewKompasApi.Documents;
if pDocuments<>nil then pDocument:=pDocuments.Add(ksDocumentPart,True);
if pDocument<>nil then Doc3D:=pDocument as IKompasDocument3D;
if Doc3D<>nil then pPart7:=Doc3D.TopPart;
if pPart7<>nil then
begin
pModelContainer:=pPart7 as IModelContainer;
if pModelContainer<>nil then
begin
pSketchs:=pModelContainer.Sketchs;
if pSketchs<>nil then pSketch:=pSketchs.Add;
if pSketch<>nil then
begin
Plane:=pPart7.DefaultObject[o3d_planeXOY];
if Plane<>nil then pSketch.Plane:=Plane;
pSketch.BeginEdit;
ArcByPoint(0,0,11,0,11,0,-11,0,1);
LineSeg(0,11,0,-11,3);
pSketch.EndEdit;
pSketch.Hidden:=True;
pSketch.Update;
end;
pRotateds:=pModelContainer.Rotateds;
if pRotateds<>nil then pRotated:=pRotateds.Add(o3d_bossRotated);
if pRotated<>nil then
begin
pRotated.Profile:=pSketch as IModelObject;
pRotated.ToroidShapeType:=False;
pRotated.Angle[True]:=360;
pThinParameters:=pRotated as IThinParameters;
if pThinParameters<>nil then pThinParameters.Thin:=False;
pRotated.Update;
end;
X:=Sqrt((11*11)/3);
pPoints3D:=pModelContainer.Points3D;
if pPoints3D<>nil then
begin
pPoint1:=pPoints3D.Add;
if pPoint1<>nil then
begin
pPoint1.ParameterType:=ksPParamCoord;
pPoint1.X:=X;
pPoint1.Y:=X;
pPoint1.Z:=X;
pPoint1.Update;
end;
pPoint2:=pPoints3D.Add;
if pPoint2<>nil then
begin
pPoint2.ParameterType:=ksPParamCoord;
pPoint2.X:=X;
pPoint2.Y:=-X;
pPoint2.Z:=X;
pPoint2.Update;
end;
end;
pDoc3DApi5:=IUnknown(ksTransferInterface(LtDefine.PIUnknown(Doc3D),ksAPI3DCom,0)) as IDocument3D;
if pDoc3DApi5<>nil then pPart:=IPart(pDoc3DApi5.GetPart(pTop_Part));
pEntity:=IEntity(pPart.NewEntity(o3d_plane3Points));
if pEntity<>nil then Plane3Points:=IUnknown(pEntity.GetDefinition) as IPlane3PointsDefinition;
if Plane3Points<>nil then
begin
pEntity1:=IUnknown(ksTransferInterface(LtDefine.PIUnknown(pPoint1 as IModelObject),ksAPI3DCom,o3d_entity)) as IEntity;
pEntity2:=IUnknown(ksTransferInterface(LtDefine.PIUnknown(pPoint2 as IModelObject),ksAPI3DCom,o3d_entity)) as IEntity;
pEntity3:=IUnknown(ksTransferInterface(LtDefine.PIUnknown(pPart7.DefaultObject[o3d_pointCS]),ksAPI3DCom,o3d_entity)) as IEntity;
if pEntity1<>nil then Plane3Points.SetPoint(1,pEntity1);
if pEntity2<>nil then Plane3Points.SetPoint(2,pEntity2);
if pEntity3<>nil then Plane3Points.SetPoint(3,pEntity3);
pEntity.Update;
end;
pAuxiliaryGeomContainer:=pPart7 as IAuxiliaryGeomContainer;
if pAuxiliaryGeomContainer<>nil then pArcs3D:=pAuxiliaryGeomContainer.Arcs3D;
if pArcs3D<>nil then pArc3D:=pArcs3D.Add;
if pArc3D<>nil then
begin
pArc3D.BuildingType:=ksArc3DByCentre;
pArc3D.Direction:=True;
pArc3D.AssociationObject[ksArc3DCenter]:=pPart7.DefaultObject[o3d_pointCS];
pModelObject:=IUnknown(ksTransferInterface(LtDefine.PIUnknown(pEntity),ksAPI7Dual,0)) as IModelObject;
if pModelObject<>nil then pArc3D.BuildingObject:=pModelObject;
pArc3D.AssociationObject[ksArc3DAngle1]:=pPoint1 as IModelObject;
pArc3D.AssociationObject[ksArc3DAngle2]:=pPoint2 as IModelObject;
pArc3D.AssociationObject[ksArc3DRadius]:=pPoint2 as IModelObject;
pArc3D.Update;
end;
end;
end;
end;
//==============================================================================
это хорошая новость, будем ждать 15 версию
немного оффтоп где можно найти step13 из примеров? (у меня 12 заканчивается)
И имеется ли возможность единожды созданный эскиз размножить по нескольким плоскостям.
У меня также, Компас V15.