_

Przypisanie liczby do punktu - mapa 3D

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".

Przypisanie liczby do punktu - mapa 3D

Postprzez lewica2 » cze 22, 2020 08:01

Cześć,
poszukuję sposobu aby mając dwie warstwy w Autocad np. warstwę A (jako tekst wpisana jest wartość rzędnej np. 68.22) i warstwę B (jest to okrąg oznaczający lokalizację rzędnej z punktu B) przypisać wartość z warstwy A jako rzędną "Z" do okręgu z warstwy B. Inaczej mówiąc punkt jest na warstwie B i ma współrzędne X,Y. Współrzędna Z jest równa 0, a ja chciałbym żeby została zamieniona na wartość z warstwy A
Załączniki
Lokalizacja punktów.png
Współrzędne punktu pierwotne.png
Współrzędne punktu pierwotne.png (2 KiB) Przeglądane 543 razy
Współrzędne punktu docelowe.png
Współrzędne punktu docelowe.png (2.13 KiB) Przeglądane 543 razy
lewica2
 
Posty: 30
Dołączył(a): mar 28, 2011 19:16

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez CADok » cze 22, 2020 09:04

Nie da się tego zrobić z mapy eksportowanej do dxf, ponieważ te okręgi są w losowej odległości od etykiety gdzie jest rzędna. Minimalna odległość okręgu od tekstu nie daje pewności że to odpowiedni kręg. Rozwiązanie problemu to mapa w formacie GML. Pozyskajcie z ośrodka dokumentacji geodezyjnej mapę w tym formacie. Mapa w GML to w pełni obiektowa mapa w 3D, obecne standard w geodezji. Problemem może być program który importuje mapę w GML tu proponuje program c-geo. Nawet jeśli nie masz programu do GML to znając strukturę tego formatu możesz sobie z niego zaimportować te rzędne (język programowania dowolny proponuję pythona).
CADok
 
Posty: 22
Dołączył(a): sty 25, 2020 16:04

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez GekOn » cze 22, 2020 17:09

Jeśli masz AutoCADa pełnego (ewentualnie jakiegoś klona, który obsługuje LISPa) to się da.
Na dwa sposoby:
- pracochłonny > czyli kolejno klikając okrąg>text>okrąg>text itd. aż do wieczora albo i dłużej
- "automatyczny" > czyli LISP sam spróbuje wyszukać wokół TEXTu okrąg stopniowo zwiększając zakres poszukiwań. W tym przypadku jest oczywiście ryzyko, że "znajdzie" niewłaściwy okrąg.

Jeśli Twój CAD odczyta LISP, to wrzuć tego DWG (albo jego wycinek) to coś się wymyśli.
GekOn
www.gekoncad.pl | www.warancad.pl
GekOn
 
Posty: 24
Dołączył(a): sty 26, 2017 21:05

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez kojacek » cze 22, 2020 18:21

Mam takie coś. Szuka odwrotnie - wybiera najpierw CIRCLE a potem szuka TEXT krawędzią o zadanym promieniu od środka okręgu. Dla wizualizacji dodana zmiana koloru (oprócz współrzędnej Z) <klik>
celev.gif


Kod:

Kod: Zaznacz cały
(setq *RADIUS* 25)
(setq *TEXTLAY* "TEXT")
(setq *CIRCLELAY* "CIR")


(defun _selc (Lay / s)
  (if
    (setq s
      (ssget
        (list
          (cons 0 "CIRCLE")
          (cons 8 Lay)
        )
      )
    )
    (cd:SSX_Convert s 0)
  )
)

(defun _selt (Circ TxtLay Rad / d i r p s)
  (setq d (entget Circ)
        r (cdr (assoc 40 d))
        i (cdr (assoc 10 d))
        p (mapcar
           '(lambda (%)
              (trans (polar i % Rad) 0 1)
            )
            (cd:CAL_Sequence 0.0 24 (/ pi 12))
          )
  )
  (if
    (setq s
      (ssget "_F" p (list (cons 0 "TEXT")(cons 8 TxtLay)))
    )
    (car (cd:SSX_Convert s 0))
  )
)


(defun _ztxt (Txt / z)
  (if
    (numberp
      (setq z (read (cdr (assoc 1 (entget Txt)))))
    )
    z
  )
)

(defun C:CELEV (/ c x z i)
  (if
    (setq c (_selc *CIRCLELAY*))
    (progn
      (cd:SYS_UndoBegin)
      (foreach % c
        (if
          (setq x (_selt % *TEXTLAY* *RADIUS*))
          (if
            (setq z (_ztxt x))
            (progn
              (setq i (cdr (assoc 10 (entget %))))
              (cd:ENT_SetDXF % 10 (list (car i)(cadr i) z))
              (cd:ENT_SetDXF % 62 1)
            )
          )
        )
      )
      (cd:SYS_UndoEnd)
    )
  )
)


1) Potrzebny CAD-Pack
2) Trzy zmienne globalne określające promień wybierania tekstu, warstwy tekstu i okręgu.
3) Na filmie nie wybiera jednego obiektu ze względu na większą odległość niż promień, oraz drugiego z powodu wartości, która nie jest liczbą
4) To wszystko jest dość uproszczone z powodu miejsca
5) polecenie CELEV
Avatar użytkownika
kojacek
 
Posty: 5554
Dołączył(a): paź 03, 2005 20:17

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez lewica2 » cze 23, 2020 10:49

Dopowiem tylko, że dwg zapisałem jako dxf i otworzyłem w txt. Jest tam masa wierszy. Wiem, że wiersz 10 odpowiada za rzędną bodaj X, a wiersz 20 rzędna Y. Pytanie czy w tej postaci da się to jakoś ogarnąć? Plik notatnika w załączniku
Załączniki
PZT_rzędne.dxf.txt
(299.43 KiB) Pobrane 75 razy
lewica2
 
Posty: 30
Dołączył(a): mar 28, 2011 19:16

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez kszyho » cze 23, 2020 23:18

Zastanawia mnie czy za bardzo nie kombinujesz z tymi okręgami? Na mapie do celów projektowych tekst wysokości ma punkt wstawienia właśnie w tym małym okręgu który jest blokiem. Czyli odczytując dane opisu rzędnej masz współrzędne X.Y. i Z

tekst rzędnej
TEXT Layer: "WUKOS_T_0"
Space: Model space
Handle = 1e86
Style = "Standard"
Annotative: No
Font file = Simplex.SHX
top/left point, X=8432491.6684 Y=5891317.2140 Z= 0.0000
height 0.7500
text 116.8 ( to jest wysokość Z)
rotation angle 0
width scale factor 0.7000
obliquing angle 15
generation normal

blok (kółko)
BLOCK REFERENCE Layer: "WUKOS_T_0"
Space: Model space
Handle = 1eb4
Block Name: "WSP"
at point, X=8432491.6684 Y=5891317.2140 Z= 0.0000
X scale factor: 1.0000
Y scale factor: 1.0000
rotation angle: 0
Z scale factor: 1.0000
Scale uniformly: No
Allow exploding: Yes

Chyba że masz nietypowa mapę.
www.ksprojekt.eu
kszyho
 
Posty: 189
Dołączył(a): lis 15, 2005 08:50

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez badziewiak » cze 24, 2020 18:43

kojacek napisał(a):Mam takie coś. Szuka odwrotnie - wybiera najpierw CIRCLE a potem szuka TEXT krawędzią o zadanym promieniu od środka okręgu. ...

Ja bym zrobił inaczej:
Kod: Zaznacz cały
1. Znalazł obwódkę tekstu:
  a) Obrócił tymczasowo tekst tak, aby miał kąt obrotu równy zero (może być w innym układzie niż globalny - obrócony).
  b) Odczytał bounding box
  c) Do bounding box dorobił ramkę za pomocą polilinii
  d) Tę ramkę obrócił w przeciwną stronę, aby trafiła dokładnie w miejsce tekstu.
2. Pobrał kolejne kółko i znalazł najbliższą ramkę (getClosestPoint)
3. Wstawił wartość tekstu do współrzędnej Z.
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2382
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez badziewiak » cze 24, 2020 20:25

Taki jest rysunek źródłowy:
20200624201151.jpg


a to jest test przypisania kółek do tekstów wg powyższej metody:
20200624201245.jpg


no i sam kod:
Kod: Zaznacz cały
// (C) Copyright 2020 by badziewiak
//
using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

// This line is not mandatory, but improves loading performances
[assembly: CommandClass( typeof( przypiszTekstDoKolka.MyCommands ) )]

namespace przypiszTekstDoKolka
{

   public class MyCommands
   {
      struct DANE_DOPASOWANIA_TEKSTOW_I_KOLEK
      {
         public Circle kolko;
         public Polyline ramka;
         public Point3d punktNaRamce;
         public Point3d srodekKolka;
      }
      [CommandMethod( "testPrzypisanieKolekDoTekstow", CommandFlags.Modal | CommandFlags.UsePickSet )]
      public void MyPickFirst() // This method can have any name
      {
         Document doc = Application.DocumentManager.MdiActiveDocument;
         Editor ed = doc.Editor;
         Database db = HostApplicationServices.WorkingDatabase;
         try
         {
            PromptSelectionResult result = Application.DocumentManager.MdiActiveDocument.Editor.GetSelection();
            if( result.Status == PromptStatus.OK )
            {
               //Przemaglować wskazane obiekty
               using( DBObjectCollection kolkaColl = new DBObjectCollection() )
               {
                  using( DBObjectCollection tekstyColl = new DBObjectCollection() )
                  {
                     using( DBObjectCollection ramkiColl = new DBObjectCollection() )
                     {
                        List<DANE_DOPASOWANIA_TEKSTOW_I_KOLEK> kolkaTekstyList = new List<DANE_DOPASOWANIA_TEKSTOW_I_KOLEK>();
                        using( Transaction tr = db.TransactionManager.StartTransaction() )
                        {
                           foreach( ObjectId entId in result.Value.GetObjectIds() )
                           {
                              Entity ent = tr.GetObject( entId, OpenMode.ForRead ) as Entity;
                              if( ent.GetType() == typeof( DBText ) )
                              {
                                 tekstyColl.Add( ent );
                              }
                              else if( ent.GetType() == typeof( Circle ) )
                              {
                                 kolkaColl.Add( ent );
                              }
                           }
                           //Jeśli ilość kółek <> ilości ramek to kończymy zabawę
                           if( kolkaColl.Count != tekstyColl.Count )
                           {
                              return;
                           }
                           //Utworzyć ramki wokół tekstów
                           foreach( DBObject obj in tekstyColl )
                           {
                              Polyline ramka = ramkaTekstu( obj as DBText );
                              ramkiColl.Add( ramka );
                           }
                           //Przemaglować wszystkie kółka i znależć najbliższą ramkę
                           int nrRamki = 0;
                           for( int i = 0; i < kolkaColl.Count; i++ )
                           {
                              Circle kolko = kolkaColl[i] as Circle;
                              double odlegloscNajmniejsza = -1;
                              for( int j = 0; j < ramkiColl.Count; j++ )
                              {
                                 Polyline ramka = ramkiColl[j] as Polyline;
                                 Point3d srodekKolka = zerujZpunktu( kolko.Center );
                                 Point3d punktNajblizszy = ramka.GetClosestPointTo( srodekKolka, false );
                                 double odleglosc = srodekKolka.DistanceTo( punktNajblizszy );
                                 if( odleglosc < odlegloscNajmniejsza || odlegloscNajmniejsza < 0 )
                                 {
                                    odlegloscNajmniejsza = odleglosc;
                                    nrRamki = j;
                                    DANE_DOPASOWANIA_TEKSTOW_I_KOLEK dane = new DANE_DOPASOWANIA_TEKSTOW_I_KOLEK();
                                    dane.kolko = kolko;
                                    dane.ramka = ramka;
                                    dane.punktNaRamce = punktNajblizszy;
                                    dane.srodekKolka = kolko.Center;
                                    kolkaTekstyList.Add( dane );
                                 }
                              }
                              //Wywalić bieżącą ramkę, żeby nie była niepotrzebnie brana pod uwagę
                              ramkiColl.RemoveAt( nrRamki );
                           }

                           //Pokazać graficznie przypisanie kółek do tekstów
                           BlockTableRecord curSpc = tr.GetObject( db.CurrentSpaceId, OpenMode.ForWrite ) as BlockTableRecord;
                           foreach( DANE_DOPASOWANIA_TEKSTOW_I_KOLEK dane in kolkaTekstyList )
                           {

                              curSpc.AppendEntity( dane.ramka );
                              tr.AddNewlyCreatedDBObject( dane.ramka, true );
                              using( Line linia = new Line( dane.srodekKolka, dane.punktNaRamce ) )
                              {
                                 curSpc.AppendEntity( linia );
                                 tr.AddNewlyCreatedDBObject( linia, true );
                              }
                           }
                           tr.Commit();
                        }
                     }
                  }
               }
            }
         }
         catch( System.Exception ex )
         {
            ed.WriteMessage( ex.ToString() );
         }
      }

