Ovaj Python program omogućava korisnicima interaktivni rad sa DXF fajlovima direktno sa komandne linije. Program je razvijen korišćenjem ezdxf
i matplotlib
biblioteka i podržava sledeće ključne funkcionalnosti:
1. Pan (Pomicanje Crteža)
- Pritiskom na točkić miša korisnici mogu da pomeraju crtež na ekranu. Ova funkcionalnost omogućava lakšu navigaciju kroz velike crteže, čineći ih jednostavno preglednim i prilagodljivim.
2. Zumiranje
- Okretanjem točkića miša korisnici mogu da zumiraju crtež, povećavajući ili smanjujući prikaz crteža u određenim područjima, što omogućava detaljan pregled elemenata crteža.
3. Merenje Rastojanja između Dve Tačke
- Pritiskom levog tastera miša na dve tačke, korisnici mogu da izmere rastojanje između tih tačaka.
- Program izračunava euklidsku distancu i prikazuje rezultat u realnom vremenu.
- Svi rezultati merenja (rastojanje) se ispisuju u konzoli.
4. Merenje Površine između VIše Tačaka
- Desnim klikom birate više tačaka za formiranje poligona.
- Kliknite ponovo na prvu tačku da zatvorite poligon.
- Rezultat će biti prikazan u konzoli..
5. Merenje Ugla između Tri Tačke
- Dok držite pritisnut taster CTRL
- Pritiskom na desni taster miša na tri tačke,
- izmerićete ugao između tih tačaka.
- Program prikazuje ugao u stepenima.
- Svi rezultati merenja (ugao) se ispisuju u konzoli.
Naravno! Evo pregleda šta sve program može da iscrta iz DXF fajla, na osnovu trenutne implementacije:
✏️ Entiteti koje program prikazuje
Program koristi biblioteku ezdxf
za parsiranje DXF fajla i matplotlib
za crtanje. U okviru draw_dxf()
funkcije, podržani su sledeći entiteti:
1. LINE
🔹 Opis: Pravolinijski segment između dve tačke.
🔹 Prikazano kao: Plava linija
🔹 Kod:
ax.plot([start.x, end.x], [start.y, end.y], 'b')
2. CIRCLE
🔹 Opis: Krug definisan centrom i radijusom.
🔹 Prikazano kao: Crveni krug (bez ispune)
🔹 Kod:
c = plt.Circle((center.x, center.y), radius, color='r', fill=False) ax.add_patch(c)
3. LWPOLYLINE
🔹 Opis: Lakša verzija polilinije — niz povezanih tačaka.
🔹 Prikazano kao: Magenta linije
🔹 Kod:
ax.plot(x_vals, y_vals, 'm')
4. POLYLINE
🔹 Opis: Klasična polilinija, često sa dodatnim osobinama (3D, visina, itd.)
🔹 Prikazano kao: Cijan (svetloplava) linija
🔹 Kod:
ax.plot(x_vals, y_vals, 'c')
📐 Napomena
- Slojevi (Layers): Program prikazuje sve entitete bez obzira na sloj.
- Zatvorene konture: Kod
POLYLINE
iLWPOLYLINE
, čak i ako su zatvorene, prikazuju se kao obične linije — ne popunjavaju se automatski.
❌ Entiteti koje program ne podržava (još)
Trenutno se ignorišu sledeći elementi (ali ih je moguće dodati):
ARC
(luk)ELLIPSE
(elipsa)TEXT
,MTEXT
(tekstualni elementi)SPLINE
(krivolinijski oblici)HATCH
(šrafura/popunjenost)DIMENSION
(dimenzije)BLOCKS
(blokovi i referencirane instance)
Ako želište da dodate podršku za još neki od ovih elemenata — možete proširiti funkciju draw_dxf()
da ih prepozna i iscrta!
Pokretanje Programa u Konzoli
✅ 1. Zahtevi (Zavisnosti)
Pre nego što pokreneš program, uveri se da su instalirani sledeći paketi:
- Python 3 (verzija 3.6+)
ezdxf
– za rad sa DXF fajlovimamatplotlib
– za crtanje i prikaz grafike
🔧 Instalacija paketa
U terminalu pokreni sledeće komande:
sudo apt update sudo apt install python3 python3-pip -y pip3 install ezdxf matplotlib
✅ 2. Smeštanje programa
- Otvori terminal.
- Kreiraj novi folder (ako želiš):
mkdir ~/vidi_dxf cd ~/vidi_dxf
Kreiraj novi Python fajl:
nano xdxf.py
(Zalepi ceo Python kod i sačuvaj: CTRL + O
, zatim ENTER
, pa CTRL + X
za izlaz.)
Python kod koji kopiraš u xdxf.py
import ezdxf import matplotlib.pyplot as plt import sys import os import math clicked_points = [] point_markers = [] polygon_patch = None drag_start = None is_panning = False def distance(p1, p2): return math.hypot(p2[0] - p1[0], p2[1] - p1[1]) def polygon_area(points): n = len(points) area = 0.0 for i in range(n): x1, y1 = points[i] x2, y2 = points[(i + 1) % n] area += x1 * y2 - x2 * y1 return abs(area) / 2.0 def draw_point(x, y): marker, = ax.plot(x, y, 'ko', markersize=5) point_markers.append(marker) fig.canvas.draw() def draw_polygon(points): global polygon_patch if polygon_patch: polygon_patch.remove() polygon_patch = plt.Polygon(points, closed=True, edgecolor='orange', facecolor='orange', alpha=0.3) ax.add_patch(polygon_patch) fig.canvas.draw() def clear_visuals(): global point_markers, polygon_patch for m in point_markers: m.remove() point_markers.clear() if polygon_patch: polygon_patch.remove() polygon_patch = None fig.canvas.draw() def on_click(event): global is_panning, drag_start if event.inaxes: if event.button == 1: # Levim klikom meri rastojanje x, y = event.xdata, event.ydata clicked_points.append((x, y)) print(f"Kliknuta tačka: ({x:.2f}, {y:.2f})") draw_point(x, y) if len(clicked_points) == 2: d = distance(clicked_points[0], clicked_points[1]) print(f"Rastojanje između tačaka: {d:.2f} jedinica\n") clicked_points.clear() clear_visuals() elif event.button == 2: # Srednji klik (točkić) za pan is_panning = True drag_start = (event.xdata, event.ydata) elif event.button == 3: # Desni klik za merenje površine ili ugla x, y = event.xdata, event.ydata # Detekcija CTRL + 3 desna klika za merenje ugla if event.key == 'control': clicked_points.append((x, y)) draw_point(x, y) if len(clicked_points) == 3: a, b, c = clicked_points angle = math.degrees(math.atan2(c[1] - b[1], c[0] - b[0]) - math.atan2(a[1] - b[1], a[0] - b[0])) angle = abs(angle) if angle > 180: angle = 360 - angle print(f"Ugao između tri tačke: {angle:.2f} stepeni\n") clicked_points.clear() clear_visuals() return new_point = (x, y) if len(clicked_points) >= 3: first_point = clicked_points[0] if distance(first_point, new_point) < 5.0: draw_polygon(clicked_points) area = polygon_area(clicked_points) print(f"Površina zatvorenog poligona ({len(clicked_points)} temena): {area:.2f} kv. jedinica\n") clicked_points.clear() clear_visuals() return clicked_points.append(new_point) draw_point(x, y) print(f"Kliknuta tačka za površinu: ({x:.2f}, {y:.2f})") def on_motion(event): global drag_start if event.inaxes and is_panning: dx = event.xdata - drag_start[0] dy = event.ydata - drag_start[1] ax.set_xlim(ax.get_xlim() - dx) ax.set_ylim(ax.get_ylim() - dy) drag_start = (event.xdata, event.ydata) fig.canvas.draw() def on_release(event): global is_panning if event.button == 2: is_panning = False def on_scroll(event): global ax if event.inaxes: scale_factor = 1.1 if event.button == 'up' else 0.9 xlim, ylim = ax.get_xlim(), ax.get_ylim() center_x, center_y = (xlim[0] + xlim[1]) / 2, (ylim[0] + ylim[1]) / 2 ax.set_xlim(center_x - (center_x - xlim[0]) * scale_factor, center_x + (xlim[1] - center_x) * scale_factor) ax.set_ylim(center_y - (center_y - ylim[0]) * scale_factor, center_y + (ylim[1] - center_y) * scale_factor) fig.canvas.draw() def on_key(event): if event.key == 'escape': print("⛔ ESC pritisnut – prekid merenja i čišćenje tačaka.\n") clicked_points.clear() clear_visuals() def draw_dxf(file_path): print(f"Učitavanje DXF fajla: {file_path}") try: doc = ezdxf.readfile(file_path) except IOError: print(f"❌ Greška: Ne mogu da otvorim fajl '{file_path}'") return except ezdxf.DXFStructureError: print(f"❌ Greška: Fajl '{file_path}' nije validan DXF fajl") return msp = doc.modelspace() global fig, ax fig, ax = plt.subplots() for entity in msp: if entity.dxftype() == 'LINE': start = entity.dxf.start end = entity.dxf.end ax.plot([start.x, end.x], [start.y, end.y], 'b') elif entity.dxftype() == 'CIRCLE': center = entity.dxf.center radius = entity.dxf.radius c = plt.Circle((center.x, center.y), radius, color='r', fill=False) ax.add_patch(c) elif entity.dxftype() == 'LWPOLYLINE': points = [point[:2] for point in entity] if len(points) > 1: x_vals, y_vals = zip(*points) ax.plot(x_vals, y_vals, 'm') elif entity.dxftype() == 'POLYLINE': points = [v.dxf.location for v in entity.vertices()] if len(points) > 1: x_vals = [p.x for p in points] y_vals = [p.y for p in points] ax.plot(x_vals, y_vals, 'c') ax.set_aspect('equal') ax.autoscale() ax.set_title("Levi klik:rastojanje|Desni klik:površina|CTRL+Desni klik:ugao|Zum:točkić|Pan:srednji klik") ax.set_xlabel("X") ax.set_ylabel("Y") ax.grid(True) fig.canvas.mpl_connect("button_press_event", on_click) fig.canvas.mpl_connect("motion_notify_event", on_motion) fig.canvas.mpl_connect("button_release_event", on_release) fig.canvas.mpl_connect("scroll_event", on_scroll) fig.canvas.mpl_connect("key_press_event", on_key) try: plt.tight_layout() plt.show() except Exception as e: print(f"❌ Greška pri prikazu crteža: {e}") input("Pritisni Enter za izlaz...") if __name__ == "__main__": if len(sys.argv) < 2: print("Upotreba: python vidi_dxf.py <putanja_do_dxf_fajla>") sys.exit(1) print(""" - Merenje rastojanja: Pritiskom na levi taster miša na dve tačke, izmerićete rastojanje između tih tačaka. Rezultat će biti prikazan u konzoli. - Merenje površine: Desnim klikom birate više tačaka za formiranje poligona. Kliknite ponovo na prvu tačku da zatvorite poligon. Rezultat će biti prikazan u konzoli. - Pan (Pomicanje crteža): Pritiskom na srednji taster miša (točkić), možete slobodno pomerati crtež na ekranu - Zumiranje: Okretanjem točkića miša, možete povećavati ili smanjivati prikaz crteža. - Merenje ugla: Dok držite pritisnut taster CTRL Pritiskom na desni taster miša na tri tačke, izmerićete ugao između tih tačaka. Rezultat će biti prikazan u konzoli. - ESC taster prekida sva merenja i čisti ekran od mernih tačaka. """) file_path = sys.argv[1] if not os.path.isfile(file_path): print(f"❌ Fajl '{file_path}' ne postoji!") sys.exit(1) draw_dxf(file_path) print("✅ Program završen.")
3. Priprema DXF fajla
U isti folder kopiraj .dxf fajl koji želiš da otvoriš.
Primer (ako se fajl zove primer.dxf
):
cp /putanja/do/primer.dxf ~/vidi_dxf/
✅ 4. Pokretanje programa
Pokreni program iz terminala na sledeći način:
python3 xdxf.py primer.dxf
🧭 5. Uputstvo za korišćenje programa
Kada pokreneš program, u terminalu će se prikazati sledeće uputstvo:
- Merenje rastojanja: Pritiskom na levi taster miša na dve tačke, izmerićete rastojanje između tih tačaka. Rezultat će biti prikazan u konzoli. - Merenje površine: Desnim klikom birate više tačaka za formiranje poligona. Kliknite ponovo na prvu tačku da zatvorite poligon. Rezultat će biti prikazan u konzoli. - Pan (Pomicanje crteža): Pritiskom na srednji taster miša (točkić), možete slobodno pomerati crtež na ekranu - Zumiranje: Okretanjem točkića miša, možete povećavati ili smanjivati prikaz crteža. - Merenje ugla: Dok držite pritisnut taster CTRL Pritiskom na desni taster miša na tri tačke, izmerićete ugao između tih tačaka. Rezultat će biti prikazan u konzoli. - ESC taster prekida sva merenja i čisti ekran od mernih tačaka.
🖱️ Pregled funkcionalnosti
Radnja | Opis |
---|---|
Levi klik (x2) | Izmeri rastojanje između dve tačke. |
Desni klik (više puta) | Formira poligon, zatvara ga klikom blizu prve tačke. |
CTRL + 3x desni klik | Izračunava ugao između tri tačke. |
Srednji klik (točkić) | Panoramsko pomeranje crteža. |
Točkić miša | Zumiranje u/van. |
🛑 6. Zatvaranje programa
Klikom na X u prozoru ili zatvaranjem matplotlib prikaza – program se završava.
Primer Pokretanja Programa:
Na primer, ako želite da otvorite fajl kupola.dxf
koji se nalazi u istom direktorijumu kao i skripta, komanda bi izgledala ovako:
python3 xdxf.py kupola.dxf
U prozoru koji se otvori, možete interaktivno pomerati crtež, zumirati, meriti rastojanja, površine i uglove.
Ovaj crtež je rađen u takvoj razmeri da su rezultati merenja dužine u santimetrima. Svi rezultati merenja (rastojanje i ugao) biće prikazani u konzoli, kao na primer:

Ovaj način interakcije omogućava jednostavno i efikasno radno okruženje u komandnoj liniji, bez potrebe za dodatnim grafičkim korisničkim interfejsima. Program je brz, fleksibilan i idealan za rad sa jednostavnim CAD crtežima i merenja u DXF formatu.
