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);
        }
Example #2
0
        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);
                }
            }
        }