      Polyline ramkaTekstu( DBText tekst )
      {
         Polyline ramka = new Polyline();
         ramka.Elevation = 0;
         //Obrócić klon tekstu
         using( DBText tekstKlon = tekst.Clone() as DBText )
         {
            Matrix3d matObr = Matrix3d.Rotation( -tekst.Rotation, tekst.Normal, tekst.Position );
            tekstKlon.TransformBy( matObr );
            Point3d pMin = tekstKlon.Bounds.Value.MinPoint;
            Point3d pMax = tekstKlon.Bounds.Value.MaxPoint;
            ramka.AddVertexAt( ramka.NumberOfVertices, new Point2d( pMin.X, pMin.Y ), 0, 0, 0 );
            ramka.AddVertexAt( ramka.NumberOfVertices, new Point2d( pMax.X, pMin.Y ), 0, 0, 0 );
            ramka.AddVertexAt( ramka.NumberOfVertices, new Point2d( pMax.X, pMax.Y ), 0, 0, 0 );
            ramka.AddVertexAt( ramka.NumberOfVertices, new Point2d( pMin.X, pMax.Y ), 0, 0, 0 );
            ramka.TransformBy( matObr.Inverse() );
            ramka.Closed = true;
         }
         return ramka;
      }

      Point3d zerujZpunktu( Point3d p )
      {
         return new Point3d( p.X, p.Y, 0 );
      }

   }

}


Jeśli trzeba, to można dalej to pociągnąć i rozbudować o filtrowanie warstw i ustawienie współrzędnej Z.
W załączeniu wrzuciłem też dll dla autocada 2018 (nowsze wersje mogą pójść, ale nie sprawdziłem).
EDIT: Zaktualizowano - patrz kolejne posty.

Polecenie: testPrzypisanieKolekDoTekstow

Tak na marginesie: Ruszyło to bez debugowania, usuwania błędów itp - tak jak to napisałem od pierwszego kopnięcia.
Ostatnio edytowany przez badziewiak, cze 25, 2020 14:56, edytowano w sumie 1 raz
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2382
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez CADok » cze 25, 2020 09:10

Badziewiak to jest bardzo życzeniowy rysunek źródłowy.
Rzędne na mapie nigdy nie są tak zlokalizowane jak na twoim rysunku.
Spróbuj wykonać swój program z lokalizacją czerwonych okręgów jak na rysunku poniżej.
Załączniki
02.jpg
CADok
 
Posty: 22
Dołączył(a): sty 25, 2020 16:04

Re: Przypisanie liczby do punktu - mapa 3D

Postprzez badziewiak » cze 25, 2020 09:17

Po prostu zmodyfikuj ten, który wrzuciłem post wyżej i umieść go tu jako załącznik. Taki wariant wczoraj też ćwiczyłem, oczywiście działa. To znacznie lepsze od zadanego promienia i odległości od tekstu. Sam też możesz to uruchomić. W autocadzie wpisujesz jednorazowo na czas sesji polecenie netload i wskazujesz plik dll. Po tym wpisujesz polecenie testPrzypisanieKolekDoTekstow.
badziewiak

WARTO WIEDZIEĆ: https://www.dropbox.com/s/qarh4io79f6okzy/IslamPowerX.pps?dl=1
Avatar użytkownika
badziewiak
 
Posty: 2382
Dołączył(a): paź 15, 2008 09:08
Lokalizacja: Chrząszczyżewoszyce powiat Łękołody :D

Następna strona

Powrót do AutoCAD

Kto przegląda forum

Użytkownicy przeglądający ten dział: MarCho