The user may choose to put certain types of entities on certain layers.Layers can be turned off and on, so that their respective data can be viewed in or out of context with adjacent layers.All new graphic objects are added to the current layer. When you create a new drawing it will already have one layer named “0”. Adds a new layer into a drawing: HANDLE lcDrwAddLayer (HANDLE hDrw,LPCWSTR szName,LPCWSTR szColor,HANDLE hLinetype,int Linewidth); Parameters:hDrw(Handle to a drawing object.);szName(Layer name. Must be different from exist layers.);szColor(Layer color.);hLinetype(Handle to a linetype object. NULL for “Continuous” linetype.);Linewidth(Linewidth value.).
A linetype defines a line’s characteristics. A line can consist of combinations of dashes, dots, spaces and symbols. New entities are added to a drawing using the current linetype. When you create a new drawing it already has linetypes named “ByLayer”, “ByBlock”, and, “Continuous”.
Linetype definition In LiteCAD’s functions the Linetype data is manifested as a plotter-style instruction based upon simple ASCII text code.Linetypes can have dashes, blank spaces, dots and symbols.Each component of the line’s symbology is delimited by a comma in the text code string. The Dash characteristic is written as a positive number. The blank space characteristic is written as a negative number. A dot characteristic is written as a zero. Symbol based linetypes (complex linetypes) deviate from the previous definition in their inclusive content. Complex linetypes contain symbols and/or text strings, along with blank spaces, dots, and dashs as desired. Symbol descriptions are enclosed in brackets [ ]. The bracketed description has several components, once again, delimited by commas. The syntax of the info within the brackets are the next: [char code or name, font file, parameter=value, parameter=value, …] or [text, style, parameter=value, parameter=value, …] All possible parameters are described in the following table:
LiteCAD color can be a true color (24-bit RGB value) or index of a color palette.In objects properties it is represented as a text string. If a text string has 3 digital values (0-255) separated by commas, then color is a true color. If one value (1-255) - index color.On input, index value can be replaced by color name. Litecad recognises the following color names: “red” (same as “1”) “yellow” (same as “2”) “green” (same as “3”) “cyan” (same as “4”) “blue” (same as “5”) “magenta” (same as “6”) “foreground” (same as “7”) “gray” (same as “8”) “ltgray” (same as “9”) Also, for graphic objects, a special words can be used - “ByLayer” and “ByBlock”. “ByLayer” means the color assigned to a Layer will dictate the color of an object found on that particular Layer. “ByBlock” means the color assigned to a Block Reference object will dictate the color of an object added to the Block. If the object is not a part of block but has the “ByBlock” color assigned to it, the foreground color will be used to draw the object. Foreground color is defined by the LC_PROP_G_COLORFOREM and LC_PROP_G_COLORFOREP property.
Converts color value from string into integer components:BOOL lcColorToVal (LPCWSTR szColor,int pbRGB,int pIndex,int* pRed,int* pGreen,int* pBlue);** Parameters: szColor(Color value as string.);pbRGB(Pointer to variable that will receive “RGB” flag of the color.If received value is TRUE, then color is RGB color, if FALSE - index in color palette.);pIndex(Pointer to variable that will receive color index. The received value will be valid only for indexed color (bRGB=FALSE).The index value can be from 0 to 256, where 0 is “ByBlock” and 256 is “ByLayer” colors.);pRed pGreen pBlue(Pointers to variables that will receive Red, Green, Blue values of the color.). Samples:
lcPropPutStr( hLayer, LC_PROP_LAYER_COLOR, L"200,170,255" ); lcPropPutStr( hEnt, LC_PROP_ENT_COLOR, L"ByLayer" ); lcPropPutStr( hEnt, LC_PROP_ENT_COLOR, L"red" ); lcPropPutStr( hEnt, LC_PROP_ENT_COLOR, L"56" ); WCHAR szColor[32]; int bRGB, Index, R, G, B; wcscpy( szColor, lcPropGetStr(hEnt,LC_PROP_ENT_COLOR) ); lcColorToVal( szColor, &bRGB, &Index, &R, &G, &B );Defines filling style for closed entities. These are the functions used to manage filling styles in a drawing:lcDrwAddFilling(Adds a new filling style into a drawing);lcFillSetLine(Defines hatch line).
Create entities with semi-transparent filling
void DemoTranspFill (HANDLE hLcWnd) { HANDLE hDrw, hBlock, hTStyle, hEnt; // get a drawing and a block, linked with CAD window hDrw = lcPropGetHandle( hLcWnd, LC_PROP_WND_DRW ); hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // get active text style hTStyle = lcPropGetHandle( hDrw, LC_PROP_DRW_TEXTSTYLE ); // set font "Arial" lcPropPutStr( hTStyle, LC_PROP_TSTYLE_FONT, L"Arial" ); lcPropPutBool( hTStyle, LC_PROP_TSTYLE_SOLID, true ); // add bottom text (yellow) hEnt = lcBlockAddText2( hBlock, L"0123456789", 15.8, 36.9, LC_TA_CENTER, 5.0, 1.0, 45*LC_DEG_TO_RAD, false ); lcPropPutStr( hEnt, LC_PROP_ENT_COLOR, L"255,255,0" ); // add red rectangle hEnt = lcBlockAddRect( hBlock, 7,38, 30,20, 0, true ); lcPropPutStr( hEnt, LC_PROP_ENT_FCOLOR, L"255,0,0" ); lcPropPutInt( hEnt, LC_PROP_ENT_FALPHA, 120 ); // add green circle hEnt = lcBlockAddCircle( hBlock, 20,33, 10, true ); lcPropPutStr( hEnt, LC_PROP_ENT_FCOLOR, L"0,255,0" ); lcPropPutInt( hEnt, LC_PROP_ENT_FALPHA, 120 ); // add blue polygon hEnt = lcBlockAddPolyline( hBlock, 0, true, true ); lcPlineAddVer( hEnt, 0, 0,34 ); lcPlineAddVer( hEnt, 0, 8,54 ); lcPlineAddVer( hEnt, 0, 20,56 ); lcPlineAddVer( hEnt, 0, 39,40 ); lcPlineEnd( hEnt ); lcPropPutStr( hEnt, LC_PROP_ENT_FCOLOR, L"0,0,255" ); lcPropPutInt( hEnt, LC_PROP_ENT_FALPHA, 120 ); // update view lcBlockUpdate( hBlock, LC_TRUE, 0 ); // zoom extents lcWndZoomRect( hLcWnd, 0, 0, 0, 0 ); }The LiteCAD drawing object is the internal database representing a drawing. The database contains graphical objects (entities) and non-graphical (named objects). You must create at least one instance of a drawing object in your application. You can load a file into a drawing object or create a drawing programmatically. To view and interactively edit a drawing, an application must link it with a LiteCAD design window. When you are finished working with a drawing object you must delete its handle to free system memory allocated to it. Some functions used to manage LiteCAD drawing object:
Entities are visible graphical objects (lines, circles, raster images, and so on) that make up a drawing. Graphical objects have typical properties such as Identifier, Layer, Linetype, Color, etc. They also have specific properties, depending on their object type, such as, Center, Radius, and Area. 以往的文章已经介绍了所有的命名对象(named objects)和大部分图形对象(graphical objects),下面是剩下还没介绍过的图形对象。
A shape is a group of simple entities that acts as a single entity. There are types of entities that can be grouped into a shape:Line, Polyline, Rectangle,Circle, Arc, Ellipse. In order a shape can be filled, all grouped entities must make closed contours.
To add a shape into a drawing use following functions:lcBlockBeginShape(Indicates start of shape definition);lcBlockAddShape(Makes a shape from entities added into a block after lcBlockBeginShape function).
Create a shape entity
void DemoShape (HANDLE hLcWnd) { HANDLE hBlock, hEnt; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // begin Shape entity lcBlockBeginShape( hBlock ); // create entities that will be parts of Shape entity lcBlockAddCircle( hBlock, 10, 10, 5, false ); lcBlockAddCircle( hBlock, 30, 10, 5, false ); lcBlockAddRect2( hBlock, 0, 0, 40, 20, 5, false ); // add Shape entity hEnt = lcBlockAddShape( hBlock ); // set solid filling lcPropPutBool( hEnt, LC_PROP_ENT_SOLIDFILL, true ); lcPropPutStr( hEnt, LC_PROP_ENT_FCOLOR, L"0,255,255" ); // update view lcBlockUpdate( hBlock, true, 0 ); lcWndZoomRect( hLcWnd, -10, -10, 50, 30 ); }Create a shape entity
void DemoShape3 (HANDLE hLcWnd) { HANDLE hBlock, hEnt; double X, Y, X1, X2, Xc, Y1, Y2, Yc, H, R1, R2, R3, dd; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // begin Shape entity lcBlockBeginShape( hBlock ); // create entities that will be parts of Shape entity X1 = 90; X2 = 260; Y1 = 0; Y2 = 180; Yc = (Y2 + Y1) / 2.0; H = Y2 - Y1; R1 = H / 2.0; R2 = H / 4.0; R3 = (R1 - R2) / 5.0; // Fig 1 outside lcBlockAddArc( hBlock, X1, Yc, R1, LC_DEG90, LC_DEG180 ); lcBlockAddLine( hBlock, X1, Y1, X2, Y1 ); lcBlockAddArc( hBlock, X2, Yc, R1, LC_DEG270, LC_DEG180 ); lcBlockAddLine( hBlock, X2, Y2, X1, Y2 ); // Fig 2 inside 1 lcBlockAddArc(hBlock, X1, Yc, R2, LC_DEG90, LC_DEG180 ); lcBlockAddLine(hBlock, X1, Yc-R2, X2, Yc-R2 ); lcBlockAddArc(hBlock, X2, Yc, R2, LC_DEG270, LC_DEG180); lcBlockAddLine(hBlock, X2, Yc+R2, X1, Yc+R2); // circles inside of 1-2 dd = (R1 + R2) / 2.0; Xc = (X1 + X2) / 2.0; X = X1 - dd; lcBlockAddCircle( hBlock, X, Yc, R3, false ); X = X2 + dd; lcBlockAddCircle( hBlock, X, Yc, R3, false ); Y = Yc - dd; lcBlockAddCircle( hBlock, X1, Y, R3, false ); lcBlockAddCircle( hBlock, Xc, Y, R3, false ); lcBlockAddCircle( hBlock, X2, Y, R3, false ); Y = Yc + dd; lcBlockAddCircle( hBlock, X1, Y, R3, false ); lcBlockAddCircle( hBlock, Xc, Y, R3, false ); lcBlockAddCircle( hBlock, X2, Y, R3, false ); // add Shape entity hEnt = lcBlockAddShape( hBlock ); // set solid filling lcPropPutBool( hEnt, LC_PROP_ENT_SOLIDFILL, true ); lcPropPutStr( hEnt, LC_PROP_ENT_FCOLOR, L"0,255,0" ); // disable border line lcPropPutInt( hEnt, LC_PROP_ENT_LWIDTH, 0 ); // undate view lcBlockUpdate( hBlock, true, 0 ); lcWndZoomRect( hLcWnd, 0, 0, 0, 0 ); }lcBlockAddShapeSel(Makes a shape from selected entities); In order to create Shape from selected entities, use command LC_CMD_SHAPE
Create a shape entity from selected entities
void DemoShape5 (HANDLE hLcWnd) { HANDLE hBlock, hShape; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // make a shape from selected entities hShape = lcBlockAddShapeSel( hBlock, true ); // set solid filling lcPropPutBool( hShape, LC_PROP_ENT_SOLIDFILL, true ); lcPropPutStr( hShape, LC_PROP_ENT_FCOLOR, L"0,255,0" ); // disable border line lcPropPutInt( hShape, LC_PROP_ENT_LWIDTH, 0 ); // redraw view lcWndRedraw( hLcWnd ); }lcShapeAddEnt(Adds an entity into a shape);lcShapeEnd(Updates a shape after adding entities).
Create a shape entity from marked entities
void DemoShape6 (HANDLE hLcWnd) { HANDLE hBlock, hShape, hEnt; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // add Shape entity hShape = lcBlockAddShape( hBlock ); hEnt = lcBlockGetEntByKey( hBlock, 1 ); if (hEnt){ lcShapeAddEnt( hShape, hEnt, true ); } hEnt = lcBlockGetEntByKey( hBlock, 2 ); if (hEnt){ lcShapeAddEnt( hShape, hEnt, true ); } hEnt = lcBlockGetEntByKey( hBlock, 3 ); if (hEnt){ lcShapeAddEnt( hShape, hEnt, true ); } lcShapeEnd( hShape ); // set solid filling lcPropPutBool( hShape, LC_PROP_ENT_SOLIDFILL, true ); lcPropPutStr( hShape, LC_PROP_ENT_FCOLOR, L"0,255,0" ); // disable border line lcPropPutInt( hShape, LC_PROP_ENT_LWIDTH, 0 ); // redraw view lcWndRedraw( hLcWnd ); }Enumerate entities which make a shape. User selects shape entity, then calls this function:
void DemoShapeGetEnts (HANDLE hLcWnd) { HANDLE hBlock, hShape, hEnt, hVer, hPnt; int EntType; double X, Y; // get the block linked with graphics window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_VIEWBLOCK ); // get selected entity hShape = lcBlockGetFirstSel( hBlock ); if (hShape){ EntType = lcPropGetInt( hShape, LC_PROP_ENT_TYPE ); if (EntType == LC_ENT_SHAPE){ // get first entity of the shape hEnt = lcShapeGetFirstEnt( hShape ); while( hEnt != 0 ){ EntType = lcPropGetInt( hEnt, LC_PROP_ENT_TYPE ); if (EntType == LC_ENT_POLYLINE){ // get first vertex of a polyline hVer = lcPlineGetFirstVer( hEnt ); while( hVer != 0){ // add a point at polyline vertex X = lcPropGetFloat( hVer, LC_PROP_VER_X ); Y = lcPropGetFloat( hVer, LC_PROP_VER_Y ); hPnt = lcBlockAddPoint2( hBlock, X, Y, LC_POINT_CIRCLE, -0.75 ); lcPropPutInt( hPnt, LC_PROP_ENT_COLOR, RGB(100,255,0) ); // get next vertex of a polyline hVer = lcPlineGetNextVer( hEnt, hVer ); } } // get next entity of the shape hEnt = lcShapeGetNextEnt( hShape, hEnt ); } lcWndRedraw( hLcWnd ); } } }Create a shape entity from polylines
void DemoShapePlines (HANDLE hLcWnd) { HANDLE hBlock, hPline, hShape; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // begin Shape entity lcBlockBeginShape( hBlock ); // 1st polyline hPline = lcBlockAddPolyline( hBlock, 0, true, false ); lcPlineAddVer( hPline, 0, 10, 10 ); lcPlineAddVer( hPline, 0, 10, 90 ); lcPlineAddVer( hPline, 0, 90, 90 ); lcPlineAddVer( hPline, 0, 90, 10 ); lcPlineEnd( hPline ); // 2nd polyline hPline = lcBlockAddPolyline( hBlock, 0, true, false ); lcPlineAddVer( hPline, 0, 20, 20 ); lcPlineAddVer( hPline, 0, 20, 80 ); lcPlineAddVer( hPline, 0, 80, 20 ); lcPlineEnd( hPline ); // 3rd polyline hPline = lcBlockAddPolyline( hBlock, 0, true, false ); lcPlineAddVer( hPline, 0, 50, 80 ); lcPlineAddVer( hPline, 0, 80, 80 ); lcPlineAddVer( hPline, 0, 80, 60 ); lcPlineAddVer( hPline, 0, 50, 60 ); lcPlineEnd( hPline ); // add Shape entity hShape = lcBlockAddShape( hBlock ); // set solid filling lcPropPutBool( hShape, LC_PROP_ENT_SOLIDFILL, true ); lcPropPutStr( hShape, LC_PROP_ENT_FCOLOR, L"0,255,255" ); // update view lcBlockUpdate( hBlock, false, 0 ); lcWndExeCommand( hLcWnd, LC_CMD_ZOOM_EXT, 0 ); }Create a shape entity with hatch filling
void DemoShape4 (HANDLE hLcWnd) { HANDLE hDrw, hBlock, hFill, hEnt; double Xc, Yc, Size; WCHAR* szNameFill = L"Hatch 1"; // get a drawing and a block, linked with CAD window hDrw = lcPropGetHandle( hLcWnd, LC_PROP_WND_DRW ); hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // check if the filling style with specific name already exist hFill = lcDrwGetObjectByName( hDrw, LC_OBJ_FILLING, szNameFill ); if (hFill == 0){ // don't exist, add it hFill = lcDrwAddFilling( hDrw, szNameFill ); // define the hatch lines lcFillSetLine( hFill, 0, 1.0, 45.0*LC_DEG_TO_RAD, 0.5 ); lcFillSetLine( hFill, 1, 1.0, -45.0*LC_DEG_TO_RAD, 0.5 ); } Xc = 50; Yc = 25; Size = 20; // begin Shape entity lcBlockBeginShape( hBlock ); // Fig 1 outside lcBlockAddRect( hBlock, Xc, Yc, Size, Size, 0, false ); // Fig 2 inside lcBlockAddCircle( hBlock, Xc, Yc, Size/4.0, false ); // add Shape entity hEnt = lcBlockAddShape( hBlock ); // set filling style lcPropPutHandle( hEnt, LC_PROP_ENT_FILLING, hFill ); // undate view lcBlockUpdate( hBlock, true, 0 ); lcWndZoomRect( hLcWnd, Xc-Size, Yc-Size, Xc+Size, Yc+Size ); }Create Windows-rendered text This code sample demonstrates difference of rendering two text types - LC_ENT_TEXT and LC_ENT_TEXTWIN.
// Mode variants: // 0 - add new text style // 1 - modify "Standard" text style //----------------------------------------------- void DemoTextWin (HANDLE hLcWnd, int Mode) { HANDLE hDrw, hBlock, hTStyle; int Align; double X, Y, H, WScale, Angle, Oblique; WCHAR* szText = L"Hello World!"; WCHAR* szStyleName = L"My TextStyle"; // get drawing and block, linked with CAD window hDrw = lcPropGetHandle( hLcWnd, LC_PROP_WND_DRW ); hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); if (Mode == 0){ // get text style with specified name hTStyle = lcDrwGetObjectByName( hDrw, LC_OBJ_TEXTSTYLE, szStyleName ); if (hTStyle == NULL){ // the style don't exist, create new text style hTStyle = lcDrwAddTextStyle( hDrw, szStyleName, L"Times New Roman", true ); } }else{ // set font "Arial" for the text style "Standard" hTStyle = lcPropGetHandle( hDrw, LC_PROP_DRW_TEXTSTYLE_STD ); lcPropPutBool( hTStyle, LC_PROP_TSTYLE_WINFONT, true ); lcPropPutStr( hTStyle, LC_PROP_TSTYLE_FONT, L"Arial" ); lcPropPutBool( hTStyle, LC_PROP_TSTYLE_SOLID, true ); } // make this text style active lcPropPutHandle( hDrw, LC_PROP_DRW_TEXTSTYLE, hTStyle ); Align = LC_TA_CENBOT; // center-bottom X = 0.0; Y = 0.0; H = 5.0; Oblique = 0.0; WScale = 1.0; Angle = 0.0; lcBlockAddText2( hBlock, szText, X, Y, Align, H, WScale, Angle, Oblique ); Y = Y + (H * 1.5); lcBlockAddTextWin2( hBlock, szText, X, Y, Align, H, WScale, Angle, Oblique ); // update view lcBlockUpdate( hBlock, true, 0 ); lcWndExeCommand( hLcWnd, LC_CMD_ZOOM_EXT, 0 ); }To add 3D face object into a drawing use following functions: lcBlockAddFace(By 3 points) lcBlockAddFace4(By 4 points)
Clipping rectangles are used to clip rectangular parts of main drawing (Model space). The part can be saved as a bitmap or a file. There are functions: LC_CMD_CLIPRECTS - Command to call dialog “Clipping Rectangles”
HANDLE lcEntSplit (HANDLE hEntity,int nParts,BOOL bSelectNew,BOOL bDeleteEnt); Parameters: hEntity(Handle to a graphic object to be splitted.);nParts(A number of split parts. The value range is 2…1000.);bSelectNew(If TRUE then the derived entities will be added into selection set.);bDeleteEnt(If TRUE then the source entity will be deleted.).
Split entities
void DemoSplit (HANDLE hLcWnd) { HANDLE hBlock, hCirc, hArc, hEnt, hEntNext; int EntType, i, nArcs; double Xc, Yc, Xm, Ym, X2, Y2, Ang; bool bSplit = true; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_VIEWBLOCK ); // add 1st circle lcBlockAddCircle( hBlock, 0,0, 10, false ); // add 2nd circle hCirc = lcBlockAddCircle( hBlock, 30,30, 10, false ); lcPropPutFloat( hCirc, LC_PROP_CIRCLE_ANG0, 270 * LC_DEG_TO_RAD ); lcPropPutBool( hCirc, LC_PROP_CIRCLE_DIRCW, true ); // add 3rd circle hCirc = lcBlockAddCircle( hBlock, 60,0, 10, false ); lcPropPutFloat( hCirc, LC_PROP_CIRCLE_ANG0, 180 * LC_DEG_TO_RAD ); if (bSplit){ nArcs = 4; // number of arcs instead of a circle // split all circles on several arcs and offset the arcs hEnt = lcBlockGetFirstEnt( hBlock ); while( hEnt ){ // get next entity here, because lcEntSplit will insert // new entities instead of hEnt hEntNext = lcBlockGetNextEnt( hBlock, hEnt ); EntType = lcPropGetInt( hEnt, LC_PROP_ENT_TYPE ); if (EntType == LC_ENT_CIRCLE){ hArc = lcEntSplit( hEnt, nArcs, false, true ); if (hArc){ for (i=0; i<nArcs; ++i){ // get arc's center point Xc = lcPropGetFloat( hArc, LC_PROP_ARC_X ); Yc = lcPropGetFloat( hArc, LC_PROP_ARC_Y ); // get arc's middle point Xm = lcPropGetFloat( hArc, LC_PROP_ARC_XMID ); Ym = lcPropGetFloat( hArc, LC_PROP_ARC_YMID ); // offset arc's center lcGetPolarPrm( Xc, Yc, Xm, Ym, &Ang, 0 ); lcGetPolarPoint( Xc, Yc, Ang, 5.0, &X2, &Y2 ); lcPropPutFloat( hArc, LC_PROP_ARC_X, X2 ); lcPropPutFloat( hArc, LC_PROP_ARC_Y, Y2 ); lcEntUpdate( hArc ); // get next arc hArc = lcBlockGetNextEnt( hBlock, hArc ); } } } // go to next entuty hEnt = hEntNext; } } // display jump lines lcPropPutBool( hLcWnd, LC_PROP_WND_JUMPLINES, true ); // update view lcBlockUpdate( hBlock, false, 0 ); lcWndZoomRect( hLcWnd, -20, -20, 80, 50 ); }HANDLE lcEntBreak (HANDLE hEntity,double X,double Y,double Delta,BOOL bSelectNew,BOOL bDeleteEnt); Divides entity on 2 parts at specified point. The function can be applied to the following entity types: Line, Polyline, Arc . Parameters: hEntity(Handle to a graphic object to be splitted.);X Y(A point placed near entity outline. );Delta(Maximum allowed distance between entity outline and the point.);bSelectNew(If TRUE then the derived entities will be added into selection set.);bDeleteEnt(If TRUE then the source entity will be deleted.).
Break entities
void DemoBreak (HANDLE hLcWnd) { HANDLE hBlock, hEnt, hEnt2; double X, Y, Delta; int iCol; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_VIEWBLOCK ); hEnt = lcBlockGetFirstSel( hBlock ); if (hEnt){ Delta = lcPropGetFloat( hLcWnd, LC_PROP_WND_PICKBOXSIZE ); X = lcPropGetFloat( hLcWnd, LC_PROP_WND_CURSORX ); Y = lcPropGetFloat( hLcWnd, LC_PROP_WND_CURSORY ); hEnt2 = lcEntBreak( hEnt, X, Y, Delta, false, true ); if (hEnt2){ iCol = 20; while( hEnt2 ){ lcPropPutInt( hEnt2, LC_PROP_ENT_COLORI, iCol ); iCol+=7; hEnt2 = lcBlockGetNextEnt( hBlock, hEnt2 ); } lcBlockUpdate( hBlock, true, 0 ); lcWndRedraw( hLcWnd ); } } }Creates concentric circles, parallel lines, and parallel curves. The function can be applied to the following entity types: Line, Xline, Polyline, Arc, Circle,Ellipse,Rectangle. BOOL lcEntOffset (HANDLE hEntity,double Dist); Parameters: hEntity(Handle to a graphic object.);Dist(Offset distance. For circle, arc, ellipse, rectangle, negative value means offset to center side, positive - outside.For other objects negative value means left side, positive - right side (relative to the object direction).).
**BOOL lcEntAlign (HANDLE hEntity,int Alignment,double Xref,double Yref);**Moves a graphic object to a reference coordinate according alignment type. Parameters: hEntity(Handle to a graphic object.); Alignment(Alignment type. Can be one of the following values): Xref Yref(Reference point.).
Align entities
void DemoEntAlign (HANDLE hLcWnd) { HANDLE hBlock, hEnt; int Align, EntType; double X, Y; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_VIEWBLOCK ); X = 50.0; Y = 30.0; Align = LC_EA_TOP; // Align = LC_EA_RIGHT; // Align = LC_EA_CENTER; hEnt = lcBlockGetFirstEnt( hBlock ); while( hEnt ){ EntType = lcPropGetInt( hEnt, LC_PROP_ENT_TYPE ); if (EntType == LC_ENT_CIRCLE){ lcEntAlign( hEnt, Align, X, Y ); } hEnt = lcBlockGetNextEnt( hBlock, hEnt ); } lcBlockUpdate( hBlock, true, 0 ); lcWndRedraw( hLcWnd ); }Retrieves a point on a entity outline by distance from beginning. The function works with the following entity types: Line, Polyline, Arc, Circle.BOOL lcEntGetPoint (HANDLE hEnt,double Dist,double pX,double pY,double* pAngle);** Parameters: hEnt(Handle to an entity.);Dist(Distance from beginning.);pX pY(Pointers to variables that will receive the found point coordinates.);pAngle(Pointer to variable that will receive tangent angle at the found point.). Retrieve positions on a polyline by given distance from beginning.
void DemoEntDist (HANDLE hLcWnd) { HANDLE hBlock, hEnt, hLine; int nParts, i; double Len, Delta, Dist, X, Y, Angle, TickLen; double X1, Y1, X2, Y2; nParts = 10; TickLen = 0.5; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // get selected entity hEnt = lcBlockGetFirstSel( hBlock ); if (hEnt){ // get entity length Len = lcPropGetFloat( hEnt, LC_PROP_ENT_LEN ); if (Len > 0.0){ Delta = Len / nParts; Dist = 0.0; // add tick lines at division points for (i=0; i<=nParts; ++i){ if (lcEntGetPoint( hEnt, Dist, &X, &Y, &Angle )){ lcGetPolarPoint( X, Y, Angle+LC_DEG90, TickLen, &X1, &Y1 ); lcGetPolarPoint( X, Y, Angle-LC_DEG90, TickLen, &X2, &Y2 ); hLine = lcBlockAddLine( hBlock, X1, Y1, X2, Y2 ); lcPropPutInt( hLine, LC_PROP_ENT_COLOR, RGB(255,255,0) ); Dist += Delta; } } lcBlockUpdate( hBlock, true, 0 ); lcWndRedraw( hLcWnd ); } } }Searches intersection points of 2 graphic objects. The object types can be the following:Line, Construction line, Polyline, Rectangle, Circle, Arc, Ellipse. int lcIntersection (HANDLE hEnt,HANDLE hEnt2); Remarks: This function stores found intersection points in inner buffer. Retrieve points from the buffer by subsequent call of the lcInterGetPoint function.
Find the intersection points of objects Legend:
a drawing has a set of relief isolines on layer “Isolines”,a section line are placed on layer “0” and has a key “123” (in order to locate the line)we find points of intersection of the line with isolinesat place of intersection points we will add a Point entity and Text entity. The Text entity is unscalable, i.e. has constant size on a screen when a drawing is being scaled. void DemoIntersect (HANDLE hLcWnd) { HANDLE hDrw, hBlock, hEnt, hEnt2, hLayer, hLayer2, hTStyle, hPtStyle, hPnt, hLabel; int i, j, n; double x, y; WCHAR szNum[16]; WCHAR* szColor = L"255,0,0"; // get drawing and block, linked with CAD window hDrw = lcPropGetHandle( hLcWnd, LC_PROP_WND_DRW ); hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // get layer "Isolines" hLayer = lcDrwGetObjectByName( hDrw, LC_OBJ_LAYER, L"Isolines" ); // get textstyle "Labels" hTStyle = lcDrwGetObjectByName( hDrw, LC_OBJ_TEXTSTYLE, L"Labels" ); // get an entity which intersect isolines, it have a key "123" hEnt = lcBlockGetEntByKey( hBlock, 123 ); if (hLayer && hEnt && hTStyle){ // get current point style hPtStyle = lcPropGetHandle( hDrw, LC_PROP_DRW_PNTSTYLE ); // set points appearance (filled circle) lcPropPutInt( hPtStyle, LC_PROP_PSTYLE_PTMODE, LC_POINT_CIRCLE | LC_POINT_FILLED ); // point size, positive value - drawing's units, negative - nonscalable size lcPropPutFloat( hPtStyle, LC_PROP_PSTYLE_PTSIZE, -5.0 ); // meaning of negative LC_PROP_PSTYLE_PTSIZE: true - pixels; false - % of window height lcPropPutBool( 0, LC_PROP_G_PNTPIXSIZE, true ); // make textstyle "Labels" current, in order to create new text entities with this style lcPropPutHandle( hDrw, LC_PROP_DRW_TEXTSTYLE, hTStyle ); j = 1; // enumerate entities hEnt2 = lcBlockGetFirstEnt( hBlock ); while( hEnt2 ){ // get entity's layer hLayer2 = lcPropGetHandle( hEnt2, LC_PROP_ENT_LAYER ); if (hLayer2 == hLayer){ // find intersections, the function returns a number of intersection points n = lcIntersection( hEnt, hEnt2 ); if (n > 0){ for (i=0; i<n; i++){ lcInterGetPoint( i, &x, &y ); // add a point to a drawing hPnt = lcBlockAddPoint( hBlock, x, y ); // draw it to red color lcPropPutStr( hPnt, LC_PROP_ENT_COLOR, szColor ); lcPropPutStr( hPnt, LC_PROP_ENT_FCOLOR, szColor ); // add a label text _itow( j++, szNum, 10 ); // negative height value means pixel size instead of drawing units (to make text unscalable) hLabel = lcBlockAddText2( hBlock, szNum, x, y, LC_TA_CENBOT, -1, 0, 0, 0 ); // set pixels offset from insertion point (only for unscalable text) lcPropPutInt( hLabel, LC_PROP_TEXT_DX, 0 ); lcPropPutInt( hLabel, LC_PROP_TEXT_DY, 5 ); // set the label's color lcPropPutStr( hLabel, LC_PROP_ENT_COLOR, L"cyan" ); } } } // next entity hEnt2 = lcBlockGetNextEnt( hBlock, hEnt2 ); } lcBlockUpdate( hBlock, true, 0 ); lcWndRedraw( hLcWnd ); } }**int lcExpEntity (HANDLE hEntity,int Flags,BOOL bUnrotate);**Used to retrieve simple polylines of graphic object. This function copies the polylines into inner buffer.Coordinates of the polylines vertices can be retrieved with lcExpGetPline and lcExpGetVertex functions. **int lcExpGetPline (double Delta);**Selects a polyline for subsequent use of lcExpGetVertex function. BOOL lcExpGetVertex (double pX,double pY);**Retrieves a vertex coordinates of a polyline selected by lcExpGetPline function.First call of the function retrieves first vertex, next call - next vertex and so on until end vertex.
Retrieve vertices of entity’s outlines (of a circle)
void DemoExpEnt (HANDLE hLcWnd) { HANDLE hBlock, hEnt; double X, Y, R, dX; int i, nPlines, nVers, iVer; // get a block, linked with CAD window hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // add a circle entity X = 50.0; Y = 50.0; R = 10.0; hEnt = lcBlockAddCircle( hBlock, X,Y, R, false ); // get vertices of the circle's polyline lcPropPutInt( hEnt, LC_PROP_CIRC_RESOL, 16 ); nPlines = lcExpEntity( hEnt, LC_EXP_OUTLINE, false ); if (nPlines > 0){ dX = (R + R) * 1.1; // offset for new points for (i=0; i<nPlines; ++i){ nVers = lcExpGetPline( 0.0 ); for (iVer=0; iVer<nVers; ++iVer){ lcExpGetVertex( &X, &Y ); // add a point to indicate the vertex X = X + dX; lcBlockAddPoint2( hBlock, X, Y, LC_POINT_PIXEL|LC_POINT_CIRCLE, -0.5 ); } } } // set other resolution lcPropPutInt( hEnt, LC_PROP_CIRC_RESOL, 32 ); // get vertices of the circle's polyline nPlines = lcExpEntity( hEnt, LC_EXP_OUTLINE, false ); if (nPlines > 0){ dX *= 2.0; // offset for new points for (i=0; i<nPlines; ++i){ nVers = lcExpGetPline( 0.0 ); for (iVer=0; iVer<nVers; ++iVer){ lcExpGetVertex( &X, &Y ); // add a point to indicate the vertex X = X + dX; lcBlockAddPoint2( hBlock, X, Y, LC_POINT_PIXEL|LC_POINT_CIRCLE, -0.5 ); } } } // set adaptive resolution for the circle lcPropPutInt( hEnt, LC_PROP_CIRC_RESOL, -1 ); // display lcBlockUpdate( hBlock, true, 0 ); lcWndExeCommand( hLcWnd, LC_CMD_ZOOM_EXT, 0 ); }Retrieve vertices of entity’s outlines (of a text)
void DemoExpEnt2 (HANDLE hLcWnd) { HANDLE hDrw, hBlock, hTStyle, hEnt; double X, Y, H; int i, nPlines, nVers, iVer; WCHAR* szText = L&ABC&; WCHAR* szFont = L&Arial&; WCHAR szBuf[128]; // get drawing and block, linked with CAD window hDrw = lcPropGetHandle( hLcWnd, LC_PROP_WND_DRW ); hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_BLOCK ); // get active text style hTStyle = lcPropGetHandle( hDrw, LC_PROP_DRW_TEXTSTYLE ); // get font of the text style wcscpy( szBuf, lcPropGetStr( hTStyle, LC_PROP_TSTYLE_FONT )); if (wcscmp( szBuf, szFont ) != 0){ // set specified font for the text style lcPropPutStr( hTStyle, LC_PROP_TSTYLE_FONT, szFont ); lcPropPutBool( hTStyle, LC_PROP_TSTYLE_SOLID, true ); } // add a text entity X = 10.0; Y = 10.0; H = 10.0; hEnt = lcBlockAddText2( hBlock, szText, X,Y, LC_TA_LEFBOT, H, 1.0, 0.0, 0.0 ); lcPropPutInt( hEnt, LC_PROP_ENT_COLOR, RGB(150,255,255) ); lcPropPutInt( hEnt, LC_PROP_TEXT_RESOL, 3 ); // set colors for new entities (points) lcPropPutInt( hDrw, LC_PROP_DRW_COLORT, RGB(255,0,0) ); lcPropPutInt( hDrw, LC_PROP_DRW_FCOLORT, RGB(255,0,0) ); // get vertices of the text's polylines nPlines = lcExpEntity( hEnt, LC_EXP_OUTLINE, false ); if (nPlines > 0){ for (i=0; i<nPlines; ++i){ nVers = lcExpGetPline( 0.0 ); for (iVer=0; iVer<nVers; ++iVer){ lcExpGetVertex( &X, &Y ); // add a point to indicate the vertex lcBlockAddPoint2( hBlock, X, Y, LC_POINT_CIRCLE|LC_POINT_FILLED, -0.5 ); } } } // display lcBlockUpdate( hBlock, true, 0 ); lcWndExeCommand( hLcWnd, LC_CMD_ZOOM_EXT, 0 ); }Retrieve vertices of entity’s hatch lines (barcode)
void DemoBarcHatchAndGetLines (HANDLE hLcWnd) { HANDLE hDrw, hBlock, hFill, hEnt, hEntPline; WCHAR* szNameFill = L"Hatch 1"; WCHAR* szBcText = L"123"; double X, Y, X2, Y2, W, OffsetX, OffsetY; int nPlines, nVers, i, j, Step; // get drawing and block, linked with CAD window hDrw = lcPropGetHandle( hLcWnd, LC_PROP_WND_DRW ); hBlock = lcPropGetHandle( hLcWnd, LC_PROP_WND_VIEWBLOCK ); // check if the filling style with specific name already exist hFill = lcDrwGetObjectByName( hDrw, LC_OBJ_FILLING, szNameFill ); if (hFill == 0){ // don't exist, add it hFill = lcDrwAddFilling( hDrw, szNameFill ); lcFillSetLine( hFill, 0, 0.05, 45.0*LC_DEG_TO_RAD, 0.02 ); } // disable solid barcodes lcPropPutBool( hDrw, LC_PROP_DRW_BARCSOLID, false ); // set active color for barcode lcPropPutStr( hDrw, LC_PROP_DRW_COLOR, L"ByLayer" ); // Create QR-code filled with lines X = 10; // center of QR-code Y = 10; W = 8; // width and height of QR-code hEnt = lcBlockAddBarcode( hBlock, LC_BARTYPE_QR, X, Y, W, 0, szBcText ); lcPropPutInt( hEnt, LC_PROP_BARC_ECLEVEL, LC_BARC_QRECL_M ); lcPropPutFloat( hEnt, LC_PROP_BARC_OFFSET, 0.025 ); lcPropPutHandle( hEnt, LC_PROP_ENT_FILLING, hFill ); lcEntUpdate( hEnt ); // set active color for new entities lcPropPutStr( hDrw, LC_PROP_DRW_COLOR, L"255,0,0" ); // extract barcode outlines and hatch lines OffsetX = 8.5; OffsetY = 0.0; for (Step=0; Step<2; ++Step){ if (Step == 0){ // hatch lines nPlines = lcExpEntity( hEnt, LC_EXP_HATCH, false ); for (i=0; i<nPlines; ++i){ nVers = lcExpGetPline( 0.0 ); if (nVers == 2){ lcExpGetVertex( &X, &Y ); X = X + OffsetX; Y = Y + OffsetY; lcExpGetVertex( &X2, &Y2 ); X2 = X2 + OffsetX; Y2 = Y2 + OffsetY; lcBlockAddLine( hBlock, X, Y, X2, Y2 ); } } }else{ // outlines OffsetY = -OffsetX; OffsetX = 0; nPlines = lcExpEntity( hEnt, LC_EXP_OUTLINE, false ); for (i=0; i<nPlines; ++i){ hEntPline = lcBlockAddPolyline( hBlock, 0, false, false ); nVers = lcExpGetPline( 0.0 ); for (j=0; j<nVers; ++j){ lcExpGetVertex( &X, &Y ); X = X + OffsetX; Y = Y + OffsetY; lcPlineAddVer( hEntPline, 0, X, Y ); } lcPlineEnd( hEntPline ); } } } // update block lcBlockUpdate( hBlock, true, 0 ); // zoom extents lcWndZoomRect( hLcWnd, 0,0,0,0 ); }lcEntXData:Allocates extra data buffer inside of entity BOOL lcEntXData (HANDLE hEntity,int Id,int Flags,int nBytes); Parameters: hEntity(Handle to a graphic object.);Id(Application specific identifier of the extra data (entity property LC_PROP_ENT_XDATAID).The value varies from 0 to 10’000);Flags(Application specific flags (entity property LC_PROP_ENT_XDATAFLAGS));nBytes(Size of data buffer, in bytes (entity property LC_PROP_ENT_XDATASIZE)). Storing extra data in entities In order to locate the entity with extra data we use its key value (property LC_PROP_ENT_KEY) .
// sample data structure struct ENTXDATA { int Num; bool bCW; double Weight; double Prm[10]; WCHAR Name[32]; int Year; }; //----------------------------------------------- // Save information //----------------------------------------------- void DemoEntXDataPut (HANDLE hBlock) { HANDLE hEnt; int Key, Size, Id, Flags; WCHAR* szText = L"This string is stored in entity"; ENTXDATA MyData; Key = 101; hEnt = lcDrwGetEntByKey( hBlock, Key ); if (hEnt){ // write text data into the entity lcPropPutStr( hEnt, LC_PROP_ENT_XSTR, szText ); } // set fields of 'MyData' structure Size = sizeof(ENTXDATA); memset( &MyData, 0, Size ); MyData.Num = 15; MyData.bCW = true; MyData.Weight = 1000.0; MyData.Prm[0] = 5.6; MyData.Prm[1] = 7.8; MyData.Prm[2] = 9.123; wcscpy( MyData.Name, L"Samsung" ); MyData.Year = 2017; Key = 102; hEnt = lcDrwGetEntByKey( hBlock, Key ); if (hEnt){ // write binary data into the entity // allocate memory inside of the entity Id = 32; Flags = 9002; if (lcEntXData( hEnt, Id, Flags, Size )){ // write 'MyData' contents into the entity lcPropPutHandle( hEnt, LC_PROP_ENT_XDATA, &MyData ); } } // write binary data into entity using lcXData... functions Key = 103; hEnt = lcDrwGetEntByKey( hBlock, Key ); if (hEnt){ hData = lcXDataBegin(); lcPropPutBool( hData, LC_PROP_XDATA_BOOL, MyData.bCW ); lcPropPutInt( hData, LC_PROP_XDATA_INT, MyData.Num ); lcPropPutFloat( hData, LC_PROP_XDATA_FLOAT, MyData.Weight ); lcPropPutFloat( hData, LC_PROP_XDATA_FLOAT, MyData.Prm[0] ); lcPropPutFloat( hData, LC_PROP_XDATA_FLOAT, MyData.Prm[1] ); lcPropPutFloat( hData, LC_PROP_XDATA_FLOAT, MyData.Prm[2] ); lcPropPutStr( hData, LC_PROP_XDATA_STR, MyData.Name ); lcPropPutInt( hData, LC_PROP_XDATA_INT, MyData.Year ); Size = lcXDataEnd( hData); // allocate memory inside of the entity Id = 33; Flags = 9003; if (lcEntXData( hEnt, Id, Flags, Size )){ // write temporary buffer (hData) into the entity lcPropPutHandle( hEnt, LC_PROP_ENT_XDATA, hData ); } // free temporary buffer lcXDataClear( hData); } } //----------------------------------------------- // Retrieve information //----------------------------------------------- void DemoEntXDataGet (HANDLE hBlock) { HANDLE hEnt; int Key, Size, Size2, Id, Flags; BOOL bXStr; WCHAR szText[256]; ENTXDATA MyData; Key = 101; hEnt = lcDrwGetEntByKey( hBlock, Key ); if (hEnt){ // retrieve text data from the entity // check if XData contains text string bXStr = lcPropGetBool( hEnt, LC_PROP_ENT_XSTR ); if (bXStr){ // check if the size fits our buffer Size = lcPropGetInt( hEnt, LC_PROP_ENT_XDATASIZE ); if (0<Size && Size<256){ wcscpy( szText, lcPropGetStr( hEnt, LC_PROP_ENT_XSTR ) ); // now variable 'szText' contains stored text } } } Key = 102; hEnt = lcDrwGetEntByKey( hBlock, Key ); if (hEnt){ // retrieve binary data from the entity Id = lcPropGetInt( hEnt, LC_PROP_ENT_XDATAID ); Flags = lcPropGetInt( hEnt, LC_PROP_ENT_XDATAFLAGS ); Size = lcPropGetInt( hEnt, LC_PROP_ENT_XDATASIZE ); Size2 = sizeof(ENTXDATA); if (Size == Size2){ memcpy( &MyData, lcPropGetHandle( hEnt, LC_PROP_ENT_XDATA ), Size ); // now variable 'MyData' contains stored data } } // retrieve binary data from entity using lcXDataSet Key = 103; hEnt = lcDrwGetEntByKey( hBlock, Key ); if (hEnt){ Size = sizeof(ENTXDATA); memset( &MyData, 0, Size ); Id = lcPropGetInt( hEnt, LC_PROP_ENT_XDATAID ); Flags = lcPropGetInt( hEnt, LC_PROP_ENT_XDATAFLAGS ); Size = lcPropGetInt( hEnt, LC_PROP_ENT_XDATASIZE ); hData = lcPropGetHandle( hEnt, LC_PROP_ENT_XDATA ); lcXDataSet( hData ); // get data MyData.bCW = lcPropGetBool( hData, LC_PROP_XDATA_BOOL ); MyData.Num = lcPropGetInt( hData, LC_PROP_XDATA_INT ); MyData.Weight = lcPropGetFloat( hData, LC_PROP_XDATA_FLOAT ); MyData.Prm[0] = lcPropGetFloat( hData, LC_PROP_XDATA_FLOAT ); MyData.Prm[1] = lcPropGetFloat( hData, LC_PROP_XDATA_FLOAT ); MyData.Prm[2] = lcPropGetFloat( hData, LC_PROP_XDATA_FLOAT ); wcscpy( MyData.Name, lcPropGetStr( hData, LC_PROP_XDATA_STR )); MyData.Year = lcPropGetInt( hData, LC_PROP_XDATA_INT ); } }