Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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();
                });
            });
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
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();
        }
Ejemplo n.º 6
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;
        }
Ejemplo n.º 7
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();
                });
            });
        }
Ejemplo n.º 8
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);
            });
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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;
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
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();
        }