_

C# Tabela - granice obramowania komórki

Forum poświęcone flagowemu produktowi oraz aplikacjom pochodnym Autodesku. To jedyne forum mające w tytule nazwę programu, a to ze względu na jego olbrzymią popularność w Polsce. Można tutaj umieszczać również posty z ogólnie pojętej tematyki "Kreślarskie 2D".

C# Tabela - granice obramowania komórki

Postprzez badziewiak » lut 18, 2017 13:31

Witam
Moim celem jest narysowanie przekątnej komórki tabeli. W tym celu biorę współrzędne narożników komórki:
Kod: Zaznacz cały
Point3dCollection extentsGoraLewa = komNaglGornaLewa.GetExtents();
Point3dCollection extentsDolnaPrawa = komNaglDolnaPrawa.GetExtents();

tylko jest mały problem: Linia nie trafia bezpośrednio w narożnik obramowania, lecz z odstępem 0,7mm w osi x i y w stronę wnętrza komórki.
Jak dobrać się do samych linii komórek?
badziewiak

WARTO WIEDZIEĆ: https://dl.dropboxusercontent.com/u/224045/IslamPowerX.pps
http://badziewiak2010.republika.pl
Avatar użytkownika
badziewiak
 
Posty: 2235
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: C# Tabela - granice obramowania komórki

Postprzez kojacek » lut 18, 2017 13:51

badziewiak napisał(a):Witam
Moim celem jest narysowanie przekątnej komórki tabeli. W tym celu biorę współrzędne narożników tabeli:
Kod: Zaznacz cały
Point3dCollection extentsGoraLewa = komNaglGornaLewa.GetExtents();
Point3dCollection extentsDolnaPrawa = komNaglDolnaPrawa.GetExtents();

tylko jest mały problem: Linia nie trafia bezpośrednio w narożnik obramowania, lecz z odstępem 0,7mm w osi x i y w stronę wnętrza komórki.
Jak dobrać się do samych linii komórek?


Grafika obiektu ACAD_TABLE, znajduje się w definicji bloku anonimowego typu *Tnn. W niej znajdują się wszystkie obiekty składające się na tabelę - czyli zwykle LINE + MTEXT-y. Ptactwo dobiera się do tego w ten sposób:
Kod: Zaznacz cały
(cdr (assoc 2 (entget (car (entsel)))))

wskazując tabelę i w wyniku uzyskując nazwę bloku. Idąc dalej (i wykorzystując CADPL-Pack'a) co wytrawniejsze wrony mogą wydziobać listę wszystkich obiektów bloku:
Kod: Zaznacz cały
(cd:BLK_GetEntity (cdr (assoc 2 (entget (car (entsel))))) nil)

lub (podobnie) samych linii:
Kod: Zaznacz cały
(cd:BLK_GetEntity (cdr (assoc 2 (entget (car (entsel))))) "LINE")

Potem trzeba jeno przemyśleć jak wyliczyć współrzędne wskazanej komórki, ale to pewnie nie będzie najtrudniejszym zadaniem. Pamiętać należy jednak że obiekty w definicji bloku mają inne współrzędne obiektów, niźli odpowiadająca im tabela w przestrzeni.
Avatar użytkownika
kojacek
 
Posty: 5222
Dołączył(a): paź 03, 2005 20:17

Re: C# Tabela - granice obramowania komórki

Postprzez badziewiak » lut 18, 2017 13:58

Ale mnie chodzi o yntelygentne dobranie się do ramki, nie chytre ;) Rozważałem latanie po definicji bloku jako ostateczność. Myślałem, że jest jakiś prostszy sposób. Zawsze mogę zrobić tak, że biorę dwie sąsiadujące komórki, z nich extents, a z tego środek między najbliższymi narożnikami (powinien wypaść dokładnie na linii). Od tego środka mierzę to co mi extents wypluł i mam poprawkę, którą uwzględniam we wszystkich komórkach.
Prościej się nie da?
badziewiak

WARTO WIEDZIEĆ: https://dl.dropboxusercontent.com/u/224045/IslamPowerX.pps
http://badziewiak2010.republika.pl
Avatar użytkownika
badziewiak
 
Posty: 2235
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: C# Tabela - granice obramowania komórki

Postprzez badziewiak » lut 18, 2017 15:02

Potwierdzam że to działa:
Kod: Zaznacz cały
//Extents jest odsunięty w kierunku wnętrza komórki w osiach X i Y o jakiś margines (ostatno zmierzony: 0,7mm). Pobrać dwie sąsiadujące komórki i wyznaczyć poprawkę
Cell komTmp1 = tabela.Cells[CWspoldzielone.matrSterIloscWierszyTabeliZwyjsciamiInaglowkiemTabeli + CWspoldzielone.matrSterIloscWierszyNaglowkaStref, CWspoldzielone.matrSterNrKolumnyPierwszegoWyjsciaModuluPoWstawieniuKolumnStref];
Cell komTmp2 = tabela.Cells[komTmp1.Row + 1, komTmp1.Column + 1];
Point3dCollection extTmp1 = komTmp1.GetExtents();
Point3dCollection extTmp2 = komTmp2.GetExtents();
Point3d srodekMiedzyKomorkami = RKGeometryczne.srodek3D( extTmp2[3], extTmp1[0] );
double poprawkaX = srodekMiedzyKomorkami.X - extTmp1[3].X;
double poprawkaY = extTmp1[3].Y - srodekMiedzyKomorkami.Y;
Point3d p1LiniiUkosnejNaglowka = new Point3d( extentsGoraLewa[0].X - poprawkaX, extentsGoraLewa[0].Y + poprawkaY, 0 );
Point3d p2LiniiUkosnejNaglowka = new Point3d( extentsDolnaPrawa[3].X + poprawkaX, extentsDolnaPrawa[3].Y - poprawkaY, 0 );
CWspoldzielone.rysujLinie( tr, model, p1LiniiUkosnejNaglowka, p2LiniiUkosnejNaglowka, warstwaPomocniczeId );

