天天看點

acedSSGet用法

大多數ObjectARX函數在處理選擇集和實體時,都用名字來識别選擇集或實體,該名字用一個長整型對來表示的,并對AutoCAD來維護。在ObjectARX中,該名字的類型為ads_name。

在對選擇集或實體進行操作之前,ObjectARX應用程式必須通過調用一個傳回其名字的庫函數來得到選擇集或實體名字。

注意:選擇集和實體的名字是不穩定的,它們僅僅在AutoCAD目前圖形工作時有效。如果從AutoCAD退出或切換到另一個圖形時其值就會丢失。

對于選擇集來說,它也是與目前圖有關聯的,是以其名字的不穩定性不會影響選擇集。但是對于實體就不一樣了,因為它是被存放在圖形資料庫中的,名字的不穩定性要影響到對實體的操作。應用程式必須在下一次對同一圖檔案中的同一實體進行操作,可以使用實體句柄,重新擷取其實體名。

選擇集的處理

ObjectARX函數對選擇集的處理類似于AutoLISP。acedSSGet()函數提供大多數建立選擇集方法。它一般通過以下三種方法之一建立選擇集:

(1)提供讓使用者選擇對象。

(2)象互動式應用AutoCAD一樣,利用RICKFIRST定義、Crossing、Crossing Polygon、Fence、Last、Previous、Window、Window Polygon等比對條件的方式來選擇實體對象,也可以通過指定一個單獨點或Fence點來選擇。

(3)使用一系列屬性和條件篩選目前圖資料庫來選擇實體對象。

該函數原型為:

int acedSSGet(const chat *str,const void *pt1,const void *pt2,const struct resbuf *entmask,ads_name ss);

acedSSGet()的第一個參數str,說明所使用的選擇條件,如下:

表示碼 意義

NULL 單點選擇(如果指定了pt1)或使用者選擇(如果pt1也為NULL)

# 非幾何選擇(all、last、previous)

:$ 提供提示文字

. 使用者拾取方式

:? 其他回調函數

A All選擇方式

B Box選擇方式

C Crossing選擇方式

CP Crossing Polygon選擇方式

:D 可以重複,即可以重複選擇一個實體,并加入選擇集中

:E 在aperture中的所有實體

F Fence選擇方式

G Groups選擇

I 如果存在RICKFIRST集、則用該集

:K    關鍵字回調函數

L Last選擇方式

M 多重選擇方式

P Previous選擇方式

:S 強制單個實體對象被選擇

W Window選擇方式

WP Window Polygon選擇方式

X 用于篩選程式搜尋整個圖形資料庫

緊跟着的兩個參數用于指定與某些選擇方式有關的可選擇的點。當不使用他們時,應該取NULL值。如果第四個參數entmask不是NULL,則它指向一個緩沖區表,用于存放用篩選選擇方式的結果。第五個參數ss是選擇集的識别名字。

下列是調用acedSSGet()的例子:

ads_point pt1,pt2,pt3,pt4;
 struct resbuf *pointlist;
 ads_name ssname;
 pt1[x]=pt1[y]=pt1[z]=0.0;
 pt2[x]=pt2[y]=5.0;pt2[z]=0.0;
 //如果有的話,擷取目前RICKFIRST選擇集,沒有則提供使用者選擇一個
 acedSSGet(NULL,NULL,NULL,NULL,ssname);
 //如果有的話,擷取目前RICKFIRST選擇集
 acedSSGet(“I”,NULL,NULL,NULL,ssname);
 //使用最近使用過的選擇集
 acedSSGet(“P”,NULL,NULL,NULL,ssname);
 //選擇最後加入到資料庫中的對象
 acedSSGet(“L”,NULL,NULL,NULL,ssname);
 //選擇通過點(5,5)的實體
 acedSSGet(NULL,pt2,NULL,NULL,ssname);
 //選擇從點(0,0)到點(5,5)的視窗中的實體
 acedSSGet(“W”,pt1,pt2,NULL,ssname);
 
 //選擇指定多邊形包圍的實體
 pt3[x]=10.0;pt3[y]=5.0;pt3[z]=0.0;
 pt4[x]=5.0;pt4[y]=pt4[z]=0.0;
 pointlist=acutBuildlist(RTPOINT,pt1, RTPOINT,pt2, RTPOINT,pt3, RTPOINT,pt4,0);
 acedSSGet(“WP”,pointlist,NULL,NULL,ssname);
 
 //選擇選擇從點(0,0)到點(5,5)的視窗内交叉的實體
 acedSSGet(“C”,pointlist,NULL,NULL,ssname);
 
 acutRelRb(pointlist);
 
 //選擇與指定栅欄交叉的實體
 pt4[y]=15.0;pt4[z]=0.0;
 pointlist=acutBuildlist(RTPOINT,pt1, RTPOINT,pt2, RTPOINT,pt3, RTPOINT,pt4,0);
 acedSSGet(“F”,pointlist,NULL,NULL,ssname);
 acutRelRb(pointlist);
           

對acedSSGet()的補充函數是acedSSFree(),它能在應用程式用完選擇集後釋放選擇集。選擇集是按名字來被使用的。對上面程式段中定義的ads_name,在這裡使用為:

