示例#1
0
        public static bool IsPointInTriangle(Vector3d p, CadFace triangle, CadMesh mesh)
        {
            if (triangle.VList.Count < 3)
            {
                return(false);
            }

            Vector3d p0 = mesh.VertexStore[triangle.VList[0]].vector;
            Vector3d p1 = mesh.VertexStore[triangle.VList[1]].vector;
            Vector3d p2 = mesh.VertexStore[triangle.VList[2]].vector;

            Vector3d c1 = CadMath.CrossProduct(p, p0, p1);
            Vector3d c2 = CadMath.CrossProduct(p, p1, p2);
            Vector3d c3 = CadMath.CrossProduct(p, p2, p0);

            double ip12 = CadMath.InnerProduct(c1, c2);
            double ip13 = CadMath.InnerProduct(c1, c3);


            // When all corossProduct result's sign are same, Point is in triangle
            if (ip12 > 0 && ip13 > 0)
            {
                return(true);
            }

            return(false);
        }
示例#2
0
        public void CursorAngleY(double d)
        {
            double t = -CadMath.Deg2Rad(d) + Math.PI / 2;

            Controller.CrossCursor.DirY.X = Math.Cos(t);
            Controller.CrossCursor.DirY.Y = Math.Sin(t);
        }
示例#3
0
        //public CadVertex NewPoint()
        //{
        //    return default(CadVertex);
        //}

        //public CadFigure NewPolyLines()
        //{
        //    CadFigure fig = Controller.DB.NewFigure(CadFigure.Types.POLY_LINES);
        //    return fig;
        //}

        public void Rotate(uint figID, Vector3d org, Vector3d axisDir, double angle)
        {
            CadFigure fig = Controller.DB.GetFigure(figID);

            if (fig == null)
            {
                return;
            }

            if (axisDir.IsZero())
            {
                return;
            }

            //Controller.SelectFigure(figID);

            axisDir = axisDir.UnitVector();

            var list = new List <CadFigure>()
            {
                fig
            };

            Controller.StartEdit(list);

            RotateWithAxis(fig, org, axisDir, CadMath.Deg2Rad(angle));

            Controller.EndEdit(list);

            Session.PostRedraw();
        }
示例#4
0
        public async void FlipWithInteractive(List <CadFigure> rootFigList)
        {
            await Task.Run(() =>
            {
                Controller.StartEdit();
                var res = InputLine();

                if (res.state != InteractCtrl.States.END)
                {
                    Controller.AbendEdit();
                    return;
                }

                if ((res.p1 - res.p0).IsZero())
                {
                    Controller.AbendEdit();
                    ItConsole.println("Error: Same point");
                    return;
                }

                Vector3d normal = CadMath.Normal(
                    res.p1 - res.p0, (Controller.DC.ViewDir));

                FlipWithPlane(rootFigList, res.p0, normal);

                RunOnMainThread(() =>
                {
                    Controller.EndEdit();
                    Controller.Redraw();
                });
            });
        }
示例#5
0
        public void CursorAngleX(double d)
        {
            double t = -CadMath.Deg2Rad(d);

            Controller.CrossCursor.DirX.X = Math.Cos(t);
            Controller.CrossCursor.DirX.Y = Math.Sin(t);
        }
示例#6
0
        private void FaceToDirection(CadFigure fig, Vector3d org, Vector3d dir)
        {
            if (fig.Type != CadFigure.Types.POLY_LINES)
            {
                return;
            }

            Vector3d faceNormal = CadUtil.TypicalNormal(fig.PointList);

            if (faceNormal.EqualsThreshold(dir) || (-faceNormal).EqualsThreshold(dir))
            {
                // Face is already target direction
                return;
            }

            //   | 回転軸 rv
            //   |
            //   |
            //   | --------->向けたい方向 dir
            //   /
            //  /
            // 面の法線 faceNormal
            Vector3d rv = CadMath.Normal(faceNormal, dir);

            double t = CadMath.AngleOfVector(faceNormal, dir);

            CadUtil.RotateFigure(fig, org, rv, t);
        }
示例#7
0
        public CadFigure AddRectRectChamferAt(Vector3d p, double w, double h, double c)
        {
            Vector3d viewDir = Controller.DC.ViewDir;
            Vector3d upDir   = Controller.DC.UpVector;

            Vector3d wdir = CadMath.Normal(viewDir, upDir);
            Vector3d hdir = upDir.UnitVector();

            Vector3d wd = wdir * w;
            Vector3d hd = hdir * h;

            CadVertex sp = (CadVertex)p;
            CadVertex tp = sp;

            Vector3d wc = wdir * c;
            Vector3d hc = hdir * c;


            CadFigure fig = Controller.DB.NewFigure(CadFigure.Types.RECT);

            fig.AddPoint(tp + wc);

            tp += wd;

            fig.AddPoint(tp - wc);

            fig.AddPoint(tp + hc);

            tp += hd;

            fig.AddPoint(tp - hc);

            fig.AddPoint(tp - wc);

            tp = sp + hd;

            fig.AddPoint(tp + wc);

            fig.AddPoint(tp - hc);

            tp = sp;

            fig.AddPoint(tp + hc);

            fig.IsLoop = true;

            fig.EndCreate(Controller.DC);

            CadOpe ope = new CadOpeAddFigure(Controller.CurrentLayer.ID, fig.ID);

            Session.AddOpe(ope);
            Controller.CurrentLayer.AddFigure(fig);

            Session.PostRemakeObjectTree();

            return(fig);
        }
示例#8
0
        public static CadMesh CreateUnitCube(Vector3d wv, Vector3d hv, FaceType faceType = FaceType.TRIANGLE)
        {
            Vector3d tv = CadMath.Normal(wv, hv);

            Vector3d wv2 = wv / 2;
            Vector3d hv2 = hv / 2;
            Vector3d tv2 = tv / 2;

            CadMesh cm = new CadMesh(8, 12);

            cm.VertexStore.Add(CadVertex.Create(wv2 + hv2 + tv2));
            cm.VertexStore.Add(CadVertex.Create(-wv2 + hv2 + tv2));
            cm.VertexStore.Add(CadVertex.Create(-wv2 - hv2 + tv2));
            cm.VertexStore.Add(CadVertex.Create(wv2 - hv2 + tv2));

            cm.VertexStore.Add(CadVertex.Create(wv2 + hv2 - tv2));
            cm.VertexStore.Add(CadVertex.Create(-wv2 + hv2 - tv2));
            cm.VertexStore.Add(CadVertex.Create(-wv2 - hv2 - tv2));
            cm.VertexStore.Add(CadVertex.Create(wv2 - hv2 - tv2));

            if (faceType == FaceType.QUADRANGLE)
            {
                cm.FaceStore.Add(new CadFace(0, 1, 2, 3));

                cm.FaceStore.Add(new CadFace(7, 6, 5, 4));

                cm.FaceStore.Add(new CadFace(0, 4, 5, 1));

                cm.FaceStore.Add(new CadFace(1, 5, 6, 2));

                cm.FaceStore.Add(new CadFace(2, 6, 7, 3));

                cm.FaceStore.Add(new CadFace(3, 7, 4, 0));
            }
            else
            {
                cm.FaceStore.Add(new CadFace(0, 1, 2));
                cm.FaceStore.Add(new CadFace(2, 3, 0));

                cm.FaceStore.Add(new CadFace(7, 6, 5));
                cm.FaceStore.Add(new CadFace(5, 4, 7));

                cm.FaceStore.Add(new CadFace(0, 4, 5));
                cm.FaceStore.Add(new CadFace(5, 1, 0));

                cm.FaceStore.Add(new CadFace(1, 5, 6));
                cm.FaceStore.Add(new CadFace(6, 2, 1));

                cm.FaceStore.Add(new CadFace(2, 6, 7));
                cm.FaceStore.Add(new CadFace(7, 3, 2));

                cm.FaceStore.Add(new CadFace(3, 7, 4));
                cm.FaceStore.Add(new CadFace(4, 0, 3));
            }

            return(cm);
        }
示例#9
0
        public async void RotateWithInteractive(List <CadFigure> rootFigList)
        {
            await Task.Run(() =>
            {
                Controller.StartEdit();
                var res = InputPoint();

                if (res.state != InteractCtrl.States.END)
                {
                    Controller.AbendEdit();
                    return;
                }

                Vector3d p0 = res.p0;

                double angle = 0;

                bool ok = false;

                RunOnMainThread(() =>
                {
                    AngleInputDialog dlg = new AngleInputDialog();
                    bool?dlgRet          = dlg.ShowDialog();

                    ok = dlgRet.Value;

                    if (ok)
                    {
                        angle = dlg.GetDouble();
                    }
                });

                if (!ok)
                {
                    ItConsole.println("Cancel!");

                    Controller.AbendEdit();
                    return;
                }

                RotateWithAxis(
                    rootFigList,
                    p0,
                    Controller.DC.ViewDir,
                    CadMath.Deg2Rad(angle));

                Controller.EndEdit();

                RunOnMainThread(() =>
                {
                    Controller.Redraw();
                    Controller.UpdateObjectTree(remakeTree: false);
                });
            });
        }
示例#10
0
        //
        // Calculate the intersection point in the screen coordinate system
        // スクリーン座標系での交点を求める
        //
        public static Vector3d CrossOnScreen(DrawContext dc, Vector3d wp00, Vector3d wp01, Vector3d wp10, Vector3d wp11)
        {
            Vector3d sp00 = dc.WorldPointToDevPoint(wp00);
            Vector3d sp01 = dc.WorldPointToDevPoint(wp01);
            Vector3d sp10 = dc.WorldPointToDevPoint(wp10);
            Vector3d sp11 = dc.WorldPointToDevPoint(wp11);

            Vector3d cp = CadMath.CrossLine2D(sp00, sp01, sp10, sp11);

            return(cp);
        }
示例#11
0
        public void CutMesh(uint id)
        {
            CadFigureMesh tfig = GetCadFigureMesh(id);

            if (tfig == null)
            {
                ItConsole.println("invalid ID");
                return;
            }

            (Vector3d p0, Vector3d p1) = InputLine();

            if (p0.IsInvalid() || p1.IsInvalid())
            {
                return;
            }


            HeModel he  = tfig.mHeModel;
            CadMesh src = HeModelConverter.ToCadMesh(he);

            Vector3d normal = CadMath.Normal(
                p1 - p0, (Controller.DC.ViewDir));

            (CadMesh m1, CadMesh m2) = MeshUtil.CutMeshWithVector(src, p0, p1, normal);


            CadFigureMesh fig1 = (CadFigureMesh)Controller.DB.NewFigure(CadFigure.Types.MESH);

            fig1.SetMesh(HeModelConverter.ToHeModel(m1));

            CadFigureMesh fig2 = (CadFigureMesh)Controller.DB.NewFigure(CadFigure.Types.MESH);

            fig2.SetMesh(HeModelConverter.ToHeModel(m2));

            CadOpe ope;

            ope = new CadOpeAddFigure(Controller.CurrentLayer.ID, fig1.ID);
            Session.AddOpe(ope);
            Controller.CurrentLayer.AddFigure(fig1);

            ope = new CadOpeAddFigure(Controller.CurrentLayer.ID, fig2.ID);
            Session.AddOpe(ope);
            Controller.CurrentLayer.AddFigure(fig2);

            ope = new CadOpeRemoveFigure(Controller.CurrentLayer, tfig.ID);
            Session.AddOpe(ope);
            Controller.CurrentLayer.RemoveFigureByID(tfig.ID);

            Controller.ClearSelection();

            Session.PostRemakeObjectTree();
        }
示例#12
0
        public void SetSelectedSegLen(double len)
        {
            if (Controller.LastSelSegment == null)
            {
                return;
            }

            MarkSegment seg = Controller.LastSelSegment.Value;

            if (seg.FigureID == 0)
            {
                return;
            }

            CadFigure fig = Controller.DB.GetFigure(seg.FigureID);

            CadVertex pa = fig.GetPointAt(seg.PtIndexA);
            CadVertex pb = fig.GetPointAt(seg.PtIndexB);

            Vector3d v;

            v = pa.vector - Controller.LastDownPoint;
            double da = v.Norm();

            v = pb.vector - Controller.LastDownPoint;
            double db = v.Norm();


            if (da < db)
            {
                Vector3d np = CadMath.LinePoint(pb.vector, pa.vector, len);
                Controller.StartEdit();

                pa.vector = np;

                fig.SetPointAt(seg.PtIndexA, pa);

                Controller.EndEdit();
            }
            else
            {
                Vector3d np = CadMath.LinePoint(pa.vector, pb.vector, len);
                Controller.StartEdit();

                pb.vector = np;

                fig.SetPointAt(seg.PtIndexB, pb);

                Controller.EndEdit();
            }
        }
示例#13
0
        // 三角形の追加
        // 左右回り方を統一して追加するようにする
        public void AddTriangle(int v0, int v1, int v2)
        {
            HalfEdge he0 = mHeModel.CreateHalfEdge(v0);
            HalfEdge he1 = mHeModel.CreateHalfEdge(v1);
            HalfEdge he2 = mHeModel.CreateHalfEdge(v2);

            he0.Next = he1;
            he0.Prev = he2;
            he1.Next = he2;
            he1.Prev = he0;
            he2.Next = he0;
            he2.Prev = he1;

            // 法線の設定
            Vector3d normal = CadMath.Normal(
                mHeModel.VertexStore[v0].vector,
                mHeModel.VertexStore[v1].vector,
                mHeModel.VertexStore[v2].vector);

            // Faceの設定
            HeFace face = mHeModel.CreateFace(he0);

            if (!normal.IsInvalid())
            {
                face.Normal = mHeModel.NormalStore.Add(normal);
                he0.Normal  = mHeModel.NormalStore.Add(normal);
                he1.Normal  = mHeModel.NormalStore.Add(normal);
                he2.Normal  = mHeModel.NormalStore.Add(normal);
            }

            int faceIndex = mHeModel.FaceStore.Add(face);

            he0.Face = faceIndex;
            he1.Face = faceIndex;
            he2.Face = faceIndex;

            // Pairの設定
            HeConnector.SetHalfEdgePair(he0, HeMap);
            HeMap[HeConnector.GetHeKey(he0)] = he0;

            HeConnector.SetHalfEdgePair(he1, HeMap);
            HeMap[HeConnector.GetHeKey(he1)] = he1;

            HeConnector.SetHalfEdgePair(he2, HeMap);
            HeMap[HeConnector.GetHeKey(he2)] = he2;
        }
示例#14
0
        private void test005()
        {
            CadFigure fig = GetTargetFigure();

            if (fig.PointCount < 3)
            {
                return;
            }

            Vector3d v1 = fig.PointList[0].vector - fig.PointList[1].vector;
            Vector3d v2 = fig.PointList[2].vector - fig.PointList[1].vector;

            double t = CadMath.AngleOfVector(v1, v2);

            double a = CadMath.Rad2Deg(t);

            ItConsole.println(string.Format("angle:{0}(deg)", a));
        }
示例#15
0
        public async void CutMeshWithInteractive(CadFigure fig)
        {
            await Task.Run(() =>
            {
                var res = InputLine();

                if (res.state != InteractCtrl.States.END)
                {
                    Controller.AbendEdit();
                    return;
                }

                if ((res.p1 - res.p0).IsZero())
                {
                    Controller.AbendEdit();
                    ItConsole.println("Error: Same point");
                    return;
                }

                CadFigureMesh mesh = fig as CadFigureMesh;

                if (mesh == null)
                {
                    Controller.AbendEdit();
                    ItConsole.println("Error: Target is not mesh");
                    return;
                }

                Vector3d normal = CadMath.Normal(
                    res.p1 - res.p0, (Controller.DC.ViewDir));

                CutMeshWithVector(mesh, res.p0, res.p1, normal);

                RunOnMainThread(() =>
                {
                    Controller.ClearSelection();
                    Controller.Redraw();
                });
            });
        }
