Тема: Izmenenije koordinat Acad objektov

Daragoj  Александр Ривилис, spasibo tebe za pomosc izmeniaja koordinati 3D polilinii, s textom, Arc, circle, Block, line, ia spravisa, s 3D plogodoria tebe toze, no ostalsia Spline i Polyline, mne nuzno sdelat toze samoje i snimi, I deja mojej raboti tokaja, predstav sebe odnu ploliliniju, ana ne priamaja a spavarotami okolo nejo mnogo vsiakix Acad objektoj, ia etu poliliniju delaju pramuju i vse objekti ia postovliaju(clone) vokrug nejo, s tem ze rastojianjen at nejo kak i bila do tago kakda ona bila ne pramaja, tak ia dolzen izmenit vse koordinati kazdoj tocki, v liniji, polyline spline ... mozet est medod kak eto sdelat neaotliciaja kokoj etot objekt?
Spasibo
Darius

Re: Izmenenije koordinat Acad objektov

> Darius
Спасибо за дорогой! :)
1) Очень тебя прошу если не можешь писать русскими буквами используй тэг [rus]tvoi text na latinice[/rus] и проверяй что получилось. У меня нет времени заниматься дешифровкой твоего текста. Тем более, что половину я не понял. :(
2) Если я правильно понял то, что тебе нужно, то форма всех этих объектов сохраняется в точности и тебе их нужно просто перенести из одной точки в другую. В этом случае вне зависимости от типа примитива ты можешь воспользоваться методом transformBy():

static void Move(void)
{
  ads_point p;
  ads_name  ent;
  if (acedEntSel("\nВыберите примитив для переноса: ",ent,p) == RTNORM)
  {
    AcDbObjectId id; acdbGetObjectId(id,ent);
    AcDbObjectPointer<AcDbEntity> pEnt(id,AcDb::kForRead);
    if (pEnt.openStatus() == Acad::eOk)
    {
      AcGePoint3d p1,p2;
      if (acedGetPoint(NULL,"\nУкажите точку \"откуда\": ",asDblArray(p1)) &&
          acedGetPoint(asDblArray(p1),"\nУкажите точку \"куда\": ",asDblArray(p2)))
      {
        acdbUcs2Wcs(asDblArray(p1),asDblArray(p1),false);
        acdbUcs2Wcs(asDblArray(p2),asDblArray(p2),false);
        AcGeMatrix3d mat; mat.setToTranslation(p2-p1);
        AcGeVector3d norm;
        if (pEnt->upgradeOpen() == Acad::eOk)
        {
          AcDbDimension *pDim = AcDbDimension::cast(pEnt.object());
          if (pDim) norm = pDim->normal();
          pEnt->transformBy(mat);
          if (pDim) pDim->setNormal(norm);
        }
      }
    }
  }
}

Re: Izmenenije koordinat Acad objektov

> Александр Ривилис
P.S.: Если же геометрия объекта должна изменится, то тогда тебе придется работать отдельно с каждым типом примитива - общего метода нет.

Re: Izmenenije koordinat Acad objektov

как понимаю это тоже самое что команда Acad Move, а мне нада изменит все координаты индивидуалъно как и в примере с 3Dpolyline мне никак неудаютса сделатъ с 2Dpolyline и Spline Спасиба

Re: Izmenenije koordinat Acad objektov

Все координаты ты изменить не можешь. Можешь изменить только координаты вершин.
Потестируешь сам:

//
//  Функция возвращает количество вершин полилинии
//
static int GetNumberOfVertexies(AcDbEntity *pEnt)
{
  int nVertex = 0;
  AcDbPolyline   *pPline   = AcDbPolyline::cast(pEnt);
  AcDb2dPolyline *p2dPline = AcDb2dPolyline::cast(pEnt);
  AcDb3dPolyline *p3dPline = AcDb3dPolyline::cast(pEnt);
  if (!p2dPline && !p3dPline && !pPline) return -1;
  if (pPline) return pPline->numVerts();
  AcDbObjectIterator *pVertIter = NULL;
  if (p2dPline) pVertIter= p2dPline->vertexIterator();
        else    pVertIter= p3dPline->vertexIterator();
  if (pVertIter)  {
    for (pVertIter->start();!pVertIter->done();pVertIter->step())
      nVertex++;
    delete pVertIter;
  }
  return nVertex;
}
//
//  Функция возвращает положение в WCS вершины, заданной номером
//
static AcGePoint3d GetVertexPosition(AcDbEntity *pEnt, int iVertex)
{
  AcGePoint3d p = AcGePoint3d(-1e+128,-1e+128,-1e+128);
  AcDbPolyline   *pPline   = AcDbPolyline::cast(pEnt);
  AcDb2dPolyline *p2dPline = AcDb2dPolyline::cast(pEnt);
  AcDb3dPolyline *p3dPline = AcDb3dPolyline::cast(pEnt);
  if (!p2dPline && !p3dPline && !pPline) return p;
  // Это простая полилиния
  if (pPline && pPline->numVerts() > iVertex && iVertex >= 0)  {
    pPline->getPointAt(iVertex,p);
  } else if (p2dPline) {
    AcDbObjectIterator *pVertIter= p2dPline->vertexIterator();
    if (!pVertIter) return p;
    int i = 0;
    for (pVertIter->start();!pVertIter->done();pVertIter->step(),i++) {
      if (i == iVertex) {
        AcDbObjectPointer<AcDb2dVertex> pVert(pVertIter->objectId(),AcDb::kForRead);
        if (pVert.openStatus() == Acad::eOk) {
          AcDb::Planarity typePlan;
          AcGePlane plan; p2dPline->getPlane(plan,typePlan);
          AcGeMatrix3d matECS = AcGeMatrix3d::planeToWorld(plan);
          p = pVert->position().transformBy(matECS);
        }
      }
    }
    delete pVertIter;
  } else if (p3dPline) {
    AcDbObjectIterator *pVertIter= p3dPline->vertexIterator();
    if (!pVertIter) return p;
    int i = 0;
    for (pVertIter->start();!pVertIter->done();pVertIter->step(),i++) {
      if (i == iVertex) {
        AcDbObjectPointer<AcDb3dPolylineVertex> pVert(pVertIter->objectId(),AcDb::kForRead);
        if (pVert.openStatus() == Acad::eOk) {
          p = pVert->position();
        }
      }
    }
    delete pVertIter;
  }
  return p;
}
//
//  Функция устанавливает вершину (заданную номером) в заданную в WCS координату
//
static void SetVertexPosition(AcDbEntity *pEnt, int iVertex, AcGePoint3d newPos)
{
  AcGePoint3d p = AcGePoint3d(-1e+128,-1e+128,-1e+128);
  AcDbPolyline   *pPline   = AcDbPolyline::cast(pEnt);
  AcDb2dPolyline *p2dPline = AcDb2dPolyline::cast(pEnt);
  AcDb3dPolyline *p3dPline = AcDb3dPolyline::cast(pEnt);
  if (!p2dPline && !p3dPline && !pPline) return;
  // Это простая полилиния
  if (pPline && pPline->numVerts() > iVertex && iVertex >= 0)  {
    AcGeMatrix3d matECS; pPline->getEcs(matECS);
    matECS.invert();
    AcGePoint3d pECS = newPos.transformBy(matECS);
    bool isWriteEnabled = pPline->isWriteEnabled();
    if (!isWriteEnabled) pPline->upgradeOpen();
    pPline->setPointAt(iVertex,AcGePoint2d(pECS[X],pECS[Y]));
    if (!isWriteEnabled) pPline->downgradeOpen();
  } else if (p2dPline) {
    AcDbObjectIterator *pVertIter= p2dPline->vertexIterator();
    if (!pVertIter) return;
    int i = 0;
    for (pVertIter->start();!pVertIter->done();pVertIter->step(),i++) {
      if (i == iVertex) {
        AcDbObjectPointer<AcDb2dVertex> pVert(pVertIter->objectId(),AcDb::kForWrite);
        if (pVert.openStatus() == Acad::eOk) {
          AcDb::Planarity typePlan;
          AcGePlane plan; p2dPline->getPlane(plan,typePlan);
          AcGeMatrix3d matECS = AcGeMatrix3d::worldToPlane(plan);
          AcGePoint3d pECS = newPos.transformBy(matECS);
          pVert->setPosition(pECS);
          delete pVertIter;
          return;
        }
      }
    }
    delete pVertIter;
  } else if (p3dPline) {
    AcDbObjectIterator *pVertIter= p3dPline->vertexIterator();
    if (!pVertIter) return;
    int i = 0;
    for (pVertIter->start();!pVertIter->done();pVertIter->step(),i++) {
      if (i == iVertex) {
        AcDbObjectPointer<AcDb3dPolylineVertex> pVert(pVertIter->objectId(),AcDb::kForWrite);
        if (pVert.openStatus() == Acad::eOk) {
          pVert->setPosition(newPos);
          delete pVertIter;
          return;
        }
      }
    }
    delete pVertIter;
  }
}
//
// Главная функция для переноса вершины полилинии:
//
static void MoveVertex(void)
{
  ads_point p; ads_name  entPoly;
  if (acedEntSel("\nВыберите кривую (AcDbPolyline,AcDb2dPolyline,AcDb3dPolyline): ", entPoly, p) != RTNORM)  return;
  AcDbObjectId pObjId;
  if (acdbGetObjectId(pObjId,entPoly) != Acad::eOk) return;
  AcDbObjectPointer<AcDbCurve> poly(pObjId,AcDb::kForRead);
  if (poly.openStatus() != Acad::eOk) return;
  AcDb2dPolyline *p2dPline = AcDb2dPolyline::cast(poly.object());
  AcDb3dPolyline *p3dPline = AcDb3dPolyline::cast(poly.object());
  AcDbPolyline   *pPline   = AcDbPolyline::cast(poly.object());
  // Если это не полилиния - завершение
  if (!pPline && !p2dPline && !p3dPline) {
    acutPrintf("\nЭто не полилиния!");
    return;
  }
  int nVertex = GetNumberOfVertexies(poly.object()), iVertex = 1;
  char buf[256]; sprintf(buf,"\nУкажите номер перемещаемой вершины (1-%d) <1>: ",nVertex);
  if (acedGetInt(buf,&iVertex) == RTCAN) return;
  if (iVertex < 1 || iVertex > nVertex) return;
  AcGePoint3d newPos = GetVertexPosition(poly.object(),iVertex-1);
  acdbWcs2Ucs(asDblArray(newPos),asDblArray(newPos),0);
  if (acedGetPoint(asDblArray(newPos),"\nУкажите новое положение вершины: ",asDblArray(newPos)) != RTNORM)
    return;
  acdbUcs2Wcs(asDblArray(newPos),asDblArray(newPos),0);
  SetVertexPosition(poly.object(),iVertex-1,newPos);
}

Со сплайном не работает. Да и врядли с ним ты что-то хорошее сможешь сделать - у него нет вершин, а перенос fit-точек (AcDbSpline::setFitPointAt(...)) - это врядли то, что ты ожидаешь.
P.S.: Вообще-то задача изначально некорректная. А что ты будешь делать с остальными типами примитивов, у которых даже самого поняти "вершина" нет?