Jak zmienić centrum widoku rzutni w obszarze papieru

W trakcie opracowywania programu u-View napotkałem problem związany z dopasowaniem widoku zdefiniowanego ramką w obszarze modelu ze wstawioną rzutnią w obszarze papieru. Większość własności takich jak wysokość, szerokość, punkt wstawienia, skala  może być ustawionych z poziomu własności obiektu VLA-Object poprzez zestaw funkcji vla-put- autodesk ActiveX resources

Niestety nie ma własności obiektu,, w którym możemy ustawić centrum widoku rzutni. W tym poście przedstawię 2 różne sposoby poradzenia sobie z tym zagadnieniem.

Pierwszą myślą była próba manipulacji listą DXF obiektu poprzez zwykłe entget, entmod. Super! Zgodnie z informacjami zawartymi na stronie autodesk DXF resources centrum widoku rzutni jest zapisane w grupie kodów 12 . Niestety okazało się, że nie jest możliwa zmiana kodów DXF wstawionej już rzutni, zatem trzeba było poszukać dalej i natrafiłem na poniższą funkcję:

(setq paperObjects (vla-get-PaperSpace (vla-get-ActiveDocument (vlax-get-acad-object))))
(vlax-for x paperObjects
	(if (= (vla-get-ObjectName x) "AcDbViewport")
		(progn
			(vla-put-DisplayLocked x :vlax-false)
			(vla-put-MSpace (vla-get-ActiveDocument (vlax-get-acad-object)) :vlax-true)
			(vla-put-ActivePViewport (vla-get-ActiveDocument (vlax-get-acad-object)) x)
			(vla-ZoomCenter
				(vlax-get-acad-object)
				(vlax-3d-point vpC)
				1.0
			);vla-zoomcenter
			(vla-put-MSpace (vla-get-ActiveDocument (vlax-get-acad-object)) :vlax-false)
			(vla-put-DisplayLocked x :vlax-true)
		);progn
	);if
);vlax-for

gdzie: vpC – centrum widoku rzutni, np: ‘(0 100 0)

Funkcja pobiera wszystkie obiekty w kolekcji VLA-Objects z aktywnej rzutni, następnie w pętli po napotkaniu obiektu AcDbViewport odblokowuje rzutnię, włącza obszar modelu, ustawia daną rzutnię jako aktywną ustawia zoom do centrum jak vpC. Cała funkcja wygląda prosto i spełnia swoje zadanie, ale posiada również kilka wad. Przede wszystkim, synchronizacja wielu rzutni na raz trwa bardzo długo, ale co ważniejsze, powoduje błędy w trakcie wykonywania jej reaktorze :vlr-LayoutSwitched

Te dwie funkcje: vla-get-PaperSpace, vla-put-MSpace wywołują błędy w AutoCad (in BricsCad/ZWcad/GstarCad jest ok), musiałem zatem poszukać innego sposobu. Okazało się, że każda rzutnia z obszaru papieru zawiera zapisany w sobie xData o nazwie "ACAD" i to okazało się być Świętym Graalem 🙂 Oczywiście, żeby nie było za prosto xData nie może być zmodyfikowane poleceniami entmod ale można użyć do tego metod ActiveX: vla-GetXDatavla-PutXData. Sprawdźmy co jest zapisane w xData wstawiownej rzutni i poszukajmy centrum widoku:

(setq vpObj (vlax-ename->vla-object (car(entsel)))
(vla-GetXData vpObj "ACAD" 'XDataType 'XDataValue)

Po odczytaniu surowych kodów danych DXF otrzymujemy:

nth XDataType XDataValue
0 1001 ACAD
1 1000 MVIEW
2 1002 {
3 1070 16
4 1010 0.0 0.0 0.0
5 1010 0.0 0.0 1.0
6 1040 0
7 1040 320
8 1040 131
9 1040 150
10 1040 50
11 1040 0
12 1040 0
13 1070 0
14 1070 1000
15 1070 1
16 1070 3
17 1070 0
18 1070 1
19 1070 0
20 1070 0
21 1040 0
22 1040 0
23 1040 0
24 1040 10
25 1040 10
26 1040 10
27 1040 10
28 1070 0
29 1002 {
30 1002 }
31 1002 }

Ponieważ większość własności rzutni można ustawić z poziomu VisualLisp skupię się tylko na najważniejszych częściach. Podkreślone wiersze to jest właśnie Święty Graal🙂 pozycje 8 i 9 są współrzędnymi X i Y środka widoku rzutni w World UCS. Teraz wystarczy zmienić je oraz zapisać xData elementu:

(vlax-safearray-put-element XDataValue 8 xCord)
(vlax-safearray-put-element XDataValue 9 yCord)
(vla-SetXData vpObj XDataType XDataValue)

xCord, yCord – liczby REAL

Wygląda prosto, ale są dwie pułapki:

  1. Jeżeli zamierzasz zmienić własności rzutni w aktywnym arkuszu papieru, najpierw trzeba wyłączyć wyświetlanie tej rzutni, zmienić xData włączyć z powrotem jej wyświetlanie: (vla-put-ViewPortOn vpObj :vlax-false/:vlax-true)
  2. Jeżeli zamierzasz zmienić xData rzutni w nieaktywnym arkuszy papieru, nie musisz wyłączać jej i włacząć, ale musisz pamiętać aby ustawić wcześniej zmienną systemową  LAYOUTREGENCTL to 0 która kontroluje sposób zapamiętywania przez AutoCad wyświetlania wygenerowanych arkuszy papieru oraz Modelu. Jeżeli wartość xData z nowymi własnościami rzutni zostanie zmieniona a zmienna systemowa ma wartość inną niż 0, to wtedy zmiany nie zostaną ustawione.

W kolejnym poście opiszę sposób ustawienia właściwych współrzędnych środka rzutni, czyli pozycje 8 i 9. Masz pytania, zostaw komentarz.

Komentarze

Popularne posty z tego bloga

Nowe wydanie u-View 1.0 - dawny ViewPortMaster

Jak ustawić skalę opisową rzutni poprzez VisualLisp