![]() |
【转帖】objectarx&dummies教程(八)——selection sets
objectarx&dummies教程(八)——selection sets
objectarx&dummies教程(八)——selection sets class 8 - selection sets hello, on this class we will cover the first ways we can interact with user to allow our application to get information from drawing screen you probably will need to use this method inside your application. introduction this is one of the most important ways to interact with user because it will allow you to get information from drawing screen through selected entities. some times you will request user to select entities individually and sometimes you will select them using a filter. a selection set is a group of entities which are currently selected by an user or by an application. the most important concept involved when selecting entities from screen is that autocad will return their names through a type called ads_name. this type contains the entity name (which is valid only on the current session) and it can be converted to objectid using the acdbgetobjectid() global function: acad::errorstatus acdbgetobjectid (acdbobjectid& objid, const ads_name objname); this function receives the ads_name and convert it to an acdbobjectid. most of selection set functions will still use the ads_name as parameters and on theses cases you don't need to convert it. the ads_name can store several entities or just one. this will depend on how you or the user has performed the selection. the selection is made using a function called acedssget() which will apply a selection or prompt the user to do that. the function signature is: int acedssget (const char *str, const void *pt1, const void *pt2, const struct resbuf *entmask, ads_name ss); how to use it receives a selection option, two points, a mask and returns the resulting selection set. after use the selection set it needs to be released and this is done through the acedssfree() function the selection option will instruct autocad interface to do one of the following methods: selection code description null single-point selection (if pt1 is specified) or user selection (if pt1 is also null) # nongeometric (all, last, previous) :$ prompts supplied . user pick :? other callbacks a all b box c crossing cp crossing polygon :d duplicates ok :e everything in aperture f fence g groups i implied :k keyword callbacks l last m multiple p previous :s force single object selection only w window wp window polygon x extended search (search whole database) this way we can perform the selection by several ways. some examples are presented below: ads_point pt1, pt2; ads_name ssname; pt1[x] = pt1[y] = pt1[z] = 0.0; pt2[x] = pt2[y] = 5.0; pt2[z] = 0.0; // get the current pickfirst or ask user for a selection acedssget(null, null, null, null, ssname); // get the current pickfirst set acedssget("i", null, null, null, ssname); // repeat the previous selection set acedssget("p", null, null, null, ssname); // selects the last created entity acedssget("l", null, null, null, ssname); // selects entity passing through point (5,5) acedssget(null, pt2, null, null, ssname); // selects entities inside the window from point (0,0) to (5,5) acedssget("w", pt1, pt2, null, ssname); using selection filters filters are a powerful way to speed up selection sets and avoid runtime operations to verify entities. you can use single filters or composed filters. each filter is specified through a structure called resbuf. a resbuf is a linked list which store several types of information and may contains several items. to use a filter we need to construct it and pass it as a parameters of acedssget() method. the selection is performed but each selected entity will need to respect the filter. there are a lot of filters we can create and the sdk documentation cover all of them. the most used examples are presented below: struct resbuf eb1, eb2; char sbuf1[10], sbuf2[10]; ads_name ssname1, ssname2; eb1.restype = 0; // entity name filter strcpy(sbuf1, "circle"); eb1.resval.rstring = sbuf1; eb1.rbnext = null; // retrieve all circles acedssget("x", null, null, &eb1, ssname1); eb2.restype = 8; // layer name filter strcpy(sbuf2, "0"); eb2.resval.rstring = sbuf2; eb2.rbnext = null; // retrieve all entities on layer 0 acedssget("x", null, null, &eb2, ssname2); modifying entities through a selection set to modify entities inside a selection set we need to walk through selection items, get each one, convert the ads_name to an objectid, open the entity for write, modify it and then close it. this operation can also be done using a transaction which is, in long operations, much better. to show you how to walk through a selection set i will present a short code to select all circle entities inside the drawing and then change its color to red. the operation is pretty simple and is done this way: // construct the filter struct resbuf eb1; char sbuf1[10]; eb1.restype = 0; // entity name strcpy(sbuf1, "circle"); eb1.resval.rstring = sbuf1; eb1.rbnext = null; // select all circles ads_name ss; if (acedssget("x", null, null, &eb1, ss) != rtnorm){ acutrelrb(&eb1); return; } // free the resbuf acutrelrb(&eb1); // get the length (how many entities were selected) long length = 0; if ((acedsslength( ss, &length ) != rtnorm) || (length == 0)) { acedssfree( ss ); return; } ads_name ent; acdbobjectid id = acdbobjectid::knull; // walk through the selection set and open each entity for (long i = 0; i < length; i++) { if (acedssname(ss,i,ent) != rtnorm) continue; if (acdbgetobjectid(id,ent) != acad::eok) continue; acdbentity* pent = null; if (acdbopenacdbentity(pent,id,acdb::kforwrite) != acad::eok) continue; // change color pent->setcolorindex(1); pent->close(); } // free selection acedssfree( ss ); i have used some new functions (like acdbopenacdbentity) that are also part of objectarx sdk. pay attention to the memory releases regarding to selection set and resbuf types. note that i have used also a function called acedsslength() to get the length of selection set. the acedssname() function get an at the passed index. if we have more than one entity selected this loop will get every single entity into this selection set. see you next class. |
所有的时间均为北京时间。 现在的时间是 11:02 PM. |