Tylko uwaga! Należy upewnić się, że komórki używane do wyznaczania środka między nimi nie są scalone! Extents z komórki znajdującej się w scalonej grupie jest taki, jak dla całej grupy!
badziewiak

WARTO WIEDZIEĆ: https://dl.dropboxusercontent.com/u/224045/IslamPowerX.pps
http://badziewiak2010.republika.pl
Avatar użytkownika
badziewiak
 
Posty: 2235
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: C# Tabela - granice obramowania komórki

Postprzez kojacek » lut 18, 2017 15:22

No to ja mam tak. Bez poprawek odsunięcia. To szkic tylko na szybko, bo docelowo więcej rzeczy trzeba by sprawdzić i poprawić, ale na gorąco działa. Idea jest taka:
1) po wskazaniu punktu w komórce
2) Ustawiamy jej kolor (BackGround) na kolor 250
3) Pobieramy dane obiektu SOLID (właśnie ten Background)
4) Wyłączamy kolor komórki
5) Rysujemy linie po pobranych współrzędnych (na czerwono)
6) Przesuwamy ją z bazowego punktu definicji bloku do rzeczywistego punktu wstawienia tabeli
CADPack - musi być wczytany.
badziewiakstable.PNG

Kodzik:
Kod: Zaznacz cały
; ================================================================== ;
; kojacek 2017
; ================================================================== ;
(defun C:XTAB (/ l a r c b g d i w x)
  (if
    (setq l
      (jk:TAB_GetTablePoint
        (getpoint "\nWskaz punkt w tabeli: ")
      )
    )
    (progn
      (setq a (car l) r (cadr l) c (caddr l)
            b (cdr (assoc 2
                (setq w (entget (vlax-vla-object->ename a))))
              )
            i (cdr (assoc 10 w))
      )
      (cd:SYS_UndoBegin)
      (vla-put-colorindex (jk:ACX_TrueColorObj) 250)
      (vla-SetCellBackgroundColor a r c *jk-TrueColor)
      (if (setq g (cd:BLK_GetEntity b "SOLID"))
        (progn
          (setq d (entget (car g)))
          (setq x (cd:ACX_AddLine (cd:ACX_ASpace)
              (cdr (assoc 11 d))(cdr (assoc 12 d)) T)
          )
          (cd:ACX_SetProp x '(("Color" . 1)))
          (vla-Move x (vlax-3d-point
                        (list 0 0 0))(vlax-3d-point i))
        )
      )
      (vla-SetCellBackgroundColorNone a r c :vlax-true)
      (cd:SYS_UndoEnd)
    )
    (princ "\nNie wskazano punktu w tabeli. ")
  )
  (princ)
)
; ==================================================================== ;
; Funkcja zwraca liste typu (<VLA-OBJECT IAcadTable> row col) jesli    ;
; wskazany punkt [Pt] jest wewnatrz tabeli                             ;
; ==================================================================== ;
(defun jk:TAB_GetTablePoint (Pt / ds p1 ss vc To row col)
  (if Pt
    (progn
      (setq ds (getvar "VIEWSIZE")
            p1 (polar Pt (* 0.5 pi) ds)
            ss (ssget "_F" (list Pt p1)'((0 . "ACAD_TABLE")))
      )
      (if ss
        (progn
          (setq vc (vlax-3d-point (getvar "VIEWDIR"))
                To (vlax-ename->vla-object (ssname ss 0))
          )
          (if
            (= :vlax-true
              (vla-hittest
                To (vlax-3d-point (trans Pt 1 0)) vc 'row 'col
              )
            )
            (list To row col) nil
          )
        ) nil
      )
    )
  )
)
; ================================================================== ;
; obiekt: TrueColor                                                  ;
; ================================================================== ;
(defun jk:ACX_TrueColorObj ()
  (if
    (not *jk-TrueColor)
    (setq *jk-TrueColor
      (vla-getinterfaceobject
        (vlax-get-acad-object)
        (strcat
          "AutoCAD.AcCmColor."
          (substr (getvar "ACADVER") 1 2)
        )
      )
    )
    *jk-TrueColor
  )
)
; ================================================================== ;
(princ)
Avatar użytkownika
kojacek
 
Posty: 5222
Dołączył(a): paź 03, 2005 20:17

Re: C# Tabela - granice obramowania komórki

Postprzez badziewiak » lut 18, 2017 16:52

W zasadzie każdy sposób jest dobry, byle skuteczny. Nie spieram się który lepszy.
BTW: Tę tabelę to już chyba gdzieś widziałem... :roll:
badziewiak

WARTO WIEDZIEĆ: https://dl.dropboxusercontent.com/u/224045/IslamPowerX.pps
http://badziewiak2010.republika.pl
Avatar użytkownika
badziewiak
 
Posty: 2235
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: C# Tabela - granice obramowania komórki

Postprzez kojacek » lut 18, 2017 17:06

badziewiak napisał(a):BTW: Tę tabelę to już chyba gdzieś widziałem... :roll:

He he, też mi gdzieś "mignęła"... ;)
Avatar użytkownika
kojacek
 
Posty: 5222
Dołączył(a): paź 03, 2005 20:17


Powrót do AutoCAD

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników