Here you find code examples for using CADability.
Import, Analyse and Modify an existing drawing: Find all drill holes of a solid.
This example shows how to analyse a drawing or a model and recognize certain features.
Step 1: Create a new Windows Forms Application. Add a reference to CADability and with "Tools", "Choose Toolbox Items" select CADability.dll. This will create a "CADControl" item in the Toolbox.
Step 2: Drag the CADControl onto the form. In the property window set "ShowMenu" and "ShowToolbar" to "true".
Step 3: Next to the control create a button and name it "findDrillHoles" and double click the button to create an click event handler.
Step 4: Write some code for the click handler.
In the example below we expect that some drawing or model has already been loaded. . (In the file menu you can open a “step” or “iges” file, but you can also use ReadFromFile). The code first gets access to the Project and Model. Then all objects in the model are iterated. If there is a Solid, Shell or Face, it is further examinated. All cylindrical faces are collected in a list. Now the list gets further examined to combine faces that describe parts of the same hole. Finally solid cylinders are created with the same diameter and at the same location as the holes. The length of the newly created cylinders fill the holes totally. These cylinders are finally colored red and added to the model. You can select the original solid afterwards and delete it. Then you will see the holes as solid cylinders.
Source Code
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using CADability; using CADability.GeoObject; using CADability.Attribute; namespace WindowsFormsApplication2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// Method which is executed when the button "Find Drill Holes" is beeing pressed /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void findDrillHoles_Click(object sender, EventArgs e) { // it is assumed the project is already loaded, but you can load the Project with a line similar to // cadControl.Frame.Project = Project.ReadFromFile("...some file name ...", "stp"); Project project = cadControl.Frame.Project; // the curren Project displayed in the cadControl Model model = project.GetActiveModel(); // the active model in that project List<Face> allCylindricalFaces = new List<Face>(); // collect all cylindrical faces in the model foreach (IGeoObject go in model) { // iterate over all geometricl objects // only check Solids, Shells and Faces, maybe you would like to only check Solids if (go is Solid) allCylindricalFaces.AddRange(checkSolid(go as Solid)); else if (go is Shell) allCylindricalFaces.AddRange(checkShell(go as Shell)); else if (go is Face) { Face face = go as Face; if (face.Surface is CylindricalSurface) allCylindricalFaces.Add(face); } } // given all the faces find corresponding cylinders to "stuff" the holes Solid[] drillHoles = createDrillHoles(allCylindricalFaces); // make all cylinders red. ColorDef red = project.ColorList.CreateOrFind("red", Color.Red); for (int i = 0; i < drillHoles.Length; i++) { drillHoles[i].ColorDef = red; } // add the cylinders to the model model.Add(drillHoles); } /// <summary> /// Given a list of cylindrical faces, create cylinders that overlap the faces. /// There might be more than one face to a cylinder, which is checked here. /// </summary> /// <param name="allCylindricalFaces"></param> /// <returns></returns> private Solid[] createDrillHoles(IEnumerable<Face> allCylindricalFaces) { List<Solid> res = new List<Solid>(); // create empty list for the result HashSet<Face> setOfFaces = new HashSet<Face>(allCylindricalFaces); // put faces into a set for better access Face face = setOfFaces.FirstOrDefault<Face>(); // start with an arbitrary face while (face != null) { setOfFaces.Remove(face); // remove this face from the set BoundingRect extuv = face.GetUVBounds(); // get the bounds in the u/v system CylindricalSurface cyl1 = face.Surface as CylindricalSurface; // access the underlying cylindrical geometry // check whether this face is connected (at its edges) with another cylindrical face // with the same geometry (axis, radius). This is often the case, when the hole is modeled with // two half-shells foreach (Edge edge in face.AllEdges) { Face other = edge.GetBuddy(face); // the connected face if (other != null) { // when it exists if (other.Surface is CylindricalSurface) { // and when it also is a cylindrical face CylindricalSurface cyl2 = other.Surface as CylindricalSurface; // get acces to the cylindrical geometry ModOp2D secondToFirst; // matrix to convert from the second u/v system to the first if (cyl2.SameGeometry(other.GetUVBounds(),cyl1,face.GetUVBounds(),Precision.eps,out secondToFirst)) { // both faces describe the same cylinder, maybe with different u/v systems BoundingRect ext2 = other.GetUVBounds(); // the bounds in the second u/v system ext2.Modify(secondToFirst); // now in the first u/v/ system extuv.MinMax(ext2); // add to the accumulated extend setOfFaces.Remove(other); // remove this other face from the set } } } } GeoPoint startPoint = cyl1.Location+extuv.Bottom*cyl1.Axis; // startpoint of the cylinder axis GeoPoint endPoint = cyl1.Location+extuv.Top*cyl1.Axis; // endpoint of the cylinder axis res.Add(Make3D.MakeCylinder(startPoint, cyl1.XAxis, endPoint - startPoint)); // create a solid cylinder // and add it to the list face = setOfFaces.FirstOrDefault<Face>(); // for the next loop } return res.ToArray(); // return all cylinders } /// <summary> /// Find all the cylindrical faces in the provided Solid /// </summary> /// <param name="solid"></param> /// <returns></returns> private IEnumerable<Face> checkSolid(Solid solid) { List<Face> res = new List<Face>(); for (int i = 0; i < solid.Shells.Length; i++) { // iterate on all shells (there only a single shell in most cases) res.AddRange(checkShell(solid.Shells[i])); } return res; } private IEnumerable<Face> checkShell(Shell shell) { List<Face> res = new List<Face>(); for (int i = 0; i < shell.Faces.Length; i++) { // iterate all the faces of the shell // and add it to the result if it has a cylindrical geometry if (shell.Faces[i].Surface is CylindricalSurface) res.Add(shell.Faces[i]); } return res; } } }