Example #1
0
        /// <summary>Checks intersection between two line segments. Line segments are fragments of lines with start and end point.</summary>
        /// <param name="lineSegment1"></param>
        /// <param name="lineSegment2"></param>
        /// <param name="intersectionPoint">The point on the first or second line segment.</param>
        /// <returns>Return true if lines intersects and if point is on the linesegments.</returns>
        public static bool LineSegmentToLineSegment(T3D.LineSegment lineSegment1, T3D.LineSegment lineSegment2, out T3D.Point intersectionPoint)
        {
            intersectionPoint = new T3D.Point();
            if (lineSegment1 == null | lineSegment2 == null)
            {
                return(false);
            }
            var line1 = new T3D.Line(lineSegment1);
            var line2 = new T3D.Line(lineSegment2);
            var intersectionLineSegment = T3D.Intersection.LineToLine(line1, line2);

            if (intersectionLineSegment == null)
            {
                return(false);
            }

            intersectionPoint = T3D.Projection.PointToLine(intersectionLineSegment.Point1, line1);
            if (!IsThePointOnTheLineSegment(lineSegment1, intersectionPoint))
            {
                return(false);
            }

            intersectionPoint = T3D.Projection.PointToLine(intersectionLineSegment.Point1, line2);
            if (!IsThePointOnTheLineSegment(lineSegment2, intersectionPoint))
            {
                return(false);
            }

            return(true);
        }
Example #2
0
        /// <summary>Checks if the point is on the line segment. Line segment is the fragment of line in 3d with start point and end point. Method should be private but in public may be usefull</summary>
        /// <param name="lineSegment">The line segment</param>
        /// <param name="point">The point to check</param>
        /// <returns>Return true if point is on the line segment between start and end point. Otherwise return false.</returns>
        public static bool IsThePointOnTheLineSegment(T3D.LineSegment lineSegment, T3D.Point point)
        {
            if (T3D.Distance.PointToPoint(lineSegment.Point1, point) < 0.1)
            {
                return(true);
            }
            if (T3D.Distance.PointToPoint(lineSegment.Point2, point) < 0.1)
            {
                return(true);
            }

            var vector1 = new T3D.Vector(lineSegment.Point1 - point);
            var vector2 = new T3D.Vector(lineSegment.Point2 - point);

            return(Math.Abs(vector1.GetAngleBetween(vector2) - Math.PI) < 0.001);
        }