acedSSFree(ssname);

注意:AutoCAD不能同時打開多于128個選擇集,包括運作中的ObjectARX和AutoLISP應用程式打開選擇集的總和。在不同的系統有可能有所不同。如果超過上限,AutoCAD拒絕建立選擇集。是以在不用選擇集時,應盡快用acedSSFree()釋放。

選擇集篩選表

當acedSSGet()函數的entmask參數明确記錄了實體的範圍值清單時,acedSSGet()掃描被選擇的實體,同時建立一個包含主實體名的選擇集,這些實體與篩選條件相比對。比如,使用這種方法,使用者可以得到一個給定的選擇集,這個選擇集包括給定的層、類型、顔色的所有實體。

篩選表可以與任何的選擇項聯合使用。如果用“X”選擇方式,意味着建立一個僅使用篩選表的選擇集。在AutoCAD以前的版本中,如果用“X”選項,acedSSGet()将掃描全部圖形資料庫。

注意:要是僅僅篩選表指定為“X”,而參數entmask是NULLL,則acedSSGet()選擇所有在資料庫中的實體。

參數entmask必須是一個結果緩沖區表。每一個緩沖區指定一個檢查參數和比對的值;緩沖區的restype段是一個DXF組碼,它指定要查詢的參數的種類,而緩沖區的restype域指定要比對的值。下面是相應的例子:

struct resbuf eb1,eb2,eb3;
char sbuf1[10],sbuf2[10];
ads_name ssname1,ssname2;
eb1.restype=0; //實體名
strcpy(sbuf1,”CIRCLE”);
eb1.resval.restring=sbuf1;
eb1.rbnext=NULL; //無其他内容
//檢索所有圓
acedSSGet(“X”,NULL,NULL,&eb1,ssname1);

eb2.restype=8;//層名
strcpy(sbuf2,”FLOOR3”);
eb2.resval.rstring=sbuf2;
eb2.rbnext=NULL;
//檢索在圖層FLOOR3上的所有實體
acedSSGet(“X”,NULL,NULL,&eb2,ssname2);
           

注意: 在每個緩沖區中指定的resval必須屬于合适的類型,比如:名字類型是字元串(resval.rstring);标高和厚度是雙精度浮點型(resval.rreal);顔色、屬性和标志值是短整型(resval.rint);拉伸向量是三維的點(resval.rpoint),等等。

如果entmask指定了多個參數,那麼隻有比對所有指定條件的實體才能被包含在選擇集裡。就象下面的例子:

eb2.restype=62;//實體顔色 
eb3.resval.rint=1;//紅色 
eb3.rbnext=NULL; 
eb1.rbnext=&eb2;//增加另外兩個條件 
eb2.rbnext=&eb3;//建立連結清單 
//檢索在圖層FLOOR3層上所有紅色的圓 
acedSSGet(“X”,NULL,NULL,&eb1,ssname1);
           

除非表中包括關系和條件操作符,否則實體的所有域都要被測試。

如果在資料庫中沒有實體與指定的篩選條件比對,函數acedSSGet()将傳回RTERROR。

前面關于acedSSGet()的例子用的是“X”選項,它掃描整個圖形資料庫;如果篩選表與其他選項(如使用者選擇、視窗選擇等)聯合使用,篩選條件隻能在被選中的實體上起作用。請看下面的一組例子:

篩選使用者選擇的實體:

eb1.restype=0;//實體類型組
 strcpy(sbuf1,”TEXT”);
 eb1.resval.rstring=sbuf1;//類型為TEXE
 eb1.rbnext=NULL;
 
 //讓使用者生成選擇集,但該選擇集中隻能有TEXT實體
 acedSSGet(NULL,NULL,NULL,&eb1,ssname1);
           

篩選前一個選擇集:

eb1.restype=0;//實體類型組
strcpy(sbuf1,”LINE”);
eb1.resval.rsting=sbuf1;//類型為LINE.
Eb1.rbnext=NULL;
 //選擇在上一個選擇集中符合條件的實體
acedSSGet(“P”,NULL,NULL,&eb1,ssname1);
           

在選擇視窗内篩選實體:

eb1.restype=8;//層
strcpy(sbuf1,”FLOOR8”);
eb1.resval.rstring=sbuf1;//層名
eb1.rbnext=NULL;
//選擇在視窗内并在FLOOR8層上的實體
acedSSGet("W", pt1, pt2, &eb1, ssname1); 
           

注意:某些組碼在不同的實體裡有不同的含義,并且不是所有的組碼都存在于所有的實體内。如果在篩選程式中指定一個特定的組碼,不包含該組碼的實體将被排除在acedSSGet()所傳回的選擇集之外。

篩選表中的通配符

篩選表中指定的符号可以包括通配符。由函數acedSSGet()織别的通配符與函數acutWcMatch()織别的通配符完全一樣。

例如,下面的程式代碼可以檢索一個名為K2的匿名塊:

eb2.restype=2;//塊名
strcpy(sbuf1,”*K2”);
eb2.resval.rstring=sbuf1;//匿名塊名
eb2.rbnext=NULL;
//選擇匿名塊*K2的塊插入引用
acedSSGet(“X”,NULL,NULL,&eb2,ssname1);
           

篩選擴充資料

擴充資料是字元串、資料、三維點、距離、層名,或者是其他附加在對象上得資料,特别是由外部應用程式附加到對象上得資料。

擴充資料大小為16KB。

通過指定,我們可以為一個特殊的應用程式使用-3組碼在篩選表中指定擴充資料來檢索擴充資料。例如:,函數acedSSGet()傳回一個以指定名字注冊的帶擴充資料的實體。acedSSGet()不檢索每個擴充資料項(組碼的範圍為1000—2000)。

下面程式用于選擇所有帶有擴充資料的圓(Circle),應用程式為這些擴充資料注冊的一個标志符(ID)為“APPNAME”。

eb1.restype=0;//實體類型
strcpy(sbuf1,”CIRCLE”);
eb1.resval.rstring=sbuf1;//實體為CIRCLE
eb1.rbnext=&eb2;
eb2.restype=-3;//擴充資料
eb2.rbnext=&eb3;
eb3.restype=1001;
strcpy(sbuf2,”APPNAME”);
eb3.resval.rstring=sbuf2;//APPNAME應用程式
eb3.rbnext=NULL;
//選擇注冊到APPNAME應用程式中的圓的擴充資料
acedSSGet(“X”,NULL,NULL,&eb1,ssname1);
           

如果不止一個應用程式名包含在表中,則acedSSGet()在選擇集中所包含實體,必須對所有指定的應用程式都有擴充資料。比如,下面的程式選擇帶有注冊到“APP1”和“APP2”中的擴充資料的圓。

eb1.restype=0;//實體類型
 strcpy(sbuf1,”CIRCLE”);
 eb1.resval.rstring=sbuf1;//圓
 eb1.rbnext=&eb2;
 
 eb2.restype=-3;//擴充資料
 eb2.rbnext=&eb3;
 eb3.restype=1001;
 strcpy(sbuf2,”APP1”);
 eb2.resval.restring=sbuf2;//應用程式APP1
 eb2.rbnext=&eb4;
 eb4.restype=1001;//擴充資料
 strcpy(sbuf3,”APP2”);
 eb4.resval.rstring=sbuf3;//應用程式APP2
 eb4.rbnext=NULL;
 //選擇注冊應用程式APP1和APP2的圓擴充資料
 acedSSGet(“X”,NULL,NULL,&eb1,ssname1);
           

下面的程式與上面的作用相同。

eb1.restype=0;
 strcpy(sbuf1,”CIRCLE”);
 eb1.resval.rstring=sbuf1;
 eb1.rbnext=&eb2;
 
 eb2.restype=-3;
 eb2.rbnext=&eb3;
 eb3.restype=1001;
 strcpy(sbuf2,”APP[12]”);//”APP[12]”
 eb3.resval.rstring=sbuf2;
 eb3.rbnext=NULL;
 //選擇注冊到APP1和APP2的圓的擴充資料
 acedSSGet(“X”,NULL,NULL,&eb1,ssname1);
           

關系檢測

除非使用者另外指定,在一個篩選表中的每一項與實體之間,有一個隐含的等量(equals)檢測,對于數字量(整數、實數值、點和向量),通過在篩選表中包括關系操作符,使用者可指定另外一些關系,關系操作符當做一個特殊的組(即-4組)傳遞,其值是一個在篩選表中将被應用于下一組檢測的字元串。

下面的程式可以挑選半徑大于等于2。0的圓:

eb3.restype=40;//半徑
 eb3.resval.rreal=2.0;
 eb3.rbnext=NULL;
 
 eb2.restype=-4;//篩選操作
 strcpy(sbuf1,”>=”);
 eb2.resval.rstring=&eb3;
 
 eb1.restype=0;//實體類型
 strcpy(sbuf2,”CIRCLE”);
 eb1.resval.rstring=sbuf2;//圓
 eb1.rbnext=&eb2;
 
 //選擇半徑大于等于2。0的圓
 acedSSGet(“X”,NULL,NULL,&eb1,ssname1);
           

條件篩選

條件操作符也可由-4組指定,但它們必須是配對的。下面的的程式用來挑選半徑為1。0的圓,并且在“ABC”層上的所有直線:

struct resbuf* prb;prb = acutBuildList(-4, "<or",-4, "<and", RTDXF0,    "CIRCLE", 40, 1.0, -4, "and>", -4, "<and", RTDXF0,     "LINE", 8, "ABC", -4, "and>", -4, "or>", 0); 
acedSSGet("X", NULL, NULL, prb, ssname1); 
           

條件操作符不是大小寫敏感的,可以使用小寫形式。

用于檢測擴充資料的條件表達式隻能包含-3組。為了選擇帶有寄存于“APP1”和“APP2”其中之一的擴充資料的所有圓,可以用以下程式來實作:

prb = acutBuildList(-4, "<xor", -3, "APP1", -3, "APP2",     -4, "xor>", 0); 
acedSSGet("X", NULL, NULL, prb, ssname1);