protected override void OnExecute(Command command, ExecutionContext context, Rectangle buttonRect) { Window window = Window.ActiveWindow; var allBodies = new List <IDesignBody>(); Document doc = window.Document; Part rootPart = doc.MainPart; Part pipesPart = Part.Create(doc, "Simplified Pipes"); Part brokenPipe = Part.Create(doc, "Broken Pipe"); int i; List <DesignBody> allDesignBodies = new List <DesignBody>(); List <DesignBody> brokenDesignBodies = new List <DesignBody>(); List <double> radii = new List <double>(); List <Color> chosen_colour; Component brokenComponent = Component.Create(rootPart, brokenPipe); //Selects the active window to work on and work on the solid bodies window.InteractionMode = InteractionMode.Solid; // ----------------------------------------------------------------- // Get the selected IDesign bodies // ----------------------------------------------------------------- var desBodies = window.ActiveContext.Selection; if (desBodies == null) { Debug.Fail("Unexpected case.", "Selection was not a single design body."); return; } // -------------------------------------------------------------- // Open up an output file inorder to write out for testing // -------------------------------------------------------------- //string outputfile = "H:/test_pipe_v2.txt"; //using (StreamWriter sw = File.CreateText(outputfile)) //{ // sw.WriteLine("OutputFile"); //} //----------------------------------------------------------------- // Get User defined requirement from dialogue box //----------------------------------------------------------------- #region Dialogue Information using (var dialogue = new PipeRadiusOptions()) { if (dialogue.ShowDialog() != DialogResult.OK) { return; } var nameAndRendering = new List <KeyValuePair <string, Graphic> >(); var partToGraphic = new Dictionary <Part, Graphic>(); var style = new GraphicStyle { EnableDepthBuffer = true }; if (dialogue.standardpipe) { Dictionary <string, List <double> > standard_pipes = StandardPipeDia.getStandardPipeDia(); radii = standard_pipes[dialogue.get_standard_dia + dialogue.get_schedule_num]; pipesPart = Part.Create(doc, "Simplified Pipes DN" + dialogue.get_standard_dia + "/" + dialogue.get_schedule_num); } else if (dialogue.userdefined) { radii.Add((double)dialogue.outRadius / 100.0); if (dialogue.hollow) { radii.Add((double)dialogue.inRadius / 100.0); pipesPart = Part.Create(doc, "Simplified Pipes OD=" + dialogue.outRadius.ToString() + " - ID=" + dialogue.inRadius.ToString() + " cm"); } else { pipesPart = Part.Create(doc, "Simplified Pipes OD=" + dialogue.outRadius.ToString() + " cm"); } } else { pipesPart = Part.Create(doc, "Simplified Pipes"); } chosen_colour = process_colour(dialogue.get_colour); } #endregion Component newComponent = Component.Create(rootPart, pipesPart); // -------------------------------------------------------------------- // // -------------------------------------------------------------------- foreach (IDesignBody desBody in desBodies) { //try to simplify try { DesignBody desBodyMaster = desBody.Master; Body currentBody = desBodyMaster.Shape; List <SpaceClaim.Api.V18.Geometry.Point> pointsList = new List <SpaceClaim.Api.V18.Geometry.Point>(); List <Circle> circleList = new List <Circle>(); List <Face> faceList = new List <Face>(); List <Plane> planeList = new List <Plane>(); //Find the end planes of the pipe List <Face> endFaces = findendFaces(currentBody); // foreach (Face endFace in endFaces) // { // DatumPlane newPlane = DatumPlane.Create(rootPart, "end Plane", endFace.GetGeometry<Plane>()); // FileWriter(outputfile, "plane"); // } // --------------------------------------------------------------- // If no user defined radii are given work out inner (if present) // and outer radii of the pipe // --------------------------------------------------------------- try { // If we are just using the pipe radii if (!radii.Any()) { radii = findRadii(endFaces.First()); } } catch { #region Dialogue Information using (var dialogue = new Pipes_Radius()) { if (dialogue.ShowDialog() != DialogResult.OK) { return; } var nameAndRendering = new List <KeyValuePair <string, Graphic> >(); var partToGraphic = new Dictionary <Part, Graphic>(); var style = new GraphicStyle { EnableDepthBuffer = true }; radii.Add((double)dialogue.outRadius); if (dialogue.hollow) { radii.Add((double)dialogue.inRadius); } } #endregion // FileWriter(outputfile, "Unable to find radii "); } //Start from the first end face in list and work along recording faces, circles and points findcircles(endFaces.First(), endFaces.Last(), out pointsList, out circleList, out faceList); //FileWriter(outputfile, "number of points"); //FileWriter(outputfile, "Number of points "+pointsList.Count().ToString()); // foreach (Point point in pointsList) // { // DatumPoint newPoint = DatumPoint.Create(rootPart, "Point", point); // } //For each toriodal face in the pipe create a new "inter" plane which can be used to cut the new cylindrical bodies //This also moves each of the points found at the end of the cylinders to a new position for (i = 0; i < faceList.Count; i++) { if (faceList[i].GetGeometry <Torus>() != null) { Plane firstplane; Plane secondplane; bool isreversedfirst; bool isreversedsecond; int round = 2; if (i == 0) { //FileWriter(outputfile, "Got Here --"); //Create a plane on one side of the tori from the circle and work out if the dirZ is reversed or not firstplane = endFaces.First().GetGeometry <Plane>(); isreversedfirst = endFaces.First().IsReversed; //DatumPlane newPlane = DatumPlane.Create(rootPart, "first Plane", firstplane); //Create a plane on the other side of the tori from the circle and work out if the dirZ is reversed or not Vector directionCylsecond; secondplane = createPlane(circleList[i + 1], pointsList[i + 1], pointsList[i + 2], round, out isreversedsecond, out directionCylsecond); //Move the cylinder points by the torus radius inorder to draw over the torus pointsList[i + 1] = pointsList[i + 1] + directionCylsecond.Direction.UnitVector * (faceList[i].GetGeometry <Torus>().MajorRadius + faceList[i].GetGeometry <Torus>().MinorRadius + 0.1); } else if (i == faceList.Count) { //FileWriter(outputfile, "Got Here \\"); //Create a plane on one side of the tori from the circle and work out if the dirZ is reversed or not Vector directionCylfirst; firstplane = createPlane(circleList[i], pointsList[i], pointsList[i - 1], round, out isreversedfirst, out directionCylfirst); //Create a plane on the other side of the tori from the circle and work out if the dirZ is reversed or not secondplane = endFaces.Last().GetGeometry <Plane>(); isreversedsecond = endFaces.Last().IsReversed; //Move the cylinder points by the torus radius inorder to draw over the torus pointsList[i] = pointsList[i] + directionCylfirst.Direction.UnitVector * (faceList[i].GetGeometry <Torus>().MajorRadius + faceList[i].GetGeometry <Torus>().MinorRadius + 0.1); } else { //Create a plane on one side of the tori from the circle and work out if the dirZ is reversed or not Vector directionCylfirst; firstplane = createPlane(circleList[i], pointsList[i], pointsList[i - 1], round, out isreversedfirst, out directionCylfirst); //Create a plane on the other side of the tori from the circle and work out if the dirZ is reversed or not Vector directionCylsecond; secondplane = createPlane(circleList[i + 1], pointsList[i + 1], pointsList[i + 2], round, out isreversedsecond, out directionCylsecond); //Move the cylinder points by the torus radius inorder to draw over the torus pointsList[i] = pointsList[i] + directionCylfirst.Direction.UnitVector * (faceList[i].GetGeometry <Torus>().MajorRadius + faceList[i].GetGeometry <Torus>().MinorRadius + 0.1); pointsList[i + 1] = pointsList[i + 1] + directionCylsecond.Direction.UnitVector * (faceList[i].GetGeometry <Torus>().MajorRadius + faceList[i].GetGeometry <Torus>().MinorRadius + 0.1); } double angle = 0; Vector3D unitvector; SpaceClaim.Api.V18.Geometry.Point pointonintesect; Plane interPlane = CreateInterPlane(firstplane, secondplane, isreversedfirst, isreversedsecond, out angle, out unitvector, out pointonintesect); planeList.Add(interPlane); } else { planeList.Add(null); } } //foreach (Point point in pointsList) //{ // DatumPoint newPoint = DatumPoint.Create(rootPart, "Point", point); //} //Draw out the new cylinders for each radii //Loop over each of the faces for (i = 0; i < faceList.Count(); i++) { //if the face is not a torus or it is the first or last face we need to draw it out if (faceList[i].GetGeometry <Torus>() == null || i == 0 || i == faceList.Count() - 1) { //List of the bodies for each cylinder (maybe an inner and outer cylinder List <Body> keepBodies = new List <Body>(); //for each of the pipe radii we will draw out a cylinder and split it on the relevant planes foreach (Double pipeRadius in radii) { //Create cylinder Body keepBody = createCylinder(faceList[i], endFaces.First(), endFaces.Last(), pipeRadius, i, faceList.Count(), pointsList[i + 1], pointsList[i]); //keepBody = newBody; //split cylinder on one of the relevant planes if (i > 0 && planeList[i - 1] != null) { keepBody = splitcylinder(keepBody, planeList[i - 1], circleList[i].Frame.Origin); } //Perform only if there is a torus at either end of the pipe if ((i == 0 || i == faceList.Count() - 1) && faceList[i].GetGeometry <Torus>() != null) { if (i == 0) { keepBody = splitcylinder(keepBody, planeList[i], circleList[i].Frame.Origin); } if (i == faceList.Count() - 1) { keepBody = splitcylinder(keepBody, planeList[i], circleList[i + 1].Frame.Origin); } } //split cylinder on second of the relevant planes if (i < planeList.Count - 1 && planeList[i + 1] != null) { keepBody = splitcylinder(keepBody, planeList[i + 1], circleList[i + 1].Frame.Origin); } keepBodies.Add(keepBody); } //transform the body back to its original position (if in a component) Matrix reverseTrans = desBody.TransformToMaster.Inverse; //FileWriter(outputfile, "Loop " + i + " of " + (faceList.Count() - 1).ToString()); //Draw out bodies allDesignBodies.AddRange(drawnbodies(keepBodies, reverseTrans, pipesPart, chosen_colour)); } } } //catch if we cannot simplify the pipe catch { Body brokenBody = desBody.Master.Shape.Copy(); Matrix reverseTrans = desBody.TransformToMaster.Inverse; brokenBody.Transform(reverseTrans); brokenDesignBodies.Add(DesignBody.Create(brokenPipe, "Broken Pipe", brokenBody)); } } var allbodies = pipesPart.Bodies; //FileWriter(outputfile, "Number of Bodies in part: " + allbodies.Count); }
protected override void OnExecute(Command command, ExecutionContext context, Rectangle buttonRect) { Window window = Window.ActiveWindow; var allBodies = new List <IDesignBody>(); Document doc = window.Document; Part rootPart = doc.MainPart; Part toriPart = Part.Create(doc, "Simp Tori"); double maxDiv; int maxCyl = 10; double cmtom = 0.01; var desBodies = window.ActiveContext.Selection; if (desBodies == null) { Debug.Fail("Unexpected case.", "Selection was not a single design body."); return; } // -------------------------------------------------------------- // Open up an output file inorder to write out for testing // -------------------------------------------------------------- /* string outputfile = "H:/tori.txt"; * using (StreamWriter sw = File.CreateText(outputfile)) * { * sw.WriteLine("OutputFile"); * } */ List <double> radii = new List <double>(); bool full_torus = false; bool end_planes = false; // Work out inner (if present) and outer radii of the pipe // List<double> radii = Pipesv2Capsule.findRadii(endFaces.First()); #region Dialogue Information using (var dialogue = new tori_simp()) { if (dialogue.ShowDialog() != DialogResult.OK) { return; } var nameAndRendering = new List <KeyValuePair <string, Graphic> >(); var partToGraphic = new Dictionary <Part, Graphic>(); var style = new GraphicStyle { EnableDepthBuffer = true }; if (dialogue.standardpipe) { Dictionary <string, List <double> > standard_pipes = StandardPipeDia.getStandardPipeDia(); radii = standard_pipes[dialogue.get_standard_dia + dialogue.get_schedule_num]; radii.Reverse(); } else if (dialogue.userdefined) { radii.Add((double)dialogue.Radius1 * cmtom); if (dialogue.radii2) { radii.Add((double)dialogue.Radius2 * cmtom); } if (dialogue.radii3) { radii.Add((double)dialogue.Radius3 * cmtom); } if (dialogue.radii4) { radii.Add((double)dialogue.Radius4 * cmtom); } } if (dialogue.fulltorus) { full_torus = true; } maxDiv = (double)dialogue.maximumCyl; } #endregion //maxCyl = 20; //radii.Add(0.02); //radii.Add(0.03); //radii.Add(0.04); // -------------------------------------------------------------------- // // -------------------------------------------------------------------- //FileWriter(outputfile, "Number of Bodies" + desBodies.Count()); foreach (IDesignBody desBody in desBodies) { DesignBody desBodyMaster = desBody.Master; Part currentPart = desBodyMaster.Parent; Body currentBody = desBodyMaster.Shape; int i; //Find all the toridal faces var tori = from currentface in currentBody.Faces where currentface.GetGeometry <Torus>() != null select currentface.GetGeometry <Torus>(); // if no radii are added just use the minor radius of the torus if (!radii.Any()) { radii.Add(tori.First().MinorRadius); } //Find all the planular faces var faces = from currentface in currentBody.Faces where currentface.GetGeometry <Plane>() != null select currentface; //Get planes for faces var planes = from face in faces where face.GetGeometry <Plane>() != null select face.GetGeometry <Plane>(); /* //Find intersection of torus with planes * Vector3D cir_U = new Vector3D(tori.First().MajorRadius * tori.First().Frame.DirX.UnitVector.X, tori.First().MajorRadius * tori.First().Frame.DirX.UnitVector.Y, tori.First().MajorRadius * tori.First().Frame.DirX.UnitVector.Z); * Vector3D cir_V = new Vector3D(tori.First().MajorRadius * tori.First().Frame.DirY.UnitVector.X, tori.First().MajorRadius * tori.First().Frame.DirY.UnitVector.Y, tori.First().MajorRadius * tori.First().Frame.DirY.UnitVector.Z); * Vector3D cir_c0 = new Vector3D(tori.First().Frame.Origin.Vector.X, tori.First().Frame.Origin.Vector.Y, tori.First().Frame.Origin.Vector.Z); * Vector3D plane1_N = new Vector3D(planes.First().Frame.DirZ.UnitVector.X, planes.First().Frame.DirZ.UnitVector.Y, planes.First().Frame.DirZ.UnitVector.Z); * Vector3D plane1_P = new Vector3D(planes.First().Frame.Origin.Vector.X, planes.First().Frame.Origin.Vector.Y, planes.First().Frame.Origin.Vector.Z); * List<Vector3D> inter_points = intersect_points(cir_c0, cir_U, cir_V, plane1_N, plane1_P); * DatumPoint.Create(rootPart,"point1", SpaceClaim.Api.V18.Geometry.Point.Create(inter_points.First().X, inter_points.First().Y, inter_points.First().Z)); * DatumPoint.Create(rootPart, "point2", SpaceClaim.Api.V18.Geometry.Point.Create(inter_points.Last().X, inter_points.Last().Y, inter_points.Last().Z)); */ //Use the Planular faces to work out where the end of the tori section is double anglediff; Vector3D startingVector = findStartAngle(tori.First(), planes.First(), planes.Last(), faces.First().IsReversed, faces.Last().IsReversed, out anglediff); //FileWriter(outputfile, "Starting Vec " + startingVector + " angle " + anglediff); //If we are doing a full torus then set the angle to 360 if (full_torus) { anglediff = 2 * Math.PI; } //Work out the maximum number of cylinders maxCyl = (int)Math.Ceiling(Math.Abs(anglediff / (maxDiv * Math.PI / 180))); //FileWriter(outputfile, "maxCyl " + maxCyl); //Create a list of points along the length of the Torus in order to split it up List <SpaceClaim.Api.V18.Geometry.Point> pointList = getPoints(tori.First(), startingVector, anglediff, maxCyl); //Create planes at each of the points List <Plane> cylplanes = makePlanes(pointList, maxCyl); //Create interplanes at the ends of each of the cylinders List <Plane> interplanes = new List <Plane>(); //dummy variables which aren't used double planeangle; Vector3D vecunit; SpaceClaim.Api.V18.Geometry.Point intersectpoint; // If we are using the original end planes use these else use interplane if (end_planes) { interplanes.Add(planes.First()); } else { interplanes.Add(Pipes_simp.CreateInterPlane(cylplanes[1], cylplanes[2], true, false, out planeangle, out vecunit, out intersectpoint)); } // Add rest of the interplanes for (i = 2; i < maxCyl - 1; i++) { interplanes.Add(Pipes_simp.CreateInterPlane(cylplanes[i * 2 - 1], cylplanes[i * 2], true, false, out planeangle, out vecunit, out intersectpoint)); } // If we are using the original end planes use these else use interplane if (end_planes) { interplanes.Add(planes.Last()); } else { interplanes.Add(Pipes_simp.CreateInterPlane(cylplanes[(maxCyl - 1) * 2 - 1], cylplanes[(maxCyl - 1) * 2], true, false, out planeangle, out vecunit, out intersectpoint)); } //Create cylinders along the tori List <Body> keepbodies = new List <Body>(); keepbodies = makeCylinders(pointList, maxCyl, radii, interplanes); //Subtract the inner cylinders from the others int j; //Subtract from each other for (i = 0; i < maxCyl; i++) { for (j = radii.Count() - 1; j > 0; j--) { keepbodies[j * maxCyl + i].Subtract(keepbodies[(j - 1) * maxCyl + i].Copy()); } } //Create design bodes in new components Matrix masterTransform = desBody.TransformToMaster; for (i = 0; i < radii.Count; i++) { toriPart = Part.Create(doc, "Simp Tori " + (i + 1).ToString()); SpaceClaim.Api.V18.Component newComponent = SpaceClaim.Api.V18.Component.Create(rootPart, toriPart); for (j = 0; j < maxCyl; j++) { DesignBody newBody = DesignBody.Create(toriPart, "newBody", keepbodies[i * maxCyl + j]); } //Cover back to master geometry newComponent.Transform(masterTransform.Inverse); } } }