Example #3
0
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                TransformationPlane currentTransformationPlane = model.GetWorkPlaneHandler().GetCurrentTransformationPlane();
                model.GetWorkPlaneHandler().SetCurrentTransformationPlane(new TransformationPlane());

                Tekla.Structures.Model.UI.Picker   picker      = new Tekla.Structures.Model.UI.Picker();
                Tekla.Structures.Model.ModelObject modelObject = picker.PickObject(Tekla.Structures.Model.UI.Picker.PickObjectEnum.PICK_ONE_PART);
                ArrayList array = new  ArrayList();
                array = picker.PickPoints(Tekla.Structures.Model.UI.Picker.PickPointEnum.PICK_TWO_POINTS, "");
                Tekla.Structures.Model.Part beam = (Tekla.Structures.Model.Part)modelObject;

                Phase phase = new Phase();
                beam.GetPhase(out phase);
                Tekla.Structures.Geometry3d.Point point1 = (Tekla.Structures.Geometry3d.Point)array[0];
                Tekla.Structures.Geometry3d.Point point2 = (Tekla.Structures.Geometry3d.Point)array[1];

                double offset = 0; double spacing = 0; double centres = 0;
                double.TryParse(textBox1.Text, out offset);
                double.TryParse(textBox2.Text, out spacing);
                double.TryParse(textBox3.Text, out centres);

                Tekla.Structures.Geometry3d.LineSegment lineSegment = new Tekla.Structures.Geometry3d.LineSegment(point1, point2);
                double count = (lineSegment.Length() - offset - 15) / spacing;
                count = Math.Truncate(count);

                if (checkBox1.Checked)
                {
                    ArrayList PartDblRepPropNames = new ArrayList();
                    PartDblRepPropNames.Add("PROFILE.WIDTH");
                    Hashtable dblProps = new Hashtable();
                    beam.GetDoubleReportProperties(PartDblRepPropNames, ref dblProps);
                    double length = (double)dblProps["PROFILE.WIDTH"];

                    if (length < 171)
                    {
                        MessageBox.Show("Warning: Flange to small");
                    }

                    BoltXYList staggeredBolt = new BoltXYList();
                    staggeredBolt.FirstPosition  = point1;
                    staggeredBolt.SecondPosition = point2;
                    staggeredBolt.PartToBoltTo   = beam;
                    staggeredBolt.PartToBeBolted = beam;

                    staggeredBolt.BoltSize     = 19.05;
                    staggeredBolt.Tolerance    = 2;
                    staggeredBolt.BoltStandard = "NELSON";
                    staggeredBolt.BoltType     = BoltGroup.BoltTypeEnum.BOLT_TYPE_WORKSHOP;
                    staggeredBolt.CutLength    = 100;

                    staggeredBolt.Length           = 100;
                    staggeredBolt.ExtraLength      = 100;
                    staggeredBolt.ThreadInMaterial = BoltGroup.BoltThreadInMaterialEnum.THREAD_IN_MATERIAL_YES;

                    staggeredBolt.Position.Depth    = Position.DepthEnum.MIDDLE;
                    staggeredBolt.Position.Plane    = Position.PlaneEnum.MIDDLE;
                    staggeredBolt.Position.Rotation = Position.RotationEnum.FRONT;

                    staggeredBolt.Bolt    = true;
                    staggeredBolt.Washer1 = staggeredBolt.Washer2 = staggeredBolt.Washer3 = staggeredBolt.Nut1 = staggeredBolt.Nut2 = false;

                    staggeredBolt.Hole1 = staggeredBolt.Hole2 = staggeredBolt.Hole3 = staggeredBolt.Hole4 = staggeredBolt.Hole5 = false;

                    staggeredBolt.StartPointOffset.Dx = offset;
                    staggeredBolt.AddBoltDistX(0);
                    staggeredBolt.AddBoltDistY(centres / 2);

                    int side = 1;
                    for (int i = 1; i <= count; i++)
                    {
                        side = side * -1;
                        staggeredBolt.AddBoltDistX(i * spacing);
                        staggeredBolt.AddBoltDistY(side * (centres / 2));
                    }

                    staggeredBolt.Insert();
                    staggeredBolt.SetPhase(phase);
                    staggeredBolt.Modify();
                }

                if (!checkBox1.Checked)
                {
                    BoltArray bolt = new BoltArray();
                    bolt.FirstPosition  = point1;
                    bolt.SecondPosition = point2;
                    bolt.PartToBoltTo   = beam;
                    bolt.PartToBeBolted = beam;

                    bolt.BoltSize     = 19.05;
                    bolt.Tolerance    = 2;
                    bolt.BoltStandard = "NELSON";
                    bolt.BoltType     = BoltGroup.BoltTypeEnum.BOLT_TYPE_WORKSHOP;
                    bolt.CutLength    = 100;

                    bolt.Length           = 100;
                    bolt.ExtraLength      = 100;
                    bolt.ThreadInMaterial = BoltGroup.BoltThreadInMaterialEnum.THREAD_IN_MATERIAL_YES;

                    bolt.Position.Depth    = Position.DepthEnum.MIDDLE;
                    bolt.Position.Plane    = Position.PlaneEnum.MIDDLE;
                    bolt.Position.Rotation = Position.RotationEnum.FRONT;

                    bolt.Bolt    = true;
                    bolt.Washer1 = bolt.Washer2 = bolt.Washer3 = bolt.Nut1 = bolt.Nut2 = false;

                    bolt.Hole1 = bolt.Hole2 = bolt.Hole3 = bolt.Hole4 = bolt.Hole5 = false;

                    bolt.StartPointOffset.Dx = offset;
                    bolt.AddBoltDistX(0);
                    bolt.AddBoltDistY(centres);

                    for (int i = 1; i <= count; i++)
                    {
                        bolt.AddBoltDistX(spacing);
                    }

                    bolt.Insert();
                    bolt.SetPhase(phase);
                    bolt.Modify();
                }
                model.GetWorkPlaneHandler().SetCurrentTransformationPlane(currentTransformationPlane);
                model.CommitChanges();
            }
            catch { }
        }
        //InterSectionTest 3
        private void button4_Click(object sender, EventArgs e)
        {
            //부재 선택
            Picker picker = new Picker();

            TSM.Part part             = picker.PickObject(Picker.PickObjectEnum.PICK_ONE_OBJECT, "철근형태를 수정할 부재를 선택하세요.") as TSM.Part;
            TSM.Part intersectingpart = picker.PickObject(Picker.PickObjectEnum.PICK_ONE_OBJECT, "간섭하는 부재를 선택하세요.") as TSM.Part;

            //Intersection 처리
            double partFrontLength    = 0.0;
            double intersectionLength = 0.0; //할당해야함

            TSG.OBB    iPartOBB    = CreateOrientedBoundingBox(intersectingpart);
            TSG.Vector partLVector = new TSG.Vector();

            if (part.GetType().Name == "Beam")
            {
                TSM.Beam        beam        = part as TSM.Beam;
                TSG.LineSegment lineSegment = new TSG.LineSegment(beam.StartPoint, beam.EndPoint);
                TSG.Point       firstPoint  = TSG.Intersection.LineSegmentToObb(lineSegment, iPartOBB).Point1;
                TSG.Point       secondPoint = TSG.Intersection.LineSegmentToObb(lineSegment, iPartOBB).Point2;

                partFrontLength    = TSG.Distance.PointToPoint(beam.StartPoint, firstPoint);
                intersectionLength = TSG.Distance.PointToPoint(firstPoint, secondPoint);
                partLVector        = new TSG.Vector(beam.EndPoint - beam.StartPoint).GetNormal();
            }
            else if (part.GetType().Name == "ContourPlate") //ContourPlate인 경우 추후 작성
            {
                TSM.ContourPlate contourPlate = part as TSM.ContourPlate;
            }

            //철근 그룹화 해제 후 singleRebar 저장
            ModelObjectEnumerator  reinforcement = part.GetReinforcements();
            List <TSM.SingleRebar> singleRebars  = new List <TSM.SingleRebar>();
            List <TSM.SingleRebar> group         = new List <TSM.SingleRebar>(); //그룹화를 위한 List

            int       rebarCount    = 0;                                         //총 단일철근 수량
            ArrayList rebarInterval = new ArrayList();                           //철근 간격 (싱글 타입일 때는 철근 간격을 어떻게 구하지? > 일단 PASS)

            while (reinforcement.MoveNext())
            {
                if (reinforcement.Current.GetType().Name == "SingleRebar") //부재에 속한 철근이 SingleRebar타입일 때
                {
                    TSM.SingleRebar singleRebar = reinforcement.Current as TSM.SingleRebar;
                    singleRebars.Add(singleRebar);

                    MessageBox.Show("SingleRebar 타입은 현재 지원 불가");
                }
                else //부재에 속한 철근이 RebarGroup타입일 때
                {
                    TSM.RebarGroup rebarGroup = reinforcement.Current as TSM.RebarGroup;
                    rebarInterval = rebarGroup.Spacings; //철근 간격 저장

                    TSM.ModelObjectEnumerator rebarEnumerator = TSM.Operations.Operation.Ungrouping(rebarGroup);
                    while (rebarEnumerator.MoveNext())
                    {
                        TSM.ModelObject rebar       = rebarEnumerator.Current;
                        TSM.SingleRebar singleRebar = rebar as TSM.SingleRebar;
                        singleRebars.Add(singleRebar);
                    }
                }
                rebarCount = singleRebars.Count; // 총 단일수량 저장
            }

            //철근 재배치
            for (int i = 0; i < singleRebars.Count - (intersectionLength / (double)rebarInterval[0]); i++) // 딱 안떨어지는 경우 고려해줘야함
            {
                double frontLength = (i * (double)rebarInterval[0]);

                if (frontLength >= partFrontLength)
                {
                    if (i == singleRebars.Count)
                    {
                        break;
                    }
                    else
                    {
                        for (int j = 0; j < singleRebars[i].Polygon.Points.Count; j++)
                        {
                            TSM.SingleRebar newSingleRebar = singleRebars[i];

                            TSG.Point intersectionLengthPoint = new TSG.Point(intersectionLength * partLVector.X, intersectionLength * partLVector.Y, intersectionLength * partLVector.Z);
                            newSingleRebar.Polygon.Points[j] = newSingleRebar.Polygon.Points[j] as TSG.Point + intersectionLengthPoint;
                            singleRebars[i].Delete();
                            newSingleRebar.Insert();

                            group.Add(newSingleRebar);
                        }
                    }
                }
                else
                {
                    group.Add(singleRebars[i]);
                }
            }

            for (int i = singleRebars.Count - (int)(intersectionLength / (double)rebarInterval[0]); i < singleRebars.Count; i++)
            {
                singleRebars[i].Delete();
            }

            TSM.RebarGroup newRebarGroup = TSM.Operations.Operation.Group(group);
        }
        //InterSectionTest 2
        private void button1_Click_1(object sender, EventArgs e)
        {
            //부재 선택
            Picker picker = new Picker();

            TSM.ModelObject  part         = picker.PickObject(Picker.PickObjectEnum.PICK_ONE_OBJECT, "부재를 선택하세요.") as TSM.ModelObject;
            TSM.ContourPlate contourPlate = part as TSM.ContourPlate;
            Solid            solid        = contourPlate.GetSolid();

            //철근 정보 받기
            //철근 선택 및 그룹철근 분할
            ModelObjectEnumerator  reinforcement = contourPlate.GetReinforcements();
            List <TSM.SingleRebar> singleRebars  = new List <TSM.SingleRebar>();
            List <TSM.SingleRebar> group         = new List <TSM.SingleRebar>(); //수정안된 철근

            while (reinforcement.MoveNext())
            {
                if (reinforcement.Current.GetType().Name == "SingleRebar")
                {
                    TSM.SingleRebar singleRebar = reinforcement.Current as TSM.SingleRebar;
                    singleRebars.Add(singleRebar);
                }
                else
                {
                    TSM.RebarGroup rebarGroup = reinforcement.Current as TSM.RebarGroup;

                    TSM.ModelObjectEnumerator rebarEnumerator = TSM.Operations.Operation.Ungrouping(rebarGroup);
                    while (rebarEnumerator.MoveNext())
                    {
                        TSM.ModelObject rebar       = rebarEnumerator.Current;
                        TSM.SingleRebar singleRebar = rebar as TSM.SingleRebar;
                        singleRebars.Add(singleRebar);
                    }
                }
            }

            //Intersect (마구리와 철근 겹치는 부분을 철근의 새 포인트로 지정한다.)
            TSG.LineSegment rebarLineSegment     = null;
            ArrayList       intersectLinesegment = new ArrayList();

            for (int j = 0; j < singleRebars.Count; j++) //철근 선택 반복문
            {
                TSG.Point       point1         = singleRebars[j].Polygon.Points[0] as TSG.Point;
                TSG.Point       point2         = singleRebars[j].Polygon.Points[1] as TSG.Point;
                TSM.SingleRebar newSingleRebar = singleRebars[j];

                if (singleRebars[j].Polygon.Points.Count == 2) //직선철근일때
                {
                    rebarLineSegment = new TSG.LineSegment(point1, point2);
                }

                intersectLinesegment             = solid.Intersect(rebarLineSegment);
                newSingleRebar.Polygon.Points[0] = intersectLinesegment[0] as TSG.Point;
                newSingleRebar.Polygon.Points[1] = intersectLinesegment[1] as TSG.Point;

                singleRebars[j].Delete();

                newSingleRebar.Insert();

                if (newSingleRebar.Polygon.Points[0] as TSG.Point == point1 && newSingleRebar.Polygon.Points[1] as TSG.Point == point2)
                {
                    group.Add(newSingleRebar);
                }
            }
            TSM.RebarGroup nonmodifiedGroup = TSM.Operations.Operation.Group(group);
        }
        //InterSectionTest 1
        private void button3_Click(object sender, EventArgs e)
        {
            //기본 객체 생성
            TSM.Part                girder       = null;
            TSM.Component           component    = new TSM.Component();
            TSM.Part                endPiece     = null;
            List <TSM.ContourPlate> endPieceList = new List <TSM.ContourPlate>();

            //1. 부재를 Input 으로 받는다.
            Picker picker = new Picker();

            TSM.ModelObject part = picker.PickObject(Picker.PickObjectEnum.PICK_ONE_OBJECT, "부재를 선택하세요.") as TSM.ModelObject;


            if (part.GetType().Name == "Beam") //선택한 거더가 단일객체일 경우
            {
                girder   = part as TSM.Beam;
                endPiece = picker.PickObject(Picker.PickObjectEnum.PICK_ONE_OBJECT, "부재를 선택하세요.") as TSM.ContourPlate; //연장할 마구리를 직접 선택

                //마구리 객체 OBB 생성 (추후 수정 - Girder 단일부재일 때도 마구리 1개이상 가능하므로)
                TSG.OBB         obb = CreateOrientedBoundingBox(endPiece); //마구리 OBB 객체 생성
                TSG.LineSegment rebarLineSegment = null;

                //철근 선택 및 그룹철근 분할
                ModelObjectEnumerator  reinforcement = girder.GetReinforcements();
                List <TSM.SingleRebar> singleRebars  = new List <TSM.SingleRebar>();
                List <TSM.SingleRebar> group1        = new List <TSM.SingleRebar>(); //수정된 철근
                List <TSM.SingleRebar> group2        = new List <TSM.SingleRebar>(); //수정안된 철근

                while (reinforcement.MoveNext())
                {
                    if (reinforcement.Current.GetType().Name == "SingleRebar") //부재 내 철근이 SingleRebar타입일때
                    {
                        TSM.SingleRebar singleRebar = reinforcement.Current as TSM.SingleRebar;
                        singleRebars.Add(singleRebar);
                    }
                    else //부재 내 철근이 rebarGroup타입일때
                    {
                        TSM.RebarGroup rebarGroup = reinforcement.Current as TSM.RebarGroup;

                        TSM.ModelObjectEnumerator rebarEnumerator = TSM.Operations.Operation.Ungrouping(rebarGroup);
                        while (rebarEnumerator.MoveNext())
                        {
                            TSM.ModelObject rebar       = rebarEnumerator.Current;
                            TSM.SingleRebar singleRebar = rebar as TSM.SingleRebar;
                            singleRebars.Add(singleRebar);
                        }
                    }
                }

                for (int j = 0; j < singleRebars.Count; j++) //철근 선택 반복문
                {
                    TSG.Point       rebarStartPoint = singleRebars[j].Polygon.Points[0] as TSG.Point;
                    TSG.Point       rebarEndPoint   = singleRebars[j].Polygon.Points[1] as TSG.Point;
                    TSM.SingleRebar newSingleRebar  = singleRebars[j]; //기존 철근을 삭제하고 형태가 변형된 새 철근 삽입

                    if (singleRebars[j].Polygon.Points.Count == 2)     //직선철근일때
                    {
                        rebarLineSegment = new TSG.LineSegment(rebarStartPoint, rebarEndPoint);
                    }

                    TSG.LineSegment intersectLine = TSG.Intersection.LineSegmentToObb(rebarLineSegment, obb); //만나는 점이 하나일 때 output 형태 > 두 점이 같은지점으로 찍힘

                    if (intersectLine != null)                                                                // 철근과 마구리가 만날때 / 한 점만 만날때는 Linesegment의 point1 과 point2 가 같은 값임
                    {
                        //철근 선을 연장
                        rebarLineSegment = new TSG.LineSegment(rebarStartPoint, rebarEndPoint + new TSG.Point(0, 100000, 0)); //추후 수정( y방향이 아니라 철근의 진행방향으로)
                        intersectLine    = TSG.Intersection.LineSegmentToObb(rebarLineSegment, obb);

                        //마구리 가까운쪽이 철근 Point1 인경우
                        if (intersectLine.Point1.Equals(intersectLine.Point2))
                        {
                            rebarLineSegment = new TSG.LineSegment(rebarStartPoint + new TSG.Point(0, 100000, 0), rebarEndPoint);
                            intersectLine    = TSG.Intersection.LineSegmentToObb(rebarLineSegment, obb);

                            newSingleRebar.Polygon.Points[0] = intersectLine.Point2;
                        }
                        else //마구리 가까운쪽이 철근 Point2 인경우
                        {
                            newSingleRebar.Polygon.Points[1] = intersectLine.Point2;
                        }
                        singleRebars[j].Delete();
                        newSingleRebar.Insert();
                        group1.Add(newSingleRebar);
                    }
                    else
                    {
                        group2.Add(singleRebars[j]); //수정안된 철근들 그룹에 넣기
                    }

                    TSM.RebarGroup modifiedGroup    = TSM.Operations.Operation.Group(group1);
                    TSM.RebarGroup nonmodifiedGroup = TSM.Operations.Operation.Group(group2);
                }
            }
            else if (part.ToString() == "Tekla.Structures.Model.Component") //선택한 거더가 컴포넌트일 경우
            {
                component = part as TSM.Component;

                //반환된 Girder의 타입 결정
                TSM.Assembly assembly = component.GetAssembly();
                if (assembly.GetMainPart().GetType().Name == "Beam")
                {
                    girder = assembly.GetMainPart() as TSM.Beam;
                }
                else if (assembly.GetMainPart().GetType().Name == "ContourPlate")
                {
                    girder = assembly.GetMainPart() as TSM.ContourPlate;
                }

                // Input으로 받은 부재에 연결되어있는 마구리와 철근정보를 받아온다.
                //반환된 Secondaries의 타입 결정

                endPieceList = new List <TSM.ContourPlate>();

                for (int i = 0; i < assembly.GetSecondaries().Count; i++)
                {
                    TSM.Part secondary = assembly.GetSecondaries()[i] as TSM.Part;

                    if (secondary.Name == "EndPiece")
                    {
                        endPieceList.Add(secondary as TSM.ContourPlate);
                    }
                }
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            // *기본 가정
            //  1) 슬라브를 배치할 두 빔은 평행
            //  2) 슬라브는 비스듬하게 배치되지 않음.(두빔에 항상 수직방향으로 배치됨)
            //  3) 슬라브는 z평면과 수평하게 배치됨
            TSM.Model currentModel = new TSM.Model();

            try
            {
                // 1. 슬라브 객체 생성
                ContourPlate contourPlate = new ContourPlate();

                // 2. 슬라브 생성할 두 부재 선택
                Picker          picker    = new Picker();
                TSM.ModelObject mainpart  = picker.PickObject(Picker.PickObjectEnum.PICK_ONE_PART, "슬라브를 삽입할 첫번째 부재를 선택하세요.");
                TSM.Beam        startBeam = mainpart as TSM.Beam;
                mainpart = picker.PickObject(Picker.PickObjectEnum.PICK_ONE_PART, "슬라브를 삽입할 두번째 부재를 선택하세요.");
                TSM.Beam endBeam = mainpart as TSM.Beam;

                // 3. 기본 방향벡터 생성
                //  1) StartBeam의 길이방향 단위벡터
                TSG.Vector startBeamLDirectionVector = new TSG.Vector(startBeam.EndPoint - startBeam.StartPoint).GetNormal();

                //  2) StartBeam의 높이방향 단위벡터-
                TSG.Vector startBeamHDirecitionVector = new TSG.Vector(0, 0, 1); //추후 기울어진 빔에도 적용가능하도록 변경

                //  EdgeEnumerator를 통해 StartBeam의 높이방향 단위벡터 구하기
                Solid solid = startBeam.GetSolid();
                if (solid != null)
                {
                    EdgeEnumerator edgeEnumerator = solid.GetEdgeEnumerator();
                    int            edgeCount      = 0;
                    while (edgeEnumerator.MoveNext())
                    {
                        var edge = edgeEnumerator.Current as Edge;
                        if (edge != null)
                        {
                            Console.WriteLine("Start : " + edge.StartPoint.ToString());
                            Console.WriteLine("End : " + edge.EndPoint.ToString());
                            Console.WriteLine("Type :" + edge.Type.ToString());

                            if (edgeCount == 8)
                            {
                                startBeamHDirecitionVector = new TSG.Vector((edge.EndPoint.X - edge.StartPoint.X) / 2, (edge.EndPoint.Y - edge.StartPoint.Y) / 2, (edge.EndPoint.Z - edge.StartPoint.Z) / 2).GetNormal();
                            }
                            edgeCount++;
                        }
                    }
                }

                //  3) StartBeam -> EndBeam 방향 단위벡터 (중점에서 중점 잇는 벡터)
                TSG.Point sbSP = startBeam.StartPoint;
                TSG.Point sbEP = startBeam.EndPoint;
                TSG.Point ebSP = endBeam.StartPoint;
                TSG.Point ebEP = endBeam.EndPoint;
                TSG.Point starBeamCenterPoint = new TSG.Point((sbSP.X + sbEP.X) / 2, (sbSP.Y + sbEP.Y) / 2, (sbSP.Z + sbEP.Z) / 2);
                TSG.Point endBeamCenterPoint  = new TSG.Point((ebSP.X + ebEP.X) / 2, (ebSP.Y + ebEP.Y) / 2, (ebSP.Z + ebEP.Z) / 2);

                TSG.Vector startBeamToEndBeamVector          = new TSG.Vector((ebSP.X + ebEP.X) / 2 - (sbSP.X + sbEP.X) / 2, (ebSP.Y + ebEP.Y) / 2 - (sbSP.Y + sbEP.Y) / 2, (ebSP.Z + ebEP.Z) / 2 - (sbSP.Z + sbEP.Z) / 2);
                TSG.Vector startBeamToEndBeamDirectionVector = new TSG.Vector((ebSP.X + ebEP.X) / 2 - (sbSP.X + sbEP.X) / 2, (ebSP.Y + ebEP.Y) / 2 - (sbSP.Y + sbEP.Y) / 2, (ebSP.Z + ebEP.Z) / 2 - (sbSP.Z + sbEP.Z) / 2).GetNormal();

                // 3. 슬라브 치수 및 기타속성 입력 ( 현재는 상수 )
                double slabWidthLeft   = 300;
                double slabWidthCenter = 300;
                double slabWidthRight  = 300;
                double slabThickness   = 100;
                double ribThickness    = 200;
                double ribDistUpper    = 50;
                double ribDistLower    = 30;
                double ribInterval     = ribDistUpper - ribDistLower;

                double startOffset = 100;
                contourPlate.Profile.ProfileString   = (startBeamToEndBeamVector.GetLength() - startOffset * 2).ToString();
                contourPlate.Material.MaterialString = "C24";

                // 4. 슬라브 시작점 설정
                //  1) 길이방향(일단은 startPoint점에서 시작하는걸로)
                String    direction      = "정방향"; //사용자가 직접 선택. 정방향 or 역방향
                TSG.Point slabStartPoint = new TSG.Point();

                if (direction == "정방향")
                {
                    slabStartPoint = startBeam.StartPoint;
                }
                else if (direction == "역방향")
                {
                    slabStartPoint            = startBeam.EndPoint;
                    startBeamLDirectionVector = startBeamLDirectionVector * -1;
                }

                //  2) 높이방향
                double heightConstant = 0.0;
                //depth type에 따른 슬라브 생성높이 변경
                if (startBeam.Position.Depth == Position.DepthEnum.FRONT)
                {
                    heightConstant = 1.0;
                }
                else if (startBeam.Position.Depth == Position.DepthEnum.MIDDLE)
                {
                    heightConstant = 0.5;
                }
                slabStartPoint += startBeamHDirecitionVector * ((Methods.GetGirderHeight(startBeam) * heightConstant + slabThickness + ribThickness));

                //  3) endBeam방향
                slabStartPoint += startBeamToEndBeamDirectionVector * (startOffset);

                // 5. 슬라브 포인트 입력
                List <TSG.Point> pointList = new List <TSG.Point>();

                pointList.Add(slabStartPoint);
                pointList.Add(pointList[0] + (startBeamHDirecitionVector * slabThickness * -1));
                pointList.Add(pointList[1] + (startBeamLDirectionVector * slabWidthLeft));
                pointList.Add(pointList[2] + (startBeamLDirectionVector * ribInterval) + (startBeamHDirecitionVector * ribThickness * -1));
                pointList.Add(pointList[3] + (startBeamLDirectionVector * ribDistLower));
                pointList.Add(pointList[4] + (startBeamLDirectionVector * ribInterval) + (startBeamHDirecitionVector * ribThickness));
                pointList.Add(pointList[5] + (startBeamLDirectionVector * slabWidthCenter));
                pointList.Add(pointList[6] + (startBeamLDirectionVector * ribInterval) + (startBeamHDirecitionVector * ribThickness * -1));
                pointList.Add(pointList[7] + (startBeamLDirectionVector * ribDistLower));
                pointList.Add(pointList[8] + (startBeamLDirectionVector * ribInterval) + (startBeamHDirecitionVector * ribThickness));
                pointList.Add(pointList[9] + (startBeamLDirectionVector * slabWidthRight));
                pointList.Add(pointList[10] + (startBeamHDirecitionVector * slabThickness));

                for (int i = 0; i <= 11; i++)
                {
                    contourPlate.AddContourPoint(new ContourPoint(pointList[i], null));
                }

                // 4. 슬라브 깊이타입 결정
                //  1) StartBeam 중앙에서 L,H Direction의 법선 벡터방향 으로 Line을 뻗어 EndBeam과 겹치는 부분이 있는지 확인
                //  2) 겹치면 깊이타입 Front , 겹치지 않으면 Back

                //  StartBeam 중앙에서 L,H Direction의 법선 벡터(외적 결과값)
                TSG.Vector crossResult = TSG.Vector.Cross(startBeamHDirecitionVector, startBeamLDirectionVector);

                //  외적벡터의 연장선
                TSG.Point       extendedPoint     = new TSG.Point(starBeamCenterPoint.X, starBeamCenterPoint.Y, starBeamCenterPoint.Z) + new TSG.Point(crossResult.X * 10000, crossResult.Y * 10000, crossResult.Z * 10000);
                TSG.LineSegment centerLineSegment = new TSG.LineSegment(starBeamCenterPoint, extendedPoint);

                //endBeam의 Plane 작성
                TSG.Vector         planeNormalVector = crossResult; //조건 중 startBeam과 endBeam이 평행하므로 평면을 구성하는 법선벡터 또한 같다.
                TSG.GeometricPlane endBeamPlane      = new TSG.GeometricPlane(endBeamCenterPoint, planeNormalVector);

                //두 line이 겹치는지 확인하는 Point (겹치면 값이 있고 안겹치면 값이 없음)
                TSG.Point isIntersect = TSG.Intersection.LineSegmentToPlane(centerLineSegment, endBeamPlane);
                if (isIntersect != null) // endBeam이 오른쪽에 있을 때
                {
                    if (direction == "정방향")
                    {
                        contourPlate.Position.Depth = Position.DepthEnum.BEHIND;
                    }
                    else if (direction == "역방향")
                    {
                        contourPlate.Position.Depth = Position.DepthEnum.FRONT;
                    }
                }
                else if (isIntersect == null) // endBeam이 오른쪽에 없을 때
                {
                    if (direction == "정방향")
                    {
                        contourPlate.Position.Depth = Position.DepthEnum.FRONT;
                    }
                    else if (direction == "역방향")
                    {
                        contourPlate.Position.Depth = Position.DepthEnum.BEHIND;
                    }
                }
                bool result = false;
                result = contourPlate.Insert();
                currentModel.CommitChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }