Esempio n. 1
0
 public override void OnDone()
 {
     if (base.ActiveObject != null)
     {
         using (base.Frame.Project.Undo.UndoFrame)
         {
             CurrentMouseView.Canvas.Cursor = "WaitCursor";
             GeoObjectList ToAdd  = new GeoObjectList();
             Model         m      = base.Frame.ActiveView.Model;
             BRepOperation brepOp = new BRepOperation(toSplit.Shells[0], plane);
             (Shell[] upper, Shell[] lower) = BRepOperation.SplitByPlane(toSplit.Shells[0], plane);
             for (int i = 0; i < upper.Length; i++)
             {
                 ToAdd.Add(Solid.MakeSolid(upper[i]));
             }
             for (int i = 0; i < lower.Length; i++)
             {
                 ToAdd.Add(Solid.MakeSolid(lower[i]));
             }
             m.Remove(toSplit);
             m.Add(ToAdd);
             base.ActiveObject = null;
             base.OnDone();
         }
     }
 }
Esempio n. 2
0
 bool curveInputPath(ConstructAction.CurveInput sender, ICurve[] Curves, bool up)
 {       // ... nur die sinnvollen Kurven verwenden
     objectPoint = base.CurrentMousePosition;
     if (up)
     {
         if (Curves.Length == 0)
         {
             sender.SetCurves(Curves, null);                     // ...die werden jetzt im ControlCenter dargestellt (nur bei up)
         }
         else
         {
             sender.SetCurves(Curves, Curves[0]);
         }
     }
     if (Curves.Length > 0)
     {   // er hat was gewählt
         selectedObjectsList.Clear();
         base.FeedBack.ClearSelected();
         selectedObjectsList.Add(Curves[0] as IGeoObject); // das eine in die Liste
         ListDefault(1);                                   // die Listen löschen und mit "1" vorbesetzen
         if (extrudeOrg())
         {
             return(true);
         }
     }
     heightInput.ReadOnly = false;
     base.FeedBack.ClearSelected();
     base.ShowActiveObject = false;
     return(false);
 }
Esempio n. 3
0
 bool geoObjectInputFace(ConstructAction.GeoObjectInput sender, IGeoObject[] TheGeoObjects, bool up)
 {   // ... nur die sinnvollen Kurven verwenden
     // TODO: evtl Mehrfachanwahl ermöglichen
     if (up)
     {
         if (TheGeoObjects.Length == 0)
         {
             sender.SetGeoObject(TheGeoObjects, null);                            // ...die werden jetzt im ControlCenter dargestellt (nur bei up)
         }
         else
         {
             sender.SetGeoObject(TheGeoObjects, TheGeoObjects[0]);
         }
     }
     if (TheGeoObjects.Length > 0)
     {   // er hat was gewählt
         selectedObjectsList.Clear();
         base.FeedBack.ClearSelected();
         selectedObjectsList.Add(TheGeoObjects[0]); // das eine in die Liste
         ListDefault(1);                            // die Listen löschen und mit "1" vorbesetzen
         if (makeFaceOrg())
         {
             return(true);
         }
     }
     base.ShowActiveObject = false;
     base.FeedBack.ClearSelected();
     return(false);
 }
Esempio n. 4
0
 public override void OnDone()
 {
     if (base.ActiveObject != null)
     {
         using (base.Frame.Project.Undo.UndoFrame)
         {
             Frame.ActiveView.Canvas.Cursor = "WaitCursor";
             GeoObjectList ToAdd = new GeoObjectList();
             Model         m     = base.Frame.ActiveView.Model;
             PlaneSurface  pls   = new PlaneSurface(plane);
             for (int i = 0; i < m.Count; ++i) // durch das ganze Modell laufen
             {
                 ICurve[] crvs = Intersect(m[i], pls);
                 if (crvs != null)
                 {
                     for (int k = 0; k < crvs.Length; k++)
                     {
                         IGeoObject go = crvs[k] as IGeoObject;
                         go.CopyAttributes(base.ActiveObject);
                         ToAdd.Add(go);
                     }
                 }
             }
             m.Add(ToAdd);
             base.KeepAsLastStyle(ActiveObject);
             base.ActiveObject = null;
             base.OnDone();
         }
     }
 }
Esempio n. 5
0
 public override void OnDone()
 {
     // ist die Shift Taste gehalten, so werden Kopien gemacht, d.h. der die Elemente
     // des blocks werden eingefügt. Ansonsten werden die original-Objekte verändert
     // TODO: Feedback über Cursor bei Shift-Taste fehlt noch
     // TODO: die neuen oder veränderten Objekte sollten markiert sein.
     using (Frame.Project.Undo.UndoFrame)
     {
         ModOp m = ModOp.Translate(offset);
         if (((Frame.UIService.ModifierKeys & Keys.Shift) != 0) || copyObject)
         {
             GeoObjectList cloned = new GeoObjectList();
             foreach (IGeoObject go in originals)
             {
                 IGeoObject cl = go.Clone();
                 cl.Modify(m);
                 //					go.Owner.Add(cl);
                 cloned.Add(cl);
             }
             base.Frame.Project.GetActiveModel().Add(cloned);
         }
         else
         {
             originals.Modify(m);
         }
     }
     base.ActiveObject = null; // damit es nicht gleich eingefügt wird
     base.OnDone();
 }
Esempio n. 6
0
        /// <summary>
        /// This method is used by a <see cref="Hatch"/> object to calculate its contents. It generates a
        /// set of parallel lines according to <see cref="LineDistance"/> and <see cref="LineAngle"/>
        /// and clips them with the given shape. The lines are projected into the 3D world
        /// by the given plane. <seealso cref="CompoundShape.Clip"/>
        /// </summary>
        /// <param name="shape">shape of the hatch object</param>
        /// <param name="plane">local plane of the hatch object</param>
        /// <returns></returns>
        public override GeoObjectList GenerateContent(CompoundShape shape, Plane plane)
        {
            GeoObjectList res = new GeoObjectList();

            if (shape == null)
            {
                return(res);
            }
            if (marginOffset != 0.0)
            {
                shape.Approximate(false, Settings.GlobalSettings.GetDoubleValue("Approximate.Precision", 0.01));
                shape = shape.Shrink(marginOffset);
            }
            for (int i = 0; i < Math.Max(1, number); ++i)
            {
                double       a   = lineAngle.Radian + i * (double)offset;
                ModOp2D      m   = ModOp2D.Rotate(new SweepAngle(-a));
                BoundingRect ext = shape.GetExtent();
                ext.Modify(m);                         // ext ist jetzt waagrecht, u.U. zu groß, was aber egal ist
                m = ModOp2D.Rotate(new SweepAngle(a)); // die umgekehrte ModOp
                int alt = 0;
                // eine Linie soll durch die Mitte gehen
                double c   = (ext.Bottom + ext.Top) / 2.0;
                double num = Math.Ceiling((c - ext.Bottom) / lineDistance);
                ext.Bottom = c - num * lineDistance; // das untere Ende sowei nach unten verschoben, dass eine Linie durch die mitte geht
                // das ist wichtig, weil sonst manche Schraffuren nicht zu picken sind, da keine Linie darin erscheint
                // da eine Schraffur meist nur aus einem SimpleShape besteht, gibt es immer eine Linie durch die Mitte
                for (double y = ext.Bottom; y < ext.Top; y += lineDistance)
                {
                    GeoPoint2D startPoint = m * new GeoPoint2D(ext.Left, y);
                    GeoPoint2D endPoint   = m * new GeoPoint2D(ext.Right, y);
                    Line2D     l          = new Line2D(startPoint, endPoint);
                    if (alternate && ((alt & 0x01) != 0))
                    {
                        l.Reverse();
                    }
                    double[] seg = shape.Clip(l, true);
                    for (int j = 0; j < seg.Length; j += 2)
                    {
                        IGeoObject go = l.Trim(seg[j], seg[j + 1]).MakeGeoObject(plane);
                        (go as ILineWidth).LineWidth     = lineWidth;
                        (go as ILinePattern).LinePattern = linePattern;
                        (go as IColorDef).ColorDef       = colorDef;
                        res.Add(go);
                    }
                    ++alt;
                }
            }
            return(res);
        }
Esempio n. 7
0
        public override GeoObjectList GenerateContent(CompoundShape shape, Plane plane)
        {
            GeoObjectList res = new GeoObjectList();

            for (int i = 0; i < shape.SimpleShapes.Length; ++i)
            {
                SimpleShape ss = shape.SimpleShapes[i].Clone();
                ss.Flatten(); // es entstehen Shapes mit Polylinien, das ist für Faces schlecht
                Face fc = Face.MakeFace(new PlaneSurface(plane), ss);
                fc.ColorDef = color;
                res.Add(fc);
            }
            return(res);
        }
Esempio n. 8
0
        public Constr3DScrewPath(GeoObjectList selectedObjects)
        {
            GeoObjectList clones = selectedObjects.CloneObjects();

            if (selectedObjects.Count == 1)
            {
                if (selectedObjects[0] is Hatch)
                {
                    shape = (selectedObjects[0] as Hatch).CompoundShape;
                    plane = (selectedObjects[0] as Hatch).Plane;
                    return;
                }
                else if (selectedObjects[0] is Face)
                {
                    if ((selectedObjects[0] as Face).Surface is PlaneSurface)
                    {
                        // here we could directely set shape and plane
                    }
                    clones.Clear();
                    foreach (Edge edg in (selectedObjects[0] as Face).AllEdgesIterated())
                    {
                        if (edg.Curve3D != null)
                        {
                            clones.Add(edg.Curve3D as IGeoObject);
                        }
                    }
                }
            }
            shape = CompoundShape.CreateFromList(clones, Precision.eps, out plane);
            if (shape == null)
            {
                Path toRotate = Path.Construct();
                toRotate.Set(clones, false, Precision.eps);
                if (toRotate.CurveCount > 0)
                {
                    if (toRotate.GetPlanarState() == PlanarState.Planar)
                    {
                        plane = toRotate.GetPlane();
                        path  = toRotate.GetProjectedCurve(plane) as Path2D;
                    }
                }
            }
        }
Esempio n. 9
0
 public override void OnDone()
 {
     // ist die Shift Taste gehalten, so werden Kopien gemacht, d.h. der die Elemente
     // des blocks werden eingefügt. Ansonsten werden die original-Objekte verändert
     // TODO: Feedback über Cursor bei Shift-Taste fehlt noch
     // TODO: die neuen oder veränderten Objekte sollten markiert sein.
     using (Frame.Project.Undo.UndoFrame)
     {
         ModOp m;
         if (!dis)
         {
             m = ModOp.Scale(base.BasePoint, faktor);       // ein faktor für alle!
         }
         else
         {       // 3 Faktoren für 3 Achsen
             m = ModOp.Scale(base.BasePoint, base.ActiveDrawingPlane.DirectionX, faktorX) * ModOp.Scale(base.BasePoint, base.ActiveDrawingPlane.DirectionY, faktorY) * ModOp.Scale(base.BasePoint, base.ActiveDrawingPlane.Normal, faktorZ);
         }
         if (!Precision.IsNull(Math.Abs(m.Determinant)))
         {
             if (((Frame.UIService.ModifierKeys & Keys.Shift) != 0) || copyObject)
             {
                 GeoObjectList cloned = new GeoObjectList();
                 foreach (IGeoObject go in originals)
                 {
                     IGeoObject cl = go.Clone();
                     cl.Modify(m);
                     cloned.Add(cl);
                 }
                 base.Frame.Project.GetActiveModel().Add(cloned);
             }
             else
             {
                 originals.Modify(m);
             }
         }
     }
     base.ActiveObject = null; // damit es nicht gleich eingefügt wird
     base.OnDone();
 }
Esempio n. 10
0
        static public bool canUseList(GeoObjectList selectedObjects)
        {
            Path          toRotate = Path.Construct();
            GeoObjectList clones   = selectedObjects.CloneObjects();

            if (selectedObjects.Count == 1)
            {
                if (selectedObjects[0] is Hatch)
                {
                    return(true);
                }
                if (selectedObjects[0] is Face)
                {
                    if ((selectedObjects[0] as Face).Surface is PlaneSurface)
                    {
                        return(true);
                    }
                    clones.Clear();
                    foreach (Edge edg in (selectedObjects[0] as Face).AllEdgesIterated())
                    {
                        if (edg.Curve3D != null)
                        {
                            clones.Add(edg.Curve3D as IGeoObject);
                        }
                    }
                }
            }
            toRotate.Set(clones, false, Precision.eps);
            if (toRotate.CurveCount > 0)
            {
                if (toRotate.GetPlanarState() == PlanarState.UnderDetermined || toRotate.GetPlanarState() == PlanarState.Planar)
                {
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 11
0
 public Constr3DFaceExtrude(GeoObjectList selectedObjectsList)
     : this()
 {
     selectedMode = (selectedObjectsList != null);
     if (selectedMode)
     {
         GeoObjectList clonedList = selectedObjectsList.Clone();
         GeoObjectList curves     = new GeoObjectList();
         for (int i = clonedList.Count - 1; i >= 0; --i)
         {
             if (clonedList[i] is ICurve)
             {
                 curves.Add(clonedList[i]);
                 clonedList.Remove(i);
             }
         }
         Plane         pln;
         CompoundShape cs = CompoundShape.CreateFromList(curves, Precision.eps, out pln);
         if (cs != null && !cs.Empty)
         {   // man konnte ein CompoundShape erzeugen, dann dieses zu Faces machen und verwenden
             for (int i = 0; i < cs.SimpleShapes.Length; i++)
             {
                 PlaneSurface ps    = new PlaneSurface(pln);
                 Face         toAdd = Face.MakeFace(ps, cs.SimpleShapes[i]);
                 toAdd.CopyAttributes(curves[0]);
                 clonedList.Add(toAdd);
             }
             this.selectedObjectsList = clonedList;
         }
         else
         {
             this.selectedObjectsList = selectedObjectsList.Clone();
         }
         ListDefault(this.selectedObjectsList.Count); // setzt alle Listen auf gleiche Länge, Inhalte "null"
     }
     ;
 }
Esempio n. 12
0
        public Shell[] Read(string fileName)
        {
            List <Shell> res = new List <Shell>();

            using (sr = new StreamReader(fileName)) // may throw exceptions like "file not found" etc.
            {
                char[] head = new char[5];
                int    read = sr.ReadBlock(head, 0, 5);
                if (read != 5)
                {
                    throw new ApplicationException("cannot read from file");
                }
                if (new string(head) == "solid")
                {
                    isASCII = true;
                }
                else
                {
                    isASCII = false;
                }
            }
            if (isASCII)
            {
                sr = new StreamReader(fileName);
                string title = sr.ReadLine();
            }
            else
            {
                br = new BinaryReader(File.Open(fileName, FileMode.Open));
                br.ReadBytes(80);
                uint nrtr = br.ReadUInt32();
            }
            OctTree <Vertex> verticesOctTree = null;
            triangle         tr;
            int           cnt      = 0;
            Set <Face>    allFaces = new Set <Face>();
            GeoObjectList dbgl     = new GeoObjectList();

            do
            {
                tr = GetNextTriangle();
                if (tr == null)
                {
                    break;
                }
                if (verticesOctTree == null)
                {
                    verticesOctTree = new OctTree <Vertex>(new BoundingCube(tr.p1, tr.p2, tr.p3), 1e-6);
                }
                try
                {
                    PlaneSurface ps = new PlaneSurface(tr.p1, tr.p2, tr.p3);
                    Vertex       v1 = VertexFromPoint(verticesOctTree, tr.p1);
                    Vertex       v2 = VertexFromPoint(verticesOctTree, tr.p2);
                    Vertex       v3 = VertexFromPoint(verticesOctTree, tr.p3);
                    Edge         e1 = Vertex.SingleConnectingEdge(v1, v2);
                    if (e1 != null && e1.SecondaryFace != null)
                    {
                    }
                    if (e1 == null || e1.SecondaryFace != null)
                    {
                        e1 = new Edge(Line.TwoPoints(v1.Position, v2.Position), v1, v2);
                    }
                    Edge e2 = Vertex.SingleConnectingEdge(v2, v3);
                    if (e2 != null && e2.SecondaryFace != null)
                    {
                    }
                    if (e2 == null || e2.SecondaryFace != null)
                    {
                        e2 = new Edge(Line.TwoPoints(v2.Position, v3.Position), v2, v3);
                    }
                    Edge e3 = Vertex.SingleConnectingEdge(v3, v1);
                    if (e3 != null && e3.SecondaryFace != null)
                    {
                    }
                    if (e3 == null || e3.SecondaryFace != null)
                    {
                        e3 = new Edge(Line.TwoPoints(v3.Position, v1.Position), v3, v1);
                    }
                    dbgl.Add(Line.TwoPoints(v1.Position, v2.Position));
                    dbgl.Add(Line.TwoPoints(v2.Position, v3.Position));
                    dbgl.Add(Line.TwoPoints(v3.Position, v1.Position));
                    Face fc = Face.Construct();
                    fc.Surface = ps;
                    //Line2D l1 = new Line2D(ps.Plane.Project(tr.p1), ps.Plane.Project(tr.p2));
                    //Line2D l2 = new Line2D(ps.Plane.Project(tr.p2), ps.Plane.Project(tr.p3));
                    //Line2D l3 = new Line2D(ps.Plane.Project(tr.p3), ps.Plane.Project(tr.p1));
                    //if (e1.PrimaryFace == null) e1.SetPrimary(fc, l1, true);
                    //else e1.SetSecondary(fc, l1, false);
                    //if (e2.PrimaryFace == null) e2.SetPrimary(fc, l2, true);
                    //else e2.SetSecondary(fc, l2, false);
                    //if (e3.PrimaryFace == null) e3.SetPrimary(fc, l3, true);
                    //else e3.SetSecondary(fc, l3, false);
                    e1.SetFace(fc, e1.Vertex1 == v1);
                    e2.SetFace(fc, e2.Vertex1 == v2);
                    e3.SetFace(fc, e3.Vertex1 == v3);
                    fc.Set(ps, new Edge[][] { new Edge[] { e1, e2, e3 } });
                    allFaces.Add(fc);
                    ++cnt;
                }
                catch (ModOpException)
                {
                    // empty triangle, plane construction failed
                }
            } while (tr != null);
            while (!allFaces.IsEmpty())
            {
                Shell part = Shell.CollectConnected(allFaces);
#if DEBUG
                // TODO: some mechanism to tell whether and how to reverse engineer the stl file
                double precision;
                if (numnum == 0)
                {
                    precision = part.GetExtent(0.0).Size * 1e-5;
                }
                else
                {
                    precision = Math.Pow(10, -numdec / (double)(numnum));  // numdec/numnum is average number of decimal places
                }
                part.ReconstructSurfaces(precision);
#endif
                res.Add(part);
            }
            return(res.ToArray());
        }
Esempio n. 13
0
 public void Add(IGeoObject toAdd, System.Drawing.Color color, int debugHint = 0)
 {
     if (toAdd != null)
     {
         ColorDef cd = new ColorDef(color.Name, color);
         if (toAdd is IColorDef)
         {
             (toAdd as IColorDef).ColorDef = cd;
         }
         toShow.Add(toAdd);
     }
 }
Esempio n. 14
0
        public GeoObjectList makeFaceDo(GeoObjectList selectedObjectsList, IFrame frame)
        {
            this.selectedObjectsList = selectedObjectsList.Clone();
            ListDefault(selectedObjectsList.Count); // setzt alle Listen auf gleiche Länge, Inhalte "null"
            IGeoObject iGeoObjectSel;
            //         IGeoObject iGeoObjectOrg;
            Boolean       success = false;                            // hat er wenigstens eins gefunden
            GeoObjectList outList = new GeoObjectList();              // sammelt die gelungenen faces

            for (int i = 0; i < selectedObjectsList.Count; i++)       // läuft über alle selektierten Objekte. Evtl nur eins bei Konstruktion
            {
                IGeoObject iGeoObjectTemp = null;                     // lokaler Merker
                iGeoObjectSel               = selectedObjectsList[i]; // zur Vereinfachung
                geoObjectOrgList[i]         = iGeoObjectSel;          // zum Weglöschen des Originals in onDone
                ownerList[i]                = iGeoObjectSel.Owner;    // owner merken für löschen
                pathCreatedFromModelList[i] = null;
                faceList[i] = null;
                //            Boolean VectorOrHeightTemp = VectorOrHeight;
                if (!(iGeoObjectSel is Face) && !(iGeoObjectSel is Shell))
                {
                    if ((iGeoObjectSel is ICurve))
                    {
                        Path p = null;
                        if (selectedObjectsList.Count == 1 && !(iGeoObjectSel as ICurve).IsClosed)
                        {
                            p = CADability.GeoObject.Path.CreateFromModel(iGeoObjectSel as ICurve, frame.ActiveView.Model, frame.ActiveView.Projection, true);
                        }
                        if (p == null)
                        {     // also nur Einzelelement
                            if (iGeoObjectSel is Path)
                            { // schon fertig
                                p = iGeoObjectSel.Clone() as Path;
                            }
                            else
                            {  // Pfad aus Einzelobjekt machen:
                                p = Path.Construct();
                                p.Set(new ICurve[] { iGeoObjectSel.Clone() as ICurve });
                            }
                        }
                        else
                        { // CreateFromModel hat was zusammengesetzt
                            if (p.IsClosed)
                            {
                                geoObjectOrgList[i]         = null; // zum nicht Weglöschen des Originals in onDone
                                pathCreatedFromModelList[i] = p;    // kopie merken für onDone
                                p = p.Clone() as Path;
                                p.Flatten();
                            }
                        }
                        if (p.IsClosed)
                        { // jetzt face machen
                            iGeoObjectTemp = Make3D.MakeFace(p, frame.Project);
                        }
                    }
                }
                if (iGeoObjectTemp != null)
                {                                 // also was geeignetes dabei
                    iGeoObjectTemp.CopyAttributes(iGeoObjectSel as IGeoObject);
                    faceList[i] = iGeoObjectTemp; // fertiger Körper in shapeList
                    success     = true;
                }
            } // for-Schleife über die Objekte der Liste
            if (success)
            {
                using (frame.Project.Undo.UndoFrame)
                {
                    for (int i = 0; i < selectedObjectsList.Count; i++)      // geht durch die komplette Liste
                    {
                        if (faceList[i] != null)                             // nur hier was machen!
                        {
                            outList.Add(faceList[i]);                        // die Guten sammeln
                            frame.Project.GetActiveModel().Add(faceList[i]); // einfügen
                            if (frame.GetBooleanSetting("Construct.3D_Delete2DBase", false))
                            {
                                if (geoObjectOrgList[i] != null) // evtl. Einzelobjekt (Object oder Path) als Original rauslöschen
                                {
                                    ownerList[i].Remove(geoObjectOrgList[i] as IGeoObject);
                                }
                                else
                                { // die Einzelelemente des CreateFromModel identifizieren
                                    for (int j = 0; j < pathCreatedFromModelList[i].Count; ++j)
                                    {
                                        IGeoObject obj = null;
                                        if ((pathCreatedFromModelList[i].Curve(j) as IGeoObject).UserData.ContainsData("CADability.Path.Original"))
                                        {
                                            obj = (pathCreatedFromModelList[i].Curve(j) as IGeoObject).UserData.GetData("CADability.Path.Original") as IGeoObject;
                                        }
                                        if (obj != null && obj.Owner != null)
                                        {
                                            obj.Owner.Remove(obj);                                   // löschen
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return(outList);
            }
            return(null);
        }
Esempio n. 15
0
        private void ShowContextMenu(Point mousePoint, IView vw)
        {
            currentView = vw;
            GeoObjectList result = new GeoObjectList();

            int pickRadius = soa.Frame.GetIntSetting("Select.PickRadius", 5);

            Projection.PickArea pa = vw.Projection.GetPickSpace(new Rectangle(mousePoint.X - pickRadius, mousePoint.Y - pickRadius, pickRadius * 2, pickRadius * 2));
            IActionInputView    pm = vw as IActionInputView;
            GeoObjectList       fl = vw.Model.GetObjectsFromRect(pa, new Set <Layer>(pm.GetVisibleLayers()), PickMode.onlyFaces, null); // returns all the face under the cursor

            // in most cases there is only a single face, which is of interest, only when we have two solids with same or overlapping faces
            // and one of them is not selectable without also selecting the other, we want both.
            faces    = new List <Face>();
            shells   = new List <Shell>(); // only Shells, which are not part of a Solid
            solids   = new List <Solid>();
            features = new List <IEnumerable <Face> >();
            double delta   = vw.Model.Extent.Size * 1e-4;
            double mindist = double.MaxValue;

            for (int i = 0; i < fl.Count; i++)
            {
                if (fl[i] is Face face) // this should always be the case
                {
                    double z = face.Position(pa.FrontCenter, pa.Direction, 0);
                    if (z < mindist)
                    {
                        if (z < mindist - delta)
                        {
                            faces.Clear();
                        }
                        faces.Add(face);
                        mindist = z;
                    }
                }
            }
            HashSet <Edge> relevantEdges = new HashSet <Edge>();

            for (int i = 0; i < faces.Count; i++)
            {
                relevantEdges.UnionWith(faces[i].AllEdges);
                if (faces[i].Owner is Shell shell)
                {
                    if (shell.Owner is Solid sld)
                    {
                        if (!solids.Contains(sld))
                        {
                            solids.Add(sld);
                        }
                    }
                    else
                    {
                        if (!shells.Contains(shell))
                        {
                            shells.Add(shell);
                        }
                    }
                }
            }
            for (int i = 0; i < faces.Count; i++)
            {
                if (faces[i].Owner is Shell shell)
                {
                    for (int j = 0; j < faces[i].OutlineEdges.Length; j++)
                    {
                        Edge edg = faces[i].OutlineEdges[j];
                        if (edg.IsPartOfHole(edg.OtherFace(faces[i])))
                        {
                            Face otherFace = edg.OtherFace(faces[i]);
                            if (otherFace != null)
                            {
                                Edge[]        hole  = otherFace.GetHole(edg);
                                List <Edge[]> loops = new List <Edge[]> {
                                    hole
                                };
                                List <IEnumerable <Face> > lfeatures = new List <IEnumerable <Face> >();
                                List <IEnumerable <Face> > lids      = new List <IEnumerable <Face> >();
                                HashSet <Face>             startWith = new HashSet <Face>();
                                foreach (Edge edge in hole)
                                {
                                    startWith.Add(edge.OtherFace(otherFace)); // all faces that are connected to the hole in "otherFace"
                                }
                                shell.FeaturesFromEdges(loops, lfeatures, lids, startWith);
                                for (int k = 0; k < lfeatures.Count; k++)
                                {
                                    if (lfeatures[k].Count() < shell.Faces.Length * 0.5)
                                    {
                                        features.Add(lfeatures[k]);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            curves = vw.Model.GetObjectsFromRect(pa, new Set <Layer>(pm.GetVisibleLayers()), PickMode.onlyEdges, null); // returns edges and curves
            edges  = new List <Edge>();
            // we only accept edges, which belong to one of the selected faces
            for (int i = curves.Count - 1; i >= 0; --i)
            {
                if (curves[i].Owner is Edge edge)
                {
                    if (relevantEdges.Contains(edge))
                    {
                        edges.Add(edge);
                    }
                    else
                    {
                        double z = curves[i].Position(pa.FrontCenter, pa.Direction, 0);
                        if (z - delta < mindist)
                        {
                            edges.Add(edge);                      // this is an edge in front of the closest face
                        }
                    }
                    curves.Remove(i);
                }
                else
                {
                    double z = curves[i].Position(pa.FrontCenter, pa.Direction, 0);
                    if (z - delta > mindist)
                    {
                        curves.Remove(i);
                    }
                }
            }

            // now we have curves, edges, faces, shells and solids (text, hatch, block, dimension not yet implemented) from the right click

            // we also need access to the already selected edges and faces to
            GeoObjectList  selobj        = soa.GetSelectedObjects();
            HashSet <Edge> selectedEdges = new HashSet <Edge>();
            HashSet <Face> selectedFaces = new HashSet <Face>();

            foreach (IGeoObject go in selobj)
            {
                if (go is ICurve && go.Owner is Edge edg)
                {
                    selectedEdges.Add(edg);
                }
                if (go is Face fc)
                {
                    selectedFaces.Add(fc);
                }
            }
            List <MenuWithHandler> cm = new List <MenuWithHandler>();

            Shell owningShell = null;

            if (edges.Count > 0)
            {
                owningShell = (edges[0].Owner as Face).Owner as Shell;
            }
            if (owningShell == null && faces.Count > 0)
            {
                owningShell = (faces[0].Owner as Shell);
            }
            if (owningShell == null && selectedFaces.Count > 0)
            {
                owningShell = selectedFaces.First().Owner as Shell;
            }
            if (owningShell == null && selectedEdges.Count > 0)
            {
                owningShell = (selectedEdges.First().Owner as Face).Owner as Shell;
            }
            if (owningShell != null)
            {
                for (int i = 0; i < features.Count; i++)
                {
                    List <Face>     featureI = new List <Face>(features[i]);
                    MenuWithHandler mh       = new MenuWithHandler("MenuId.Feature");
                    mh.OnSelected = (m, selected) =>
                    {
                        currentMenuSelection.Clear();
                        currentMenuSelection.AddRange(featureI.ToArray());
                        currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                    };
                    MenuWithHandler positionFeature = new MenuWithHandler("MenuId.Feature.Position");
                    MenuWithHandler nameFeature     = new MenuWithHandler("MenuId.Feature.Name");
                    mh.SubMenus = new MenuWithHandler[] { positionFeature, nameFeature };
                    // this is very rudimentary. We have to provide a version of ParametricsDistanceAction, where you can select from and to object. Only axis is implemented
                    Shell         shell = featureI[0].Owner as Shell;
                    GeoObjectList fa    = shell.FeatureAxis;
                    Line          axis  = null;
                    foreach (IGeoObject geoObject in fa)
                    {
                        Face axisOf = geoObject.UserData.GetData("CADability.AxisOf") as Face;
                        if (axisOf != null)
                        {
                            if (featureI.Contains(axisOf))
                            {
                                axis = geoObject as Line;
                            }
                        }
                        if (axis != null)
                        {
                            break;
                        }
                    }
                    positionFeature.OnCommand = (menuId) =>
                    {
                        ParametricsDistanceActionOld pd = new ParametricsDistanceActionOld(featureI, soa.Frame);
                        soa.Frame.SetAction(pd);
                        return(true);
                    };
                    positionFeature.OnSelected = (menuId, selected) =>
                    {
                        currentMenuSelection.Clear();
                        currentMenuSelection.AddRange(featureI.ToArray());
                        currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                    };
                    nameFeature.OnCommand = (menuId) =>
                    {
                        string name = shell.GetNewFeatureName();
                        shell.AddFeature(name, featureI);
                        if (shell.Owner is Solid sld)
                        {
                            soa.SetSelectedObject(sld);
                            IPropertyEntry toEdit = soa.Frame.ControlCenter.FindItem(name);
                            if (toEdit != null)
                            {
                                List <IPropertyEntry> parents = new List <IPropertyEntry>();
                                if (toEdit != null)
                                {
                                    IPropertyEntry p = toEdit;
                                    while ((p = p.Parent as IPropertyEntry) != null)
                                    {
                                        parents.Add(p);
                                    }
                                    IPropertyPage propertyPage = parents[parents.Count - 1].Parent as IPropertyPage;
                                    if (propertyPage != null)
                                    {
                                        for (int k = parents.Count - 1; k >= 0; --k)
                                        {
                                            propertyPage.OpenSubEntries(parents[k], true);
                                        }
                                        toEdit.StartEdit(false);
                                    }
                                }
                            }
                        }

                        return(true);
                    };
                    nameFeature.OnSelected = (menuId, selected) =>
                    {
                        currentMenuSelection.Clear();
                        currentMenuSelection.AddRange(featureI.ToArray());
                        currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                    };

                    cm.Add(mh);
                }
            }
            for (int i = 0; i < curves.Count; i++)
            {   // No implementation for simple curves yet.
                // We would need a logical connection structure as in vertex->edge->face->shell in 2d curves, which we currently do not have.
                Face faceWithAxis = (curves[i] as IGeoObject).UserData.GetData("CADability.AxisOf") as Face;
                if (faceWithAxis != null)
                {
                    MenuWithHandler mh = new MenuWithHandler("MenuId.Axis");
                    mh.SubMenus = GetFacesSubmenus(faceWithAxis).ToArray();
                    mh.Target   = this;
                    IGeoObject curveI = curves[i] as IGeoObject;
                    mh.OnSelected = (m, selected) =>
                    {
                        currentMenuSelection.Clear();
                        currentMenuSelection.Add(curveI);
                        currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                    };
                    cm.Add(mh);
                }
            }
            for (int i = 0; i < edges.Count; i++)
            {
                MenuWithHandler mh = new MenuWithHandler();
                mh.ID   = "MenuId.Edge." + i.ToString();
                mh.Text = StringTable.GetString("MenuId.Edge", StringTable.Category.label);
                List <MenuWithHandler> lmh             = new List <MenuWithHandler>();
                MenuWithHandler        selectMoreEdges = new MenuWithHandler("MenuId.SelectMoreEdges");
                lmh.Add(selectMoreEdges);
                Edge edgeI = edges[i];
                selectMoreEdges.OnCommand = (menuId) =>
                {
                    soa.SetSelectedObject(edgeI.Curve3D as IGeoObject);
                    soa.OverwriteMode(PickMode.onlyEdges);
                    return(true);
                };
                lmh.AddRange(edges[i].GetContextMenu(soa.Frame));
                mh.SubMenus = lmh.ToArray();
                mh.Target   = this;
                cm.Add(mh);
            }
            for (int i = 0; i < faces.Count; i++)
            {
                MenuWithHandler mh = new MenuWithHandler();
                mh.ID   = "MenuId.Face." + i.ToString();
                mh.Text = StringTable.GetString("MenuId.Face", StringTable.Category.label);
                List <MenuWithHandler> lmh             = new List <MenuWithHandler>();
                MenuWithHandler        selectMoreFaces = new MenuWithHandler("MenuId.SelectMoreFaces");
                lmh.Add(selectMoreFaces);
                Face faceI = faces[i];
                selectMoreFaces.OnCommand = (menuId) =>
                {
                    soa.SetSelectedObject(faceI);
                    soa.OverwriteMode(PickMode.onlyFaces);
                    return(true);
                };
                lmh.AddRange(GetFacesSubmenus(faces[i]));
                if (owningShell != null)
                {
                    double thickness = owningShell.GetGauge(faces[i], out HashSet <Face> frontSide, out HashSet <Face> backSide);
                    if (thickness != double.MaxValue && frontSide.Count > 0)
                    {
                        MenuWithHandler gauge = new MenuWithHandler("MenuId.Gauge");
                        gauge.OnCommand = (menuId) =>
                        {
                            ParametricsOffset po = new ParametricsOffset(frontSide, backSide, soa.Frame, thickness);
                            soa.Frame.SetAction(po);
                            return(true);
                        };
                        gauge.OnSelected = (menuId, selected) =>
                        {
                            currentMenuSelection.Clear();
                            currentMenuSelection.AddRange(frontSide.ToArray());
                            currentMenuSelection.AddRange(backSide.ToArray());
                            currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                        };
                        lmh.Add(gauge);
                    }
                    int n = owningShell.GetFaceDistances(faces[i], out List <Face> distanceTo, out List <double> distance, out List <GeoPoint> pointsFrom, out List <GeoPoint> pointsTo);
                    for (int j = 0; j < n; j++)
                    {
                        if (backSide == null || !backSide.Contains(distanceTo[j])) // this is not already used as gauge
                        {
                            HashSet <Face>  capturedFaceI    = new HashSet <Face>(new Face[] { faces[i] });
                            HashSet <Face>  capturedDistTo   = new HashSet <Face>(new Face[] { distanceTo[j] });
                            double          capturedDistance = distance[j];
                            GeoPoint        capturedPoint1   = pointsFrom[j];
                            GeoPoint        capturedPoint2   = pointsTo[j];
                            GeoObjectList   feedbackArrow    = currentView.Projection.MakeArrow(pointsFrom[j], pointsTo[j], currentView.Projection.ProjectionPlane, Projection.ArrowMode.circleArrow);
                            MenuWithHandler faceDist         = new MenuWithHandler("MenuId.FaceDistance");
                            faceDist.OnCommand = (menuId) =>
                            {
                                ParametricsDistanceAction pd = new ParametricsDistanceAction(capturedFaceI, capturedDistTo, capturedPoint1, capturedPoint2, soa.Frame);
                                soa.Frame.SetAction(pd);
                                return(true);
                            };
                            faceDist.OnSelected = (menuId, selected) =>
                            {
                                currentMenuSelection.Clear();
                                currentMenuSelection.AddRange(capturedFaceI.ToArray());
                                currentMenuSelection.AddRange(capturedDistTo.ToArray());
                                currentMenuSelection.AddRange(feedbackArrow);
                                currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                            };
                            lmh.Add(faceDist);
                        }
                    }
                }
                mh.SubMenus = lmh.ToArray();
                mh.Target   = this;
                cm.Add(mh);

                //cm.AddRange(GetFacesSubmenus(faces));
            }
            for (int i = 0; i < faces.Count; i++)
            {
                if (faces[i].Owner is Shell shell)
                {
                    Shell sh = shell.FeatureFromFace(faces[i]);
                }
            }
            for (int i = 0; i < edges.Count; i++)
            {
                if (edges[i].PrimaryFace.Owner is Shell shell)
                {
                    //shell.FeatureFromEdges(edges[i].PrimaryFace);
                }
            }
            for (int i = 0; i < shells.Count; i++)
            {
                MenuWithHandler mh = new MenuWithHandler();
                mh.ID       = "MenuId.Shell." + i.ToString();
                mh.Text     = StringTable.GetString("MenuId.Shell", StringTable.Category.label);
                mh.SubMenus = shells[i].GetContextMenu(soa.Frame);
                mh.Target   = this;
                cm.Add(mh);
            }
            for (int i = 0; i < solids.Count; i++)
            {
                MenuWithHandler mh = new MenuWithHandler();
                mh.ID       = "MenuId.Solid." + i.ToString();
                mh.Text     = StringTable.GetString("MenuId.Solid", StringTable.Category.label);
                mh.SubMenus = solids[i].GetContextMenu(soa.Frame);
                mh.Target   = this;
                cm.Add(mh);
            }
            {   // selection independent menu items
                MenuWithHandler mh = new MenuWithHandler();
                mh.ID   = "MenuId.Show";
                mh.Text = StringTable.GetString("MenuId.Show", StringTable.Category.label);
                MenuWithHandler mhShowHidden = new MenuWithHandler();
                mhShowHidden.ID        = "MenuId.ShowHidden";
                mhShowHidden.Text      = StringTable.GetString("MenuId.ShowHidden", StringTable.Category.label);
                mhShowHidden.OnCommand = (menuId) =>
                {
                    foreach (IGeoObject geoObject in vw.Model)
                    {
                        if (geoObject.Layer != null && geoObject.Layer.Name == "CADability.Hidden")
                        {
                            Layer layer = geoObject.UserData.GetData("CADability.OriginalLayer") as Layer;
                            if (layer != null)
                            {
                                geoObject.Layer = layer;
                            }
                        }
                    }
                    return(true);
                };
                MenuWithHandler mhShowAxis = new MenuWithHandler();
                mhShowAxis.ID        = "MenuId.ShowAxis";
                mhShowAxis.Text      = StringTable.GetString("MenuId.ShowAxis", StringTable.Category.label);
                mhShowAxis.OnCommand = (menuId) =>
                {
                    bool isOn = false;
                    foreach (IGeoObject geoObject in vw.Model)
                    {
                        Shell shell = null;
                        if (geoObject is Solid solid)
                        {
                            shell = solid.Shells[0];
                        }
                        else if (geoObject is Shell sh)
                        {
                            shell = sh;
                        }
                        if (shell != null && shell.FeatureAxis.Count > 0)
                        {
                            isOn = shell.FeatureAxis[0].IsVisible;
                            break;
                        }
                    }

                    using (vw.Canvas.Frame.Project.Undo.UndoFrame)
                    {
                        foreach (IGeoObject geoObject in vw.Model)
                        {
                            if (geoObject is Solid solid)
                            {
                                solid.ShowFeatureAxis = !isOn;
                            }
                            else if (geoObject is Shell shell)
                            {
                                shell.ShowFeatureAxis = !isOn;
                            }
                        }
                    }
                    return(true);
                };
                mhShowAxis.OnUpdateCommand = (menuId, commandState) =>
                {
                    bool isOn = false;
                    foreach (IGeoObject geoObject in vw.Model)
                    {
                        Shell shell = null;
                        if (geoObject is Solid solid)
                        {
                            shell = solid.Shells[0];
                        }
                        else if (geoObject is Shell sh)
                        {
                            shell = sh;
                        }
                        if (shell != null && shell.FeatureAxis.Count > 0)
                        {
                            isOn = shell.FeatureAxis[0].IsVisible;
                            break;
                        }
                    }
                    commandState.Checked = isOn;
                    return(true);
                };
                mh.SubMenus = new MenuWithHandler[] { mhShowHidden, mhShowAxis };
                mh.Target   = this;
                cm.Add(mh);
            }
            vw.SetPaintHandler(PaintBuffer.DrawingAspect.Select, new PaintView(OnRepaintSelect));
            mousePoint.X += vw.DisplayRectangle.Width / 8; // find a better place for the menu position, using the extent of the objects
            vw.Canvas.ShowContextMenu(cm.ToArray(), mousePoint, ContextMenuCollapsed);
        }
Esempio n. 16
0
        private bool rotateOrg(bool openDraw)
        {
            if (selectedObjectsList == null || selectedObjectsList.Count == 0)
            {
                return(false);
            }
            IGeoObject selectedObject = null;

            blk = Block.Construct(); // as feedback object
            if (base.ActiveObject != null)
            {
                blk.CopyAttributes(base.ActiveObject);
            }
            // der block wird das neue aktive Objekt, er muss die Attribute tragen, weil sie später
            // wieder von ihm verlangt werden
            Boolean   success       = false;
            GeoPoint  axisPointSav  = axisPoint;
            GeoVector axisVectorSav = axisVector;

            updateOptional();
            if (selectedObjectsList.Count > 1)
            {   // maybe there are several curves in the list, then we try to make a path
                // and use only this path. No mixture of faces and paths possible
                List <ICurve> crvs = new List <ICurve>();
                for (int i = 0; i < selectedObjectsList.Count; i++)
                {
                    if (selectedObjectsList[i] is ICurve crv)
                    {
                        crvs.Add(crv);
                    }
                }
                if (crvs.Count > 1)
                {
                    Path path = Path.FromSegments(crvs, false);
                    if (path != null)
                    {
                        selectedObjectsList.Clear();
                        selectedObjectsList.Add(path);
                    }
                }
            }
            for (int i = 0; i < selectedObjectsList.Count; i++)
            {
                IGeoObject objectToRotate = null;                   // lokaler Merker
                geoObjectOrgList[i]         = selectedObject;       // zum Weglöschen des Originals in onDone
                selectedObject              = selectedObjectsList[i];
                ownerList[i]                = selectedObject.Owner; // owner merken für löschen
                pathCreatedFromModelList[i] = null;
                shapeList[i]                = null;

                if ((selectedObject is Face) || (selectedObject is Shell))
                { // nur kopieren
                    objectToRotate = selectedObject.Clone();
                }
                else
                {
                    if (selectedObject is ICurve selCurve)
                    {
                        Path p = null;
                        if (!selCurve.IsClosed)
                        {
                            // trying to rotate an open curve: if the axis and the curve have a commonn plane close a path with the perpendicular foot points and axis segment
                            Line axisLine = Line.TwoPoints(axisPoint, axisPoint + axisVector);
                            if (Curves.GetCommonPlane(new ICurve[] { selCurve, axisLine }, out Plane commonPlane))
                            {
                                Line          l1         = Line.TwoPoints(selCurve.EndPoint, Geometry.DropPL(selCurve.EndPoint, axisPoint, axisVector));
                                Line          l2         = Line.TwoPoints(Geometry.DropPL(selCurve.StartPoint, axisPoint, axisVector), selCurve.StartPoint);
                                Line          l3         = Line.TwoPoints(l1.EndPoint, l2.StartPoint);
                                List <ICurve> closedPath = new List <ICurve>();
                                closedPath.Add(selCurve);
                                if (l1.Length > Precision.eps)
                                {
                                    closedPath.Add(l1);
                                }
                                if (l3.Length > Precision.eps)
                                {
                                    closedPath.Add(l3);
                                }
                                if (l2.Length > Precision.eps)
                                {
                                    closedPath.Add(l2);
                                }
                                p = Path.FromSegments(closedPath, true); // should always work
                                p.Flatten();
                            }
                        }
                        else
                        {
                            p = Path.FromSegments(new ICurve[] { selCurve }, true);
                        }
                        if (p == null)
                        {
                            continue;            // no path constructed
                        }
                        if ((p as ICurve).GetSelfIntersections().Length > 0)
                        {
                            continue;                                                  // not possible
                        }
                        if (!p.IsClosed)
                        {
                            continue;
                        }
                        // make a face from the closed pathe
                        objectToRotate = Make3D.MakeFace(p, Frame.Project, true);
                    }
                }
                if (objectToRotate != null)
                { // also was geeignetes dabei
                  //if (angleOffsetRotation != 0.0)
                  //{
                  //    ModOp m = ModOp.Rotate(axisPoint, axisVector, new SweepAngle(angleOffsetRotation));
                  //    iGeoObjectTemp.Modify(m);
                  //}
                    double sw = angleRotation;
                    if (sw == 0.0)
                    {
                        sw = Math.PI * 2.0;
                    }
                    // IGeoObject shape = Make3D.MakeRevolution(iGeoObjectTemp, axisPoint, axisVector, sw, Frame.Project);
                    IGeoObject shape = Make3D.Rotate(objectToRotate, new Axis(axisPoint, axisVector), sw, angleOffsetRotation, Frame.Project);
                    if (shape != null)
                    {
                        shape.CopyAttributes(blk);
                        shapeList[i] = shape;                      // fertiger Körper in shapeList
                        blk.Add(shape);                            // resulting object
                        base.FeedBack.AddSelected(objectToRotate); // zum Markieren des Ursprungsobjekts
                        success = true;
                    }
                }
            }
            axisPoint  = axisPointSav; // im Fall nicht geschlossener Pfad und nichts bestimmt, werden diese Parameter oben verstellt
            axisVector = axisVectorSav;
            if (success)
            {
                base.ActiveObject     = blk; // darstellen
                base.ShowActiveObject = true;
                return(true);
            }
            else
            {
                updateOptional();
                base.ShowActiveObject = false;
                base.FeedBack.ClearSelected();
                return(false);
            }
        }