示例#16
0
        public Vector3d RotateVector(Vector3d v, Vector3d axis, double angle)
        {
            axis = axis.UnitVector();

            double t = CadMath.Deg2Rad(angle);

            CadQuaternion q = CadQuaternion.RotateQuaternion(axis, t);
            CadQuaternion r = q.Conjugate();;

            CadQuaternion qp;

            qp = CadQuaternion.FromPoint(v);

            qp = r * qp;
            qp = qp * q;

            Vector3d rv = v;

            rv = qp.ToPoint();

            return(rv);
        }
示例#17
0
        public async void FlipAndCopyWithInteractive(List <CadFigure> rootFigList)
        {
            await Task.Run(() =>
            {
                var res = InputLine();

                if (res.state != InteractCtrl.States.END)
                {
                    return;
                }

                if ((res.p1 - res.p0).IsZero())
                {
                    ItConsole.println("Error: Same point");
                    return;
                }

                Vector3d normal = CadMath.Normal(
                    res.p1 - res.p0, Controller.DC.ViewDir);

                FlipAndCopyWithPlane(rootFigList, res.p0, normal);
            });
        }
示例#18
0
        public CadFigure AddCircleAt(Vector3d p, double r)
        {
            Vector3d viewDir = Controller.DC.ViewDir;
            Vector3d upDir   = Controller.DC.UpVector;

            CadFigure fig = Controller.DB.NewFigure(CadFigure.Types.CIRCLE);

            Vector3d p0 = p;
            Vector3d p1 = p0 + CadMath.Normal(viewDir, upDir) * r;

            fig.AddPoint((CadVertex)p0);
            fig.AddPoint((CadVertex)p1);
            fig.EndCreate(Controller.DC);

            CadOpe ope = new CadOpeAddFigure(Controller.CurrentLayer.ID, fig.ID);

            Session.AddOpe(ope);
            Controller.CurrentLayer.AddFigure(fig);

            Session.PostRemakeObjectTree();

            return(fig);
        }
示例#19
0
        public CadFigure AddRectAt(Vector3d p, double w, double h)
        {
            Vector3d viewDir = Controller.DC.ViewDir;
            Vector3d upDir   = Controller.DC.UpVector;

            Vector3d wd = CadMath.Normal(viewDir, upDir) * w;
            Vector3d hd = upDir.UnitVector() * h;

            CadVertex p0 = (CadVertex)p;
            CadVertex p1 = (CadVertex)p;

            CadFigure fig = Controller.DB.NewFigure(CadFigure.Types.RECT);

            fig.AddPoint(p0);

            p1 = p0 + wd;
            fig.AddPoint(p1);

            p1 = p0 + wd + hd;
            fig.AddPoint(p1);

            p1 = p0 + hd;
            fig.AddPoint(p1);

            fig.IsLoop = true;

            fig.EndCreate(Controller.DC);

            CadOpe ope = new CadOpeAddFigure(Controller.CurrentLayer.ID, fig.ID);

            Session.AddOpe(ope);
            Controller.CurrentLayer.AddFigure(fig);

            Session.PostRemakeObjectTree();

            return(fig);
        }
示例#20
0
        public void RecreateNormals()
        {
            Vector3dList newNormalStore = new Vector3dList(VertexStore.Count);

            int i;

            for (i = 0; i < FaceStore.Count; i++)
            {
                HeFace face = FaceStore[i];

                HalfEdge head = FaceStore[i].Head;
                HalfEdge c    = head;

                Vector3d n = CadMath.Normal(
                    VertexStore[c.Vertex].vector,
                    VertexStore[c.Next.Vertex].vector,
                    VertexStore[c.Next.Next.Vertex].vector
                    );

                face.Normal = newNormalStore.Add(n);

                for (; ;)
                {
                    c.Normal = newNormalStore.Add(n);

                    c = c.Next;

                    if (c == head)
                    {
                        break;
                    }
                }
            }

            NormalStore = newNormalStore;
        }
