Chapter 1
The program is developed an AutoCAD dynamic connection library, the following is the entry function of the dynamic connection library, responds to the two messages of AutoCAD in the entry function, namely Acrx :: KinitAppmsg and KunloadAppmsg, as shown below Paragraph
Extern "C" Acrx :: Appretcode
AcrxEntryPoint (Acrx :: Appmsgcode MSG, VOID * PKT) // Dynamic Library Inlet Function.
{
Switch (msg) {
Case Acrx :: KinitAppmsg:
// Comment Out The Following Line if Your
// Application Should Be Locked Into Memory
AcrxdyNamiClinker-> UnlockApplication (PKT);
AcrxdyNamiclinker-> Registerappmdiaware (PKT);
InitApplication (); // Initialization function
Break;
Case Acrx :: KunloadAppmsg:
UnloadApplication (); // Uninstall function
Break;
}
Return Acrx :: Kretok;
}
1, initialization function initApplication ()
Below is the code segment that the ARX wizard is automatically added.
VoidinitApplication () // Initialization function
{
// {{AFX_ARX_INIT
Addcommand ("Green", "DisplayWall", "Displaywall", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET | ACRX_CMD_NONTERNALLOCK, GREENDISPLAYWALL
Addcommand ("Green", "Scanroom", "Scanroom", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET | ACRX_CMD_NONTERNALLOCK, GREENSCANROOM
Addcommand ("Green", "Hightlight", "Hightlight", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET, GREENHHTLIGHT
Addcommand ("Green", "HighlightLine", "Highlightline", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET, GREENHHIGHLIGHTLINE
Addcommand ("Green", "CreatDoefile", "CreatDoefile", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET, GREENCREATDOEFILE
//}} AFX_ARX_INIT
}
In this code segment, the AutoCAD external command developed by the registered user is registered in this code segment, which is used to scan the line information in the project diagram, and display the wall of the analysis, and the walls of the analysis. Highlights the highlights of the room line and the highlighted display of the specific single wall. The following is an example of the function addcommand () of the registered external command in the code segment as an example of ScanRoom.
AddCommand ("Green", // Group name
"Scanroom", // The external name "scanroom", // registration command is the external name
ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET | ACRX_CMD_NOINTERNALLOCK, / / Command User Description
The function module called when the greenscanroom // command is executed
);
The above command Scanroom is executed when calling a function GreenScanRoom (), and the other commands in the initialization calls the function GreenDisplayWall (), GreenHightlightLight () and GreenHightlightLine ().
The GreenScanRoom () function is used to analyze various wall information using the information in the autocad diagram, and then the wall information is used to use a comprehensive map of support trees algorithm and node visible. The integrated algorithm of the sorting algorithm, identifies the various rooms in the design, and the detailed introduction of the top-down method forms wall information and the comprehensive algorithm to identify the detailed introduction of the room, there is a detailed C pseudo code in the author's paper, And there is a detailed comment in my source code segment. The function corresponding to different commands is introduced below.
1) Functions called when the scanroom command is executed Greenscanhood ()
The code of the function is as follows:
Void Greenscanroom ()
{
Scanlines ("Wall", False); / * The information obtained is saved in linehead, LINEHEAD is a global variable for saving the drawing information. * /
RefineLineset (); / * Preliminary processing of the obtained information, handling some problems due to obvious mapping * /
Clineset * mid = new clineset (); // * Generates a new central line collection for keeping the center line formed in the analysis * /
Clineset * midwall = new clineset (); // Generates a collection for saving the centerline of the intermediate wall.
Make_whole_zone_mid (& Linehead, MID, MIDWALL); / * Recovered the wall information using the top-down method * /
CUT_MIDDLE_ARC (); / / is an air function, reserved for processing of arcs
DisplayMID (MID); // Displays the center line in AutoCAD in AutoCAD.
LINEHEAD.FREESET (); /// Release the drawing information
MID-> freeset (); release center line occupied memory space
}
Here, you must focus on the Make_Whole_Zone_MID () function called in the function. In this function, its portal parameters are lines, which is a collection of saved line information, scanning information in this collection in the program. , Distinguish between walls and intermediate wall districts, for lines in the wall, use depressed points to identify the intermediate half wall, form a central line, to generate two directed center line, record to the entrance parameter Midwall In the collection
#define chendebug
Void make_whole_zone_mid (Clineset * Lines, Clineset * MID, Clineset * Midwall)
{
/ * ※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
Centralize the lines of the lines in the entire graphics, and add the center line of the wall to the MID chain.
For the intermediate wall to generate two centerlines, add to the Midwall chain list
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※ * / Clineset * Head = NULL, * GIVENLINE = NULL; / / Defining Head Pointer And give a line pointer
INT AMOUNT = 0;
ClineSet * p = null; // Defines the scan pointer
Clineset * p1 = NULL;
While (1) // looped to process the wall of the wall and the intermediate wall, until all line information is completed
{
Givenline = lines-> pnext;
LINES-> PNEXT = Givenline-> PNEXT;
Givenline-> PNext = NULL;
Head = FindlineCircle (Lines, Givenline, Amount); / * Take a given line as a parameter, wall district recognition * /
IF (amount == 4) // found a middle wall area
{
// make the mid line of all directions and add the midwall list
P = head-> pnext;
P1 = p-> pnext;
Clineset * tempmid = new clineset (p-> theline-> makemid (p1-> pnext-> theline));
Tempmid-> pnext = midwall-> pnexT;
Midwall-> pnext = tempmid;
P = P1;
P1 = p-> pnext;
Tempmid = new clineset (p-> theline-> makemid (p1-> pnext-> theline));
Tempmid-> pnext = midwall-> pnexT;
Midwall-> pnext = tempmid;
P = p1 = null; delete head;
}
Else / found a wall area
{
Double thrick = 0;
Clineset * midline = make_zone_midline (head, thick); / * Generate the centerline of half wall in the wall * /
CUT_MIDDLE_LINE (MIDLINE, Thick); / / Split the formed center line
Match_zone_mid (midline); // Apply minor integrity principle to match walls in a wall area
P = MIDLINE-> PNEXT;
While (P-> PNEXT) P = P-> PNEXT;
P-> PNEXT = MID-> PNEXT;
MID-> PNEXT = MIDLINE-> PNEXT;
MIDLINE-> PNEXT = NULL;
Delete midline;
}
Amount = 0;
IF (! lines-> pnext) Break;
}
// So the line scan is completed
Clineset * unmatched = new clineset (); / * Form a new collection that cannot match the line * /
Match_whole_map (mid, unmatched); / * Matching the centerline of all walls, using minimal integrity principles, matching successful lines Add to the MID collection, can not match the unmatched collection * /
FIX_WINDOWS (MID, MIDWALL); / / Installing the doors and windows, where Midwall is the collection of two centerlines of the intermediate wall.
Delete Midwall; // at Last Free The Memory THE MID WALL OCCUPIED
DEAL_WITH_ABNORMAL (MID, UNMATCHED); / / // Treat p = unmatched;
While (p-> pnext) p = p-> pnext; / * If there is no matching line to add it directly to the center line collection, display it to the user later, let the user processes. * /
IF (p)
{
P-> PNEXT = MID-> PNEXT;
MID-> pnext = unmatched-> pnext;
Unmatched-> pnext = null;
}
DELETE UNMATCHED;
}
The functions used in this function are as follows:
a) Clineset * FindlineCircle (Clineset * WholeList, Clineset * Givenline, Int & Amount)
This function is started with a given straight line Givenline as the starting line, searching with the starting line can enable the wall area or other straight lines of the wall area or half wall region in line set, and record the number of straight lines of the surrounding area, for the difference is half wall Regional retained wall district, distinguished characteristics, the number of straight lines enclosed in the half wall area is 4, and the number of walls is greater than 4. In the make_whole_zone_mid () function, the central line is simply generated in the middle wall, and the following function is further processed for the wall area. Searching linear organizations into a linear chain list for returning.
B) Clineset * make_zone_midline (Clineset * List, Double & Thickness)
This function is a given enclosure area, and the centerline of the wall is obtained into a linked list.
The parameter List is a line linked list that is wounded into the wall area after calling FindLineCircle (), and Thick is the wall thickness.
The function of this function is always split on the wall region with a handover of a wall and other walls, and forms the centerline of the divided wall forms its centerline, and the organizational module is returned. About this function Detailed description reference papers and source code.
C) Void Cut_Middle_Line (Clineset * Lines, Double & Thickness)
This function is used to segment the generated wall center line intersect the center line of the wall. Among them: MIDLINE is the center line chain list, the split new lines are still added to the list; Thick is the wall thickness;
d) void match_zone_mid (Clineset * MID)
This function is used for each wall of a wall to determine its state, and the state of one wall reflects whether there is any other wall through it.
E) void match_whole_map (Clineset * MID, Clineset * unmatched)
This function is used to match all walls that have no matching half walls in accordance with the minimum integrity principle, and cannot match the semi-walls to the unmached linked list, MID is the half-wall center line.
F) Void fix_windows (Clineset * Whole, ClineSet * Winlines)
This function is used to find their walls in the center line of the intermediate wall and split them out of the door. Where: MID is the center of the full wall, Midwall is the center line of the intermediate wall.
g) void deal_with_abnormal (Clineset * Whole, ClineSet * Abnormal)
This function is used to process some exception matches, that is, the calling function match_map () cannot make special processing, the principle of special processing, see the paper, detailed code reference source code.
The function GreenScanRoom () is called in the command scanroom. The function is called according to different conditions according to the different functions of the different order, and finally calls the function void displaymid (ClineSet * line), the wall of the wall and the door hole on the wall Lines, newly opened a layer ARX_WALL in AutoCAD If the analysis result is incorrect, let the user modifies on the new layer ARX_WALL.
2) DisplayWall command correspondence function
After executing the scanroom command, the center line of the expression wall is formed, and the displaywall command is called to analyze the center lines to form a room expressing the architectural plane space. This command lasts in the form of a dialog box to set the other non-geometric properties of the building space. . Below is the detailed source code of this function:
Void GreenDisplaywall ()
{
Myarcset * scanedarcset = new myarcset ();
ScanedarcSet-> PNEXTARC = ArcHead.pnexTarc; // Store the arc set in a new set
Archead.pnexTarc = null; // Empty the arc set getted before
Scanlines ("arx_wall", true); // Revenue the wall center line after user modification
Comparearc (& Archead, ScanedarcSet);
IF (ScanedarcSet-> PnexTarc) // The Scage Arc Set Is Not Empty Yet
{
// Find The Lines and make A Wall, And Use the line to make a win of itself
Find_line_arc_win (scanedarcset, & linehead);
}
// free the not found if any
Myarcset * p = scanedarcset-> pnexTarc, * p1 = null;
ScanedarcSet-> pnexTarc = null;
Delete scanedarcset;
While (p)
{
P1 = p-> pnextarc;
delete p; p = p1;
}
ARC_TO_LINE (& Archead, & linehead);
// gethouse (); // previously discarded functions
Room * Temp = Findroom (& linehead); // Call the Findroom function to form data expressing the construction space
Roomset.nextr = Temp-> NEXTR; // Tissue the found space into a list
#if Defined Chendebug // Test Information
{
Clineset * pcurrent = roomset.nextr-> Bases-> pnext;
ACDBENTINTITY * PEN = NULL;
ACDBOPENOBJECT (Pen, Pcurrent-> TheLine-> LineId, ACDB :: KforWrite, False);
Pen-> close ();
}
#ENDIF
TEMP-> NEXTR = NULL; DELETE TEMP;
RoomSet.make_whole_room (); // Set their various properties according to the nature of the room
Roomset.Setroomheight (FLOOR_HEIGHT); // the the rooms' Height in the roomset and set the massial stand of all walls
CacModulesourceOverride resoverride; // Register resources for dialog resource application Room * pr = roomset.nextr;
While (PR)
{
PR-> set_block (); // Pieces the ground in each room
Pr = Pr-> NEXTR;
}
PDLG = New LinedISPlayer ()); / * Assign dialog resources to display user interface * /
PDLG-> CREATE (IDD_DISPLAYER); // Create a dialog resource based on the reference number of the resource
PDLG-> ShowWindow (sw_show); // Display dialog box, enter the user interface
}
The following is an important function Room * Findroom (ClineSet * WholeLine) in this function.
Function FINDROOM () is used to achieve the division of the entire integrated planar basis, which calls the above functions. Where wholeLine is a linked list of the side of the entire topology map, which generates a response space and organizes into a spatial linked list for returning. The algorithm thoughts of this function are combined with the support trees and nodes visible side to rotate to sort, please refer to the paper, the following is the full source code of the function:
Room * Findroom (Clineset * WholeLine)
{
CMYPOINT * OLDLAYER = New CMYPOINT (), * NewLayer = New CMYPOINT (); / * Defines and opens the head node of two node layers * /
Clineset * p = null, * p1 = null, * p2 = null, * p3 = null; // line traversal pointer
Clineset * UPLINE = new clineset (); / * Used to record the side that has been accessed, called the upper line linked list * /
/ * Generate two nodes in the two endpoints of the first line in the linked list to the upper node layer and the new node layer, respectively, and transfer the line to the upper line chain list * /
P = wholeline; p1 = wholeline-> pnext;
P-> PNEXT = P1-> PNEXT;
P1-> pNext = UPLINE-> PNEXT; UPLINE-> PNEXT = P1;
NEWLAYER-> Next = new cmypoint (p1-> theline-> thee-> x, p1-> theline-> the-> y, 0); / * Generate the first node of the upper node layer * /
OldLayer-> NextPoint = new cmypoint (p1-> theline-> these> x, p1-> theline-> THES-> Y, 0);; / * Generate the first node of the new node layer * /
CMYPOINT * PP = NULL, * PP1 = NULL, * PP2 = NULL, * PP3 = NULL; / * Define node layer access pointer * /
Clineset * foundlist = null, * baselist = null; // Define nodes to access the border
Clineset * foundline = null; // Define the pointer to record the remaining tree
Room * Roomlist = new room (); // Define Links to Record Space
BOOL POINTFOUND = false; / / Define the flag variable that the node is accessible
Clineset * failedLine = new clineset (); / * Defines the line chain list, the record is temporarily unable to find the remaining tree side of the surface base field, called the failure chain table * /
CMYPOINT * NEWLAYERITERATOR = newLayer-> NextPoint; / * Define pointer to the new node layer final node * / while (1) // Start traversing the entire topology map
{
PP = OldLayer; // Initialization layer node pointer
PP1 = pp-> nextpoint;
While (pp1) // makes a broad traversal for each node in the upper node
{
/ / Looking for all straight lines through this point in the WholeLine Link
FoundList = FindlineTHROUGHPOINT (WholeLine, PP1);
If (! FoundList) // The remaining lines do not pass the straight line of this point,
{
PP = pp1; // Change condition Brand the next node in this layer
PP1 = PP1-> nextPoint; Continue;
}
P = FoundList; p1 = p-> pnext;
While (p1) // pair all edges through the current node
{
/ / Check if the other endpoint of the side is already in the upper and lower node chain tables, respectively.
PointFound = Checkpoint (p1-> theline-> the, * oldlayer);
IF (! PointFound) PointFound = Checkpoint (p1-> theline-> the, * newlayer);
If (! PointFound) // Access to the node is a new node
{
// Add this new node in the last addition of the next node linked list
NewLayeriterator-> NextPoint = New CMYPOINT
P1-> theline-> thee-> x, p1-> theline-> thee-> y, 0);
IF (! PointAdd) pointd = newLayerIterator;
NEWLAYERITERATOR = NewLayeriterator-> NextPoint;
}
ELSE // Traverage
{
Room * TemProom = GETROOMBASELIST (UPLINE, P1); / * Search Facial Foundation * /
IF (! temproom) // Looking for the surface base field failure
{
// Currently transferred to the failed chain table
Failedline-> pnext = p1; p-> pnext = p1-> pnext;
P1 = p-> pnext; company;
}
TemProom-> nextr = roomlist-> nextr; // Founded to find success
Roomlist-> nextr = TemProom; TemProom = NULL;
}
/ * Transfer the next edge to the upper side, and move the edge pointer to the next side of the node * /
P-> pnext = p1-> pnext; p1-> pnext = UPLINE-> PNEXT;
UPLINE-> PNEXT = P1; P1 = P-> PNEXT;
} // end while (p1) // End the traversal of the current node
PP = pp1; pp1 = pp1-> nextpoint; / * Mobile node pointer, traversal of the next node * /
} // end while (pp1), all nodes of the current layer are over
/ * Try to search for its corresponding spread field * / after all node of the current layer is accessed again
P = failedline;
While (P-> PNext) // The Point That Have Visited Failed At Searching for Room
{
P1 = p-> pnext;
Room * TemProom = GETROOMBASELIST (UPLINE, P1);
IF (TemProom)
{
Temproom-> nextr = roomlist-> nextr; roomlist-> nextr = TemProom; TemProom = NULL;
P-> pnext = p1-> pnext; p1-> pnext = UPLINE-> PNEXT;
UPLINE-> PNEXT = P1; P1 = P-> PNEXT;
}
Else
{P = p1; p1 = p1-> pnext;}
}
/ * The upper point has been searched, delete the point on the upper layer, the following layer is the new upper layer,
Re-loop, if there is no lower level, indicating that the whole process has been completed * /
// delet the point in the unlayer
PP = OldLayer; pp1 = pp-> nextpoint;
While (pp1)
{
PP-> NextPoint = pp1-> nextpoint;
PP1-> NextPoint = NULL; DELETE PP1;
PP1 = pp-> nextpoint;
}
IF (Foundlist)
{
Foundlist-> pnext = null;
DELETLODLIST; FOUNDLIST = NULL;
}
/ * If there are other nodes in the new node layer, the new node layer is the upper node layer, in-depth traversing * /
IF (newLayer-> NextPoint)
{
OldLayer-> NextPoint = newlayer-> nextpoint;
NEWLAYER-> NextPoint = NULL;
NEWLAYERITERATOR = NewLayer;
}
Else Break; / / Otherwise ending the entire travers
} // End while (1)
Delete Oldlayer, Delete Newlayer; // Free The Layer Node At Last
Return Roomlist; // Return to Space Links
}
This function first calls the function:
Clineset * FindlineTHROUGHPOINT (CLINESET * LINE, CMYPOINT * Thepoint)
With a given point as the starting point (gived the point is the first straight line in the LINE list, the specifically determined by the previous program), search all the straight lines passing through this point in the LINE chain, as a round of broadcasting can be accessed The node, the function adjusts the search straight line to the starting point and gives a fixed point, and returns all straight-line organizations.
Next, the search line end is processed, see if the new node or has already accessed the node, and add all the upper edges of the traversal of the traversal, and record the traversal support tree. The current layer and the previous layer are used to identify the nodes being accessed, and the nodes that have already been accessed, this call function:
Bool CheckPoint (CMYPOINT * GivenPoint, CMYPOINT POINTLIST) can make judgments, where givenpoint is a node accessed, and PointList is used to specify whether to search on the current layer or on the previous layer, the principle of search is first on the previous layer Search, no search is searched on the current layer. It is the new node to the current layer, otherwise the call function:
Room * getRoombaselist (Clineset * list, clineset * givenline)
among them:
List passes to the upper layer of the above, Givenline is the remaining tree of the discovery, and the function returns the verse field determined by the remaining tree. It is returned by generating a room with a face-based region. The function finally displays the user's non-geometric attribute input interface, and the report is left behind.
3) Command Hightlight's corresponding function Green GreenHightlight ()
Void GreenHightlight ()
{
If (PHighlight == PHighlight) // Judging whether the room to be highlighted and the highlight is the same room
{
Hightlight (PHIGHLIGHT, FALSE); // is, reverse this room is highlight, indicating that all highlights of the restore
Return;
}
IF (phighlighted) hightlight (pHIGHLIGHTED, FALSE); anti-highlighting the original room,
Highlight (PHIGHLIGHT, TRUE); highlights the selected room,
PHIGHLIGHTED = PHIGHLIGHT; // Record
PHIGHLIGHT = NULL;
}
This function cooperates with global traversal Room * Phighlight and Room * Phighlight a highlights in AutoCAD in AutoCAD in the user interface, where Phighlighted is used to save the room that is highlighted, and Phighlight is the room to be highlighted. This command is executed in the user interface to execute, specifically, first assign the PHIGHLIGHT global traversal, and then send a command, below:
PHIGHLIGHT = CURROOM; / / assignment to global variables
ACDOCMANAGER-> SendStringToExecute (ACDOCMANAGER-> Curdocument (),
"_hightlight", false, true); // Send a hightlight command
4) Command HightlightLine Corresponding Function GreenHightlightLine ()
Void GreenhightLine ()
{
IF (PHighlight )Hightlight (PHIGHLIGHTED, FALSE); // Unhanghlight All The Wall First
IF (ObjectId == HIGHEDID) Return; // The Same Line ID
ACDBENTINTITY * PEN = NULL;
ACDBOPENOBJECT (Pen, HighedId, ACDB :: KforWrite, True);
IF (Pen)
{
Pen-> unhanghlight ();
Pen-> close (); // close the pointer;
}
ACDBOPENOBJECT (Pen, ObjectID, ACDB :: KforWrite, True); // Open the New Object
IF (Pen)
{
Pen-> highlight ();
Pen-> close ();
HIGHEDID = ObjectId; // save
}
}
And the above highlights the basic functionality of the room, the difference is that the room is to highlight multiple lines, this function is just a highlight of the line of the selected wall. The same function is carried out with two global variables, and these two globally traverses:
ACDBOBJECTID ObjectId; // To perform highlight line ID number
ACDBOBJECTID HIGHEDID; // Highlights the straight line ID number
At this point, the command entry and function written in me are introduced!