示例#21
0
        // 回転体の作成
        public static CadMesh CreateRotatingBody(int circleDiv, Vector3d org, Vector3d axis, VertexList vl, bool topCap, bool btmCap, FaceType facetype = FaceType.TRIANGLE)
        {
            if (vl.Count < 2)
            {
                return(null);
            }

            #region 面の向きが外から中心に向かってみた場合に左回りになるように回転軸の向きを調整
            // vlの全体的な向きを求めるためvl[0]から一番遠い点を求める
            int      fi    = CadUtil.FindMaxDistantPointIndex(vl[0], vl);
            Vector3d vldir = (Vector3d)(vl[fi] - vl[0]);

            // vlの全体的な向きと回転軸の向きが同じ場合、回転軸の向きを反転
            double dot = CadMath.InnerProduct(axis, vldir);
            if (dot > 0)
            {
                axis *= -1;
            }
            #endregion

            CadMesh mesh = new CadMesh(vl.Count * circleDiv, vl.Count * circleDiv);

            CrossInfo crossS = CadMath.PerpCrossLine(org, org + axis, (Vector3d)vl[0]);
            CrossInfo crossE = CadMath.PerpCrossLine(org, org + axis, (Vector3d)vl.End());

            crossS.Distance = (crossS.CrossPoint - (Vector3d)vl[0]).Length;
            crossE.Distance = (crossE.CrossPoint - (Vector3d)vl.End()).Length;

            int s = 0;
            int e = vl.Count;

            int vc = vl.Count;
            int ps = 0;

            // VertexStoreの並びは以下の様になる。vlの個数をnとする。
            // topCap中心点, btmCap中心点, 側面点0, 側面点1 ..... 側面点n-1
            // 変数ps: 側面の点0の位置
            // 変数s:  vlから取り出す先頭位置
            //        最初の点をtopCapの中心とする場合、側面点0ではなくなるので、+1する
            // 変数e:  vlから取り出す終端
            //        最後の点をbtmCapの中心とする場合、側面点n-1ではなくなるので、-1する
            // 変数vc: 側面1列の点の数

            if (crossS.Distance < CadMath.Epsilon)
            {
                mesh.VertexStore.Add(vl[0]);
                s     += 1;
                topCap = true;
                vc--;
                ps++;
            }
            else if (topCap)
            {
                mesh.VertexStore.Add((CadVertex)crossS.CrossPoint);
                ps++;
            }

            if (crossE.Distance < CadMath.Epsilon)
            {
                mesh.VertexStore.Add(vl.End());
                e     -= 1;
                btmCap = true;
                vc--;
                ps++;
            }
            else if (btmCap)
            {
                mesh.VertexStore.Add((CadVertex)crossE.CrossPoint);
                ps++;
            }

            double d = Math.PI * 2.0 / circleDiv;


            CadQuaternion qp;

            for (int i = 0; i < circleDiv; i++)
            {
                double        a   = i * d;
                CadQuaternion q   = CadQuaternion.RotateQuaternion(axis, a);
                CadQuaternion con = q.Conjugate();

                for (int vi = s; vi < e; vi++)
                {
                    CadVertex p = vl[vi];

                    p.vector -= org;

                    qp = CadQuaternion.FromPoint(p.vector);

                    qp = con * qp;
                    qp = qp * q;

                    p.vector = qp.ToPoint();

                    p += org;

                    mesh.VertexStore.Add(p);
                }
            }

            CadFace f;

            if (topCap)
            {
                for (int i = 0; i < circleDiv; i++)
                {
                    f = new CadFace(0, ((i + 1) % circleDiv) * vc + ps, i * vc + ps);
                    mesh.FaceStore.Add(f);
                }
            }

            if (btmCap)
            {
                for (int i = 0; i < circleDiv; i++)
                {
                    int bi = (vc - 1);

                    f = new CadFace(1, (i * vc) + bi + ps, ((i + 1) % circleDiv) * vc + bi + ps);
                    mesh.FaceStore.Add(f);
                }
            }

            // 四角形で作成
            if (facetype == FaceType.QUADRANGLE)
            {
                for (int i = 0; i < circleDiv; i++)
                {
                    int nextSlice = ((i + 1) % circleDiv) * vc + ps;

                    for (int vi = 0; vi < vc - 1; vi++)
                    {
                        f = new CadFace(
                            (i * vc) + ps + vi,
                            nextSlice + vi,
                            nextSlice + vi + 1,
                            (i * vc) + ps + vi + 1
                            );

                        mesh.FaceStore.Add(f);
                    }
                }
            }
            else
            {
                // 三角形で作成
                for (int i = 0; i < circleDiv; i++)
                {
                    int nextSlice = ((i + 1) % circleDiv) * vc + ps;

                    for (int vi = 0; vi < vc - 1; vi++)
                    {
                        f = new CadFace(
                            (i * vc) + ps + vi,
                            nextSlice + vi,
                            (i * vc) + ps + vi + 1
                            );

                        mesh.FaceStore.Add(f);

                        f = new CadFace(
                            nextSlice + vi,
                            nextSlice + vi + 1,
                            (i * vc) + ps + vi + 1
                            );

                        mesh.FaceStore.Add(f);
                    }
                }
            }

            return(mesh);
        }
示例#22
0
        // option:
        // e.g.
        // a100q30 max area = 100, min degree = 30
        // a100q max area = 100, min degree = default (20)
        // min degree < 34
        // Other options see
        // https://www.cs.cmu.edu/~quake/triangle.switch.html
        //
        public void Triangulate(uint figID, string option)
        {
            CadFigure tfig = Controller.DB.GetFigure(figID);

            if (tfig == null || tfig.Type != Types.POLY_LINES)
            {
                return;
            }

            if (tfig.PointCount < 3)
            {
                return;
            }

            CadFigure cfig = FigUtil.Clone(tfig);

            Vector3d org = cfig.PointList[0].vector;
            Vector3d dir = Vector3d.UnitZ;

            Vector3d faceNormal = CadUtil.TypicalNormal(cfig.PointList);

            Vector3d rotateV = default;

            double t = 0;

            if (!faceNormal.EqualsThreshold(dir) && !(-faceNormal).EqualsThreshold(dir))
            {
                rotateV = CadMath.Normal(faceNormal, dir);
                t       = -CadMath.AngleOfVector(faceNormal, dir);
                CadUtil.RotateFigure(cfig, org, rotateV, t);
            }

            //Controller.CurrentLayer.AddFigure(cfig);

            VertexList vl = cfig.GetPoints(12);

            CadMesh m = IglW.Triangulate(vl, option);

            HeModel hem = HeModelConverter.ToHeModel(m);

            CadFigureMesh fig = (CadFigureMesh)Controller.DB.NewFigure(CadFigure.Types.MESH);

            fig.SetMesh(hem);

            for (int i = 0; i < fig.PointCount; i++)
            {
                CadVertex v = fig.PointList[i];
                v.Z = org.Z;
                fig.PointList[i] = v;
            }

            if (t != 0)
            {
                CadUtil.RotateFigure(fig, org, rotateV, -t);
            }

            CadOpeList root = new CadOpeList();
            CadOpe     ope;

            ope = new CadOpeAddFigure(Controller.CurrentLayer.ID, fig.ID);
            Session.AddOpe(ope);

            Controller.CurrentLayer.AddFigure(fig);


            ope = new CadOpeRemoveFigure(Controller.CurrentLayer, figID);
            Session.AddOpe(ope);

            Controller.CurrentLayer.RemoveFigureByID(figID);
            Controller.CurrentFigure = null;

            Session.PostRemakeObjectTree();
        }
示例#23
0
        // Faceを三角形に分割する
        public static List <CadFace> Split(CadFace face, CadMesh mesh)
        {
            CadVertex p0 = default(CadVertex);

            // Deep copy
            CadFace src = new CadFace(face);

            var triangles = new List <CadFace>();

            int i1 = -1;

            int state = 0;

            CadFace triangle;

            i1 = FindMaxDistantPointIndex(p0, src, mesh);

            if (i1 == -1)
            {
                return(triangles);
            }

            triangle = GetTriangleWithCenterPoint(src, i1);

            Vector3d tp0 = mesh.VertexStore[triangle.VList[0]].vector;
            Vector3d tp1 = mesh.VertexStore[triangle.VList[1]].vector;
            Vector3d tp2 = mesh.VertexStore[triangle.VList[2]].vector;

            Vector3d dir        = CadMath.Normal(tp1, tp0, tp2);
            Vector3d currentDir = Vector3d.Zero;

            while (src.VList.Count > 3)
            {
                if (state == 0)
                {
                    i1 = FindMaxDistantPointIndex(p0, src, mesh);
                    if (i1 == -1)
                    {
                        return(triangles);
                    }
                }

                triangle = GetTriangleWithCenterPoint(src, i1);

                tp0 = mesh.VertexStore[triangle.VList[0]].vector;
                tp1 = mesh.VertexStore[triangle.VList[1]].vector;
                tp2 = mesh.VertexStore[triangle.VList[2]].vector;

                currentDir = CadMath.Normal(tp1, tp0, tp2);

                bool hasIn = ListContainsPointInTriangle(triangle, src, mesh);

                double scala = CadMath.InnerProduct(dir, currentDir);

                if (!hasIn && (scala > 0))
                {
                    triangles.Add(triangle);
                    src.VList.RemoveAt(i1);
                    state = 0;
                    continue;
                }

                if (state == 0)
                {
                    state = 1;
                    i1    = 0;
                }
                else if (state == 1)
                {
                    i1++;
                    if (i1 >= src.VList.Count)
                    {
                        break;
                    }
                }
            }

            if (src.VList.Count == 3)
            {
                triangle = new CadFace();
                triangle.VList.Add(src.VList[0]);
                triangle.VList.Add(src.VList[1]);
                triangle.VList.Add(src.VList[2]);

                triangles.Add(triangle);
            }

            return(triangles);
        }
示例#24
0
        public static CadMesh CreateExtruded(VertexList src, Vector3d dv, int div = 0)
        {
            if (src.Count < 3)
            {
                return(null);
            }

            div += 1;

            VertexList vl;

            Vector3d n = CadUtil.TypicalNormal(src);


            if (CadMath.InnerProduct(n, dv) <= 0)
            {
                vl = new VertexList(src);
                vl.Reverse();
            }
            else
            {
                vl = src;
            }

            int vlCnt = vl.Count;

            CadMesh mesh = new CadMesh(vl.Count * 2, vl.Count);

            CadFace f;

            Vector3d dt = dv / div;

            Vector3d sv = Vector3d.Zero;

            // 頂点リスト作成
            for (int i = 0; i < div + 1; i++)
            {
                for (int j = 0; j < vlCnt; j++)
                {
                    mesh.VertexStore.Add(vl[j] + sv);
                }

                sv += dt;
            }


            // 表面
            f = new CadFace();

            for (int i = 0; i < vlCnt; i++)
            {
                f.VList.Add(i);
            }

            mesh.FaceStore.Add(f);


            // 裏面
            f = new CadFace();

            int si = (div + 1) * vlCnt - 1;
            int ei = si - (vlCnt - 1);

            for (int i = si; i >= ei; i--)
            {
                f.VList.Add(i);
            }

            mesh.FaceStore.Add(f);

            // 側面
            for (int k = 0; k < div; k++)
            {
                int ti = vlCnt * k;

                for (int i = 0; i < vlCnt; i++)
                {
                    int j = (i + 1) % vlCnt;

                    f = new CadFace();

                    f.VList.Add(i + ti);
                    f.VList.Add(i + ti + vlCnt);
                    f.VList.Add(j + ti + vlCnt);
                    f.VList.Add(j + ti);

                    mesh.FaceStore.Add(f);
                }
            }

            MeshUtil.SplitAllFace(mesh);

            return(mesh);
        }