예제 #1
0
 public override void OnDone()
 {
     if (edges.Count > 0)
     {
         IGeoObject[] affected;
         IGeoObject[] modified = Make3D.MakeChamfer(theFace, edges.ToArray(), dist1, dist2, out affected);
         if (affected.Length > 0)
         {
             using (Frame.Project.Undo.UndoFrame)
             {
                 IGeoObjectOwner owner = null;
                 for (int i = 0; i < affected.Length; ++i)
                 {
                     if (owner == null || affected[i].Owner is Model)
                     {
                         owner = affected[i].Owner;
                     }
                     affected[i].Owner.Remove(affected[i]);
                 }
                 for (int i = 0; i < modified.Length; ++i)
                 {
                     owner.Add(modified[i]);
                 }
             }
         }
     }
     base.OnDone();
 }
예제 #2
0
 public override void OnDone()
 {
     if (validResult && ActiveObject != null)
     {
         using (Frame.Project.Undo.UndoFrame)
         {
             Solid sld = shell.Owner as Solid;
             if (sld != null)
             {                                      // the shell was part of a Solid
                 IGeoObjectOwner owner = sld.Owner; // Model or Block
                 owner.Remove(sld);
                 Solid replacement = Solid.MakeSolid(ActiveObject as Shell);
                 owner.Add(replacement);
             }
             else
             {
                 IGeoObjectOwner owner = shell.Owner;
                 owner.Remove(shell);
                 owner.Add(ActiveObject);
             }
         }
     }
     ActiveObject = null;
     base.OnDone();
 }
예제 #3
0
 virtual public bool OnCommand(string MenuId)
 {
     switch (MenuId)
     {
     case "MenuId.Explode":
         if (Frame.ActiveAction is SelectObjectsAction)
         {
             using (Frame.Project.Undo.UndoFrame)
             {
                 IGeoObjectOwner addTo = dimension.Owner;
                 if (addTo == null)
                 {
                     addTo = Frame.ActiveView.Model;
                 }
                 GeoObjectList toSelect = dimension.Decompose();
                 addTo.Remove(dimension);
                 for (int i = 0; i < toSelect.Count; ++i)
                 {
                     addTo.Add(toSelect[i]);
                 }
                 SelectObjectsAction soa = Frame.ActiveAction as SelectObjectsAction;
                 soa.SetSelectedObjects(toSelect);     // alle Teilobjekte markieren
             }
         }
         return(true);
     }
     return(false);
 }
예제 #4
0
        public Constr3DRuledFace(GeoObjectList geoObjectList, IFrame frame)
        { // constructor für SelectedObjectsAction, ein selektierter Pfad
            bool pathCreatedFromModel;

            if (geoObjectList == null)
            {
                selectedMode = 0;
            }
            else
            {
                //if (geoObjectList.Count == 2)
                //    {  ruledSolidDo(geoObjectList, frame); }
                //else
                selectedMode = 1;
                p1           = findPath(geoObjectList[0], frame.ActiveView.Model, out pathCreatedFromModel);
                if (p1 != null)
                {
                    attrObject     = geoObjectList[0];       // merker, um das passende Attribut zu bekommen
                    iGeoObjectOrg1 = geoObjectList[0];       // zum Weglöschen des Originals in onDone
                    owner1         = geoObjectList[0].Owner; // owner merken für löschen
                    if (pathCreatedFromModel)
                    {
                        iGeoObjectOrg1        = null; // zum nicht Weglöschen des Originals in onDone
                        pathCreatedFromModel1 = p1;   // kopie merken für onDone
                    }
                }
            }
        }
예제 #5
0
            bool ICommandHandler.OnCommand(string MenuId)
            {
                switch (MenuId)
                {
                case "MenuId.Fillet.ChangeRadius":
                    ParametricsRadius pr = new ParametricsRadius(involvedFaces, selectActionContextMenu.soa.Frame, true);
                    selectActionContextMenu.soa.Frame.SetAction(pr);
                    return(true);

                case "MenuId.Fillet.Remove":
                    Shell orgShell = involvedFaces[0].Owner as Shell;
                    if (orgShell != null)
                    {
                        RemoveFillet rf = new RemoveFillet(involvedFaces[0].Owner as Shell, new HashSet <Face>(involvedFaces));
                        Shell        sh = rf.Result();
                        if (sh != null)
                        {
                            using (selectActionContextMenu.soa.Frame.Project.Undo.UndoFrame)
                            {
                                sh.CopyAttributes(orgShell);
                                IGeoObjectOwner owner = orgShell.Owner;
                                owner.Remove(orgShell);
                                owner.Add(sh);
                            }
                        }
                    }
                    return(true);
                }
                return(false);
            }
 public override void OnDone()
 {
     if (validResult && ActiveObject != null)
     {
         Solid sld = shell.Owner as Solid;
         if (sld != null)
         {                                      // the shell was part of a Solid
             IGeoObjectOwner owner = sld.Owner; // Model or Block
             using (Frame.Project.Undo.UndoFrame)
             {
                 owner.Remove(sld);
                 Solid replacement = Solid.MakeSolid(ActiveObject as Shell);
                 replacement.CopyAttributes(sld);
                 owner.Add(replacement);
                 if (!string.IsNullOrEmpty(parametricsName) && parametricProperty != null)
                 {
                     parametricProperty.Name = parametricsName;
                     replacement.Shells[0].AddParametricProperty(parametricProperty);
                 }
             }
         }
         else
         {
             IGeoObjectOwner owner = shell.Owner;
             using (Frame.Project.Undo.UndoFrame)
             {
                 owner.Remove(shell);
                 owner.Add(ActiveObject);
             }
         }
     }
     ActiveObject = null;
     base.OnDone();
 }
예제 #7
0
 /// <summary>
 /// Implements <see cref="CADability.UserInterface.ICommandHandler.OnCommand (string)"/>
 /// </summary>
 /// <param name="MenuId"></param>
 /// <returns></returns>
 virtual public bool OnCommand(string MenuId)
 {
     switch (MenuId)
     {
     case "MenuId.Explode":
         if (frame.ActiveAction is SelectObjectsAction)
         {
             using (frame.Project.Undo.UndoFrame)
             {
                 IGeoObjectOwner addTo = blockRef.Owner;
                 if (addTo == null)
                 {
                     addTo = frame.ActiveView.Model;
                 }
                 addTo.Remove(blockRef);
                 //IGeoObject go = blockRef.ReferencedBlock.Clone();
                 //go.PropagateAttributes(blockRef.Layer, blockRef.ColorDef);
                 GeoObjectList l = blockRef.Decompose();
                 addTo.Add(l[0]);
                 SelectObjectsAction soa = frame.ActiveAction as SelectObjectsAction;
                 soa.SetSelectedObjects(l);     // alle Teilobjekte markieren
             }
         }
         return(true);
     }
     return(false);
 }
예제 #8
0
        virtual public bool OnCommand(string MenuId)
        {
            switch (MenuId)
            {
            case "MenuId.Reverse":
                polyline.Reverse();
                return(true);

            case "MenuId.CurveSplit":
                Frame.SetAction(new ConstrSplitCurve(polyline));
                return(true);

            case "MenuId.Explode":
                if (Frame.ActiveAction is SelectObjectsAction)
                {
                    using (Frame.Project.Undo.UndoFrame)
                    {
                        IGeoObjectOwner addTo = polyline.Owner;
                        if (addTo == null)
                        {
                            addTo = Frame.ActiveView.Model;
                        }
                        GeoObjectList toSelect = polyline.Decompose();
                        addTo.Remove(polyline);
                        for (int i = 0; i < toSelect.Count; ++i)
                        {
                            addTo.Add(toSelect[i]);
                        }
                        SelectObjectsAction soa = Frame.ActiveAction as SelectObjectsAction;
                        soa.SetSelectedObjects(toSelect);     // alle Teilobjekte markieren
                    }
                }
                return(true);

            case "MenuId.Aequidist":
                Frame.SetAction(new ConstructAequidist(polyline));
                return(true);

            case "MenuId.Path.Vertex.StartWithMe":
            {
                if (polyline.IsClosed)
                {
                    GeoPointProperty gpp = Frame.ContextMenuSource as GeoPointProperty;
                    if (gpp != null)
                    {
                        if (gpp.UserData.ContainsData("Index"))
                        {
                            int index = (int)gpp.UserData.GetData("Index");
                            polyline.CyclicalPermutation(index);
                        }
                    }
                }
            }
                return(true);
            }
            return(false);
        }
예제 #9
0
        virtual public bool OnCommand(string MenuId)
        {
            switch (MenuId)
            {
            case "MenuId.Explode":
                if (Frame.ActiveAction is SelectObjectsAction)
                {
                    SelectObjectsAction soa = Frame.ActiveAction as SelectObjectsAction;
                    soa.SetSelectedObjects(new GeoObjectList());
                    //Application.DoEvents();
                    using (Frame.Project.Undo.UndoFrame)
                    {
                        IGeoObjectOwner addTo = block.Owner;
                        if (addTo == null)
                        {
                            addTo = Frame.ActiveView.Model;
                        }
                        addTo.Remove(block);
                        GeoObjectList toSelect = block.Decompose();
                        for (int i = 0; i < toSelect.Count; i++)
                        {
                            addTo.Add(toSelect[i]);
                        }

                        soa.SetSelectedObjects(toSelect);     // alle Teilobjekte markieren
                    }
                }
                return(true);

            case "MenuId.SelectedObject.ToBackground":
                if (ContextMenuSource != null)
                {
                    block.MoveToBack(ContextMenuSource);
                    subEntries = null;
                    if (propertyPage != null)
                    {
                        propertyPage.Refresh(this);
                    }
                }
                return(true);

            case "MenuId.SelectedObject.ToForeground":
                if (ContextMenuSource != null)
                {
                    block.MoveToFront(ContextMenuSource);
                    subEntries = null;
                    if (propertyPage != null)
                    {
                        propertyPage.Refresh(this);
                    }
                }
                return(true);
            }
            return(false);
        }
예제 #10
0
 public override void OnDone()
 {
     if (edges.Count > 0)
     {
         IGeoObject[] affected;
         IGeoObject[] modified = Make3D.MakeFillet(edges.ToArray(), radius, out affected);
         if (affected != null && affected.Length > 0)
         {
             using (Frame.Project.Undo.UndoFrame)
             {
                 IGeoObjectOwner owner = null; // should be a solid if the affected shell is part of a solid, or owner should be the model
                 // only the edges of a single shell should be rounded!
                 for (int i = 0; i < affected.Length; ++i)
                 {
                     if (owner == null || affected[i].Owner is Model)
                     {
                         owner = affected[i].Owner;
                     }
                     affected[i].Owner.Remove(affected[i]);
                 }
                 if (owner is Model model)
                 {
                     model.Remove(affected);
                     model.Add(modified);
                 }
                 else if (owner is Solid sld)
                 {
                     Model m = sld.Owner as Model;
                     if (m != null)    // not able to round edges of Solid which is part of a Block?
                     {
                         m.Remove(sld);
                         for (int i = 0; i < modified.Length; ++i)
                         {
                             Solid rsld = Solid.Construct();
                             rsld.SetShell(modified[i] as Shell);
                             m.Add(rsld);
                         }
                     }
                 }
             }
         }
     }
     base.OnDone();
 }
예제 #11
0
        void geoObjectInputPath2Changed(ConstructAction.GeoObjectInput sender, IGeoObject SelectedGeoObject)
        {
            //            iGeoObjectSel2 = SelectedGeoObject;
            bool createdFromModel;

            p2 = findPath(SelectedGeoObject, base.Frame.ActiveView.Model, out createdFromModel);
            if (p2 != null)
            {
                iGeoObjectOrg2 = SelectedGeoObject;       // zum Weglöschen des Originals in onDone
                owner2         = SelectedGeoObject.Owner; // owner merken für löschen
                if (createdFromModel)
                {
                    iGeoObjectOrg2        = null; // zum nicht Weglöschen des Originals in onDone
                    pathCreatedFromModel2 = p2;   // kopie merken für onDone
                }
                if (p1 != null)                   // anderer Pfad schon bestimmt
                {
                    ruledFaceOrg();
                }
            }
        }
예제 #12
0
        void geoObjectInputPath1Changed(ConstructAction.GeoObjectInput sender, IGeoObject SelectedGeoObject)
        {
            bool createdFromModel;

            p1 = findPath(SelectedGeoObject, base.Frame.ActiveView.Model, out createdFromModel);
            if (p1 != null)
            {
                attrObject     = SelectedGeoObject;       // merker, um das passende Attribut zu bekommen
                iGeoObjectOrg1 = SelectedGeoObject;       // zum Weglöschen des Originals in onDone
                owner1         = SelectedGeoObject.Owner; // owner merken für löschen
                if (createdFromModel)
                {
                    iGeoObjectOrg1        = null; // zum nicht Weglöschen des Originals in onDone
                    pathCreatedFromModel1 = p1;   // kopie merken für onDone
                }
                if (p2 != null)                   // anderer Pfad schon bestimmt
                {
                    ruledFaceOrg();
                }
            }
        }
예제 #13
0
        internal static void Approximate(IFrame frame, IGeoObject toApproximate)
        {   // die Approximation gemäß globaler Einstellung aus einem ShowProperty heraus,
            // also mit SelectObjectsAction als aktiver Aktion
            ICurve app = (toApproximate as ICurve).Approximate(frame.GetIntSetting("Approximate.Mode", 0) == 0, frame.GetDoubleSetting("Approximate.Precision", 0.01));

            Actions.SelectObjectsAction soa   = frame.ActiveAction as Actions.SelectObjectsAction;
            IGeoObjectOwner             addTo = toApproximate.Owner;

            if (addTo == null)
            {
                addTo = frame.ActiveView.Model;
            }
            using (frame.Project.Undo.UndoFrame)
            {
                addTo.Remove(toApproximate);
                IGeoObject go = app as IGeoObject;
                go.CopyAttributes(toApproximate);
                addTo.Add(go);
                soa.SetSelectedObjects(new GeoObjectList(go));
            }
        }
예제 #14
0
        private bool showObject()
        {       // jetzt werden die Schnittparameter bestimmt
            base.ActiveObject = null;
            base.FeedBack.ClearSelected();
            double[] cutPlace;
            owner     = (iCurve as IGeoObject).Owner; // owner merken für löschen und Einfügen
            trimCurve = null;
            param1    = 0.0;
            param2    = 1.0;

            //			if (trimObject.Fixed)
            if (sourceCurve != null)
            {
                cutPlace = Curves.Intersect(iCurve, sourceCurve, true);
                Array.Sort(cutPlace);
            }
            else
            {
                cutPlace = base.Frame.ActiveView.ProjectedModel.GetIntersectionParameters(iCurve, ProjectedModel.IntersectionMode.InsideAndSelfIntersection);
            }
            // von Gerhard: cutPlace hat alle Schnittpositionen, aufsteigend sortiert
            // ein Problem taucht auf, wenn das Objekt an Anfangspunkt oder Endpunkt
            // genau einen Schnitt hat, dann enthält cutPlace 0.0 oder 1.0. Sind das dann die
            // einzigen Schnittpunkte, dann soll das Objekt gelöscht werden können:
            //   ein Schnittpunkt			sehr nahe bei Null         oder   sehr nahe bei eins
            deleteObject = true;
            for (int i = 0; i < cutPlace.Length; i++)
            { // also: nicht entweder fast Null oder fast eins
                if (!((Math.Abs(cutPlace[i]) < 1e-8) || (Math.Abs(cutPlace[i] - 1) < 1e-8)))
                {
                    deleteObject = false;
                    break;
                }
            }

            //if ((cutPlace.Length == 1) && ((Math.Abs(cutPlace[0])<1e-10) || (Math.Abs(cutPlace[0]-1) <1e-10))
            //    ||
            //    // oder 2 Schnittpunkte  und  erster sehr nahe bei Null  und zweiter sehr nahe bei eins
            //    ((cutPlace.Length == 2) && ((Math.Abs(cutPlace[0])<1e-10) && (Math.Abs(cutPlace[1]-1) <1e-10)))
            //    ||
            //        ((cutPlace.Length == 0) && (sourceCurve == null))) // also: einzeln stehendes Element ohne Schnittpunkte
            if (deleteObject)
            {
                trimCurve = iCurve.Clone();
                //				deleteObject = true;
            }
            else
            {
                // von Gerhard: cutPlace hat alle Schnittpositionen, aufsteigend sortiert
                // ein Problem taucht auf, wenn das Objekt an Anfangspunkt oder Endpunkt
                // genau einen Schnitt hat, dann enthält cutPlace 0.0 oder 1.0. Das tritt oft
                // auf, z.B. wenn man eine Linie zweimal trimmt. Also alles was <=0.0 und =>1.0 ist
                // muss raus:
                if (iCurve.IsClosed)
                {
                    // hier evtl. Schnittpunkte bei 0.0 auf 1.0 verdoppeln und umgekehrt, da man nicht weiss, welche Seite man wegtrimmen will
                    // es funktioniert aber auch so, warum auch immer
                    List <double> lst = new List <double>(cutPlace);
                    if (cutPlace[cutPlace.Length - 1] >= 1 - 1e-10)
                    {
                        lst.Insert(0, 0.0);                                             // wenn 1.0 ein Schnittpunkt ist, dann im geschlossenen Fall auch 0.0
                    }
                    if (cutPlace[0] <= 1e-10)
                    {
                        lst.Add(1.0);
                    }
                    cutPlace = lst.ToArray();
                }
                else
                {
                    ArrayList tmp = new ArrayList(cutPlace.Length);
                    for (int i = 0; i < cutPlace.Length; ++i)
                    {
                        if (cutPlace[i] > 1e-10 && cutPlace[i] < 1 - 1e-10)
                        {
                            tmp.Add(cutPlace[i]);
                        }
                    }
                    cutPlace = (double[])tmp.ToArray(typeof(double));
                }
                double pos = iCurve.PositionOf(objectPoint);
                if (cutPlace.Length > 0) // es gibt mindestens einen Schnittpunkt, Schnittpunkte sind sortiert!!
                {
                    int k = -1;
                    for (int i = 0; i < cutPlace.Length; ++i)
                    {
                        if (cutPlace[i] > pos && ((cutPlace[i] > 0.0 && cutPlace[i] < 1.0) || iCurve.IsClosed))
                        {          // pos ist oft -0.01 oder 1.01, da am Anfang oder Ende gepickt
                            k = i; // Schnittstelle "oberhalb" gefunden
                            break;
                        }
                    }
                    ICurve[] splitedCurves;
                    if (iCurve.IsClosed)
                    {
                        if (k > 0) // zwei Schnittpunkte oberhalb von 0.0 = 0 Grad des Kreises
                        {          // dieser Split gilt nur für geschlossenes:
                            splitedCurves = iCurve.Split(cutPlace[k - 1], cutPlace[k]);
                            if (splitedCurves.Length >= 2)
                            {
                                param1    = cutPlace[k - 1];  // merken für onDone
                                param2    = cutPlace[k];      // merken für onDone
                                trimCurve = splitedCurves[0]; // nur den einen nehmen, da eindeutig sortiert
                            }
                        }
                        else
                        {
                            if (cutPlace.Length > 1) // erster und letzter Schnittpunkt, 0 Grad ist eingeschlossen
                            {
                                splitedCurves = iCurve.Split(cutPlace[0], cutPlace[cutPlace.Length - 1]);
                                if (splitedCurves.Length >= 2)
                                {
                                    param1    = cutPlace[cutPlace.Length - 1]; // merken für onDone
                                    param2    = cutPlace[0];                   // merken für onDone
                                    trimCurve = splitedCurves[1];              // nur den einen nehmen, da eindeutig sortiert
                                }
                            }
                        }
                    }
                    else            // jetzt die offenen Objekte:
                    {
                        if (k <= 0) // trimmen am Ende
                        {
                            if (k == -1)
                            {   //  Pickpunkt am oberen Ende
                                splitedCurves = iCurve.Split(cutPlace[cutPlace.Length - 1]);
                                if (splitedCurves.Length >= 2)
                                {
                                    param2    = cutPlace[cutPlace.Length - 1]; // trimm(0.0,param2) merken für onDone
                                    trimCurve = splitedCurves[1];
                                }
                            }
                            if (k == 0)
                            {   //  Pickpunkt am unteren Ende
                                splitedCurves = iCurve.Split(cutPlace[0]);
                                if (splitedCurves.Length >= 2)
                                {
                                    param1    = cutPlace[0]; // trimm(param1,1.0), merken für onDone
                                    trimCurve = splitedCurves[0];
                                }
                            }
                        }
                        else  // trimmen mit mehreren Schnittpunkten, Pickpunkt mittendrinn
                        {
                            trimCurve     = iCurve.Clone(); // zunächst Kopie der Kurve
                            splitedCurves = iCurve.Split(cutPlace[k - 1]); // Schnittpunkt unterhalb
                            if (splitedCurves.Length >= 2)
                            {
                                param1    = cutPlace[k - 1];  // merken für onDone
                                trimCurve = splitedCurves[1]; // Kurvenkopie unten abgeschnitten
                            }
                            else
                            {
                                param1 = cutPlace[k];                                                           // merken für onDone
                            }
                            splitedCurves = trimCurve.Split(trimCurve.PositionOf(iCurve.PointAt(cutPlace[k]))); // Schnittpunkt oberhalb
                            if (splitedCurves.Length >= 2)
                            {
                                param2    = cutPlace[k];      // merken für onDone
                                trimCurve = splitedCurves[0]; // Kurvenkopie auch noch oben abgeschnitten
                            }
                            else
                            {
                                param2 = cutPlace[k - 1];   // merken für onDone
                            }
                        }
                    }
                }
            }
            if (trimCurve != null)
            {
                (trimCurve as IGeoObject).CopyAttributes(iCurve as IGeoObject);
                Color backColor = base.Frame.GetColorSetting("Colors.Feedback", Color.DarkGray);
                if (trimCurve is IColorDef)
                {
                    (trimCurve as IColorDef).ColorDef = new ColorDef("", backColor);
                }
                base.FeedBack.AddSelected(trimCurve as IGeoObject); // darstellen
                base.ActiveObject = trimCurve as IGeoObject;        // merken
                return(true);
            }
            return(false);
        }
예제 #15
0
        virtual public bool OnCommand(string MenuId)
        {
            switch (MenuId)
            {
            case "MenuId.Reverse":
                (path as ICurve).Reverse();
                if (propertyPage != null)
                {
                    propertyPage.Refresh(this);
                }
                return(true);

            case "MenuId.CurveSplit":
                Frame.SetAction(new ConstrSplitCurve(path));
                return(true);

            case "MenuId.Approximate":
                if (Frame.ActiveAction is SelectObjectsAction)
                {
                    Curves.Approximate(Frame, path);
                }
                return(true);

            case "MenuId.Explode":
                if (Frame.ActiveAction is SelectObjectsAction)
                {
                    using (Frame.Project.Undo.UndoFrame)
                    {
                        IGeoObjectOwner addTo = path.Owner;
                        if (addTo == null)
                        {
                            addTo = Frame.ActiveView.Model;
                        }
                        ICurve[]      pathCurves = path.Curves;
                        GeoObjectList toSelect   = path.Decompose();
                        addTo.Remove(path);
                        for (int i = toSelect.Count - 1; i >= 0; --i)
                        {
                            if (!toSelect[i].HasValidData())
                            {
                                toSelect.Remove(i);
                            }
                        }
                        for (int i = 0; i < toSelect.Count; i++)
                        {
                            addTo.Add(toSelect[i]);
                        }
                        SelectObjectsAction soa = Frame.ActiveAction as SelectObjectsAction;
                        soa.SetSelectedObjects(toSelect);     // alle Teilobjekte markieren
                    }
                }
                return(true);

            case "MenuId.Aequidist":
                Frame.SetAction(new ConstructAequidist(path));
                return(true);

            case "MenuId.Reduce":
                if (path.GetPlanarState() == PlanarState.Planar)
                {
                    Plane  pln = path.GetPlane();
                    Path2D p2d = path.GetProjectedCurve(pln) as Path2D;
                    if (p2d != null)
                    {
                        p2d.ForceConnected();
                        Reduce2D r2d = new Reduce2D();
                        r2d.Precision = Settings.GlobalSettings.GetDoubleValue("Approximate.Precision", 0.01);
                        r2d.Add(p2d.SubCurves);
                        r2d.OutputMode = Reduce2D.Mode.Paths;
                        ICurve2D[] red = r2d.Reduced;
                        if (red.Length == 1)
                        {
                            using (Frame.Project.Undo.UndoFrame)
                            {
                                IGeoObjectOwner addTo = path.Owner;
                                if (addTo == null)
                                {
                                    addTo = Frame.ActiveView.Model;
                                }
                                addTo.Remove(path);
                                Path redpath = red[0].MakeGeoObject(pln) as Path;
                                if (redpath != null)
                                {
                                    SelectObjectsAction soa = Frame.ActiveAction as SelectObjectsAction;
                                    soa.SetSelectedObjects(new GeoObjectList(redpath));
                                }
                            }
                        }
                    }
                }
                return(true);
            }
            return(false);
        }
예제 #16
0
        private bool showObject()
        {       // jetzt werden die Schnittparameter bestimmt
            base.FeedBack.ClearSelected();
            base.ActiveObject = null;
            double[] cutPlace = base.Frame.ActiveView.ProjectedModel.GetIntersectionParameters(iCurve, ProjectedModel.IntersectionMode.InsideAndSelfIntersection);
            owner = (iCurve as IGeoObject).Owner;        // owner merken für löschen und Einfügen

            double pos = iCurve.PositionOf(objectPoint); // der Pickpunkt

            trimCurves = null;
            bool realCut;

            if (cutPlace.Length > 0) // es gibt mindestens einen Schnitt
            {
                realCut = false;
                for (int i = 0; i < cutPlace.Length; ++i)
                {
                    if (!((Math.Abs(cutPlace[i]) < 1e-8) || (Math.Abs(cutPlace[i] - 1) < 1e-8)))
                    {
                        realCut = true;
                        break;
                    }
                }
                if (realCut)
                {
                    int k = -1;
                    for (int i = 0; i < cutPlace.Length; ++i)
                    {
                        if (cutPlace[i] > pos && cutPlace[i] > 0.0 && cutPlace[i] < 1.0)
                        {          // pos ist oft -0.01 oder 1.01, da am Anfang oder Ende gepickt
                            k = i; // Schnittstelle "oberhalb" gefunden
                            break;
                        }
                    }
                    ICurve[] splitedCurves;
                    if (iCurve.IsClosed)
                    {
                        if (k > 0) // zwei Schnittpunkte oberhalb von 0.0 = 0 Grad des Kreises/Rechtecks
                        {
                            splitedCurves = iCurve.Split(cutPlace[k - 1], cutPlace[k]);
                            if (splitedCurves.Length >= 2)
                            {
                                trimCurves = splitedCurves;    // nur den einen nehmen, da eindeutig sortiert
                                trimCurve  = splitedCurves[0]; // nur den einen nehmen, da eindeutig sortiert
                            }
                        }
                        else
                        {
                            if (cutPlace.Length > 1) // erster und letzter Schnittpunkt, 0 Grad ist eingeschlossen
                            {
                                splitedCurves = iCurve.Split(cutPlace[0], cutPlace[cutPlace.Length - 1]);
                                if (splitedCurves.Length >= 2)
                                {
                                    trimCurves = splitedCurves;    // nur den einen nehmen, da eindeutig sortiert
                                    trimCurve  = splitedCurves[1]; // nur den einen nehmen, da eindeutig sortiert
                                }
                            }
                        }
                    }
                    else
                    {
                        // jetzt die offenen Objekte:
                        if (k <= 0)  // trimmen am Ende
                        {
                            if (k == -1)
                            {   //  Pickpunkt am oberen Ende
                                splitedCurves = iCurve.Split(cutPlace[cutPlace.Length - 1]);
                                if (splitedCurves.Length >= 2)
                                {
                                    trimCurves = splitedCurves;
                                    // nur den einen nehmen, da eindeutig sortiert
                                    trimCurve = splitedCurves[1];
                                }
                            }
                            if (k == 0)
                            {   //  Pickpunkt am unteren Ende
                                splitedCurves = iCurve.Split(cutPlace[0]);
                                if (splitedCurves.Length >= 2)
                                {
                                    trimCurves = splitedCurves;
                                    // nur den einen nehmen, da eindeutig sortiert
                                    trimCurve = splitedCurves[0];
                                }
                            }
                        }
                        else  // trimmen mit mehreren Schnittpunkten, Pickpunkt mittendrinn
                        {
                            /*					trimCurves = new ICurve[3];
                             *                  splitedCurves = iCurve.Split(cutPlace[k-1]);
                             *                  trimCurves[0] = splitedCurves[0]; // untere Linie
                             *                  splitedCurves = iCurve.Split(cutPlace[k]);
                             *                  trimCurves[1] = splitedCurves[1]; // obere Linie
                             *                  ICurve curveTmp = iCurve.Clone();
                             *                  curveTmp.Trim(cutPlace[k-1],cutPlace[k]); // mittlere Linie
                             *                  trimCurves[2] = curveTmp;
                             */
                            trimCurve = iCurve.Clone(); // zunächst Kopie der Kurve
                            // tempräres Array zum Sammeln der Kurven
                            ArrayList tmpArray = new ArrayList();
                            splitedCurves = iCurve.Split(cutPlace[k - 1]); // Schnittpunkt unterhalb
                            if (splitedCurves.Length >= 2)
                            {                                              // den unteren Abschnitt sammeln
                                tmpArray.Add(splitedCurves[0]);
                                trimCurve = splitedCurves[1];              // Kurvenkopie unten abgeschnitten
                            }
                            // auf der (evtl) unten abgeschnittenen Kopie weitermachen
                            splitedCurves = trimCurve.Split(trimCurve.PositionOf(iCurve.PointAt(cutPlace[k]))); // Schnittpunkt oberhalb
                            if (splitedCurves.Length >= 2)
                            {
                                tmpArray.Add(splitedCurves[0]);
                                tmpArray.Add(splitedCurves[1]);
                                trimCurve = splitedCurves[0]; // Kurvenkopie auch noch oben abgeschnitten
                            }
                            else
                            {
                                tmpArray.Add(trimCurve);                             // kein echter Schnittpunkt, dann das Reststück zufügen
                            }
                            trimCurves = (ICurve[])tmpArray.ToArray(typeof(ICurve)); // reTyping nach Sammeln
                        }
                    }
                }
            }
            if (trimCurves != null)
            {
                (trimCurve as IGeoObject).CopyAttributes(iCurve as IGeoObject);
                Color backColor = base.Frame.GetColorSetting("Colors.Feedback", Color.DarkGray);
                if (trimCurve is IColorDef)
                {
                    (trimCurve as IColorDef).ColorDef = new ColorDef("", backColor);
                }
                base.FeedBack.AddSelected(trimCurve as IGeoObject); // darstellen
                base.ActiveObject = trimCurve as IGeoObject;        // merken
                return(true);
            }
            return(false);
        }
예제 #17
0
        bool geoObjectInputPath2(ConstructAction.GeoObjectInput sender, IGeoObject[] TheGeoObjects, bool up)
        {   // ... nur die sinnvollen Kurven verwenden
            //            objectPoint = base.CurrentMousePosition;
            bool      createdFromModel;
            ArrayList usableObjects = new ArrayList();

            for (int i = 0; i < TheGeoObjects.Length; ++i)
            {
                p2 = findPath(TheGeoObjects[i], base.Frame.ActiveView.Model, out createdFromModel);
                if (p2 != null)
                {
                    //                    if (geoObjectInput1.Fixed)
                    if (p1 != null) // anderer Pfad schon bestimmt
                    {
                        if (ruledFaceOrg())
                        {
                            usableObjects.Add(TheGeoObjects[i]);
                        }
                    }
                    else
                    {
                        usableObjects.Add(TheGeoObjects[i]);
                    }
                }
            }
            // ...hier wird der ursprüngliche Parameter überschrieben. Hat ja keine Auswirkung nach außen.
            TheGeoObjects = (IGeoObject[])usableObjects.ToArray(typeof(IGeoObject));
            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
                p2 = findPath(TheGeoObjects[0], base.Frame.ActiveView.Model, out createdFromModel);
                if (p2 != null)
                {
                    iGeoObjectOrg2 = TheGeoObjects[0];       // zum Weglöschen des Originals in onDone
                    owner2         = TheGeoObjects[0].Owner; // owner merken für löschen
                    if (createdFromModel)
                    {
                        iGeoObjectOrg2        = null; // zum nicht Weglöschen des Originals in onDone
                        pathCreatedFromModel2 = p2;   // kopie merken für onDone
                    }
                    if (p1 != null)                   // anderer Pfad schon bestimmt
                    {
                        return(ruledFaceOrg());
                    }
                    else
                    {
                        return(true);
                    }
                }
            }
            p2 = null;
            base.ShowActiveObject = false;
            return(false);
        }
예제 #18
0
        private List <MenuWithHandler> GetFacesSubmenus(Face face)
        {
            List <MenuWithHandler> res = new List <MenuWithHandler>();

            if (face.IsFillet())
            {
                HashSet <Face> connectedFillets = new HashSet <Face>();
                CollectConnectedFillets(face, connectedFillets);
                FeatureCommandHandler fch = new FeatureCommandHandler(connectedFillets.ToArray(), this, "MenuId.Fillet");
                MenuWithHandler       fr  = new MenuWithHandler("MenuId.Fillet.ChangeRadius");
                fr.OnCommand = (menuId) =>
                {
                    ParametricsRadius pr = new ParametricsRadius(connectedFillets.ToArray(), soa.Frame, true);
                    soa.Frame.SetAction(pr);
                    return(true);
                };
                fr.OnSelected = (mh, selected) =>
                {
                    currentMenuSelection.Clear();
                    currentMenuSelection.AddRange(connectedFillets.ToArray());
                    currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                };
                MenuWithHandler fd = new MenuWithHandler("MenuId.Fillet.Remove");
                fd.OnCommand = (menuId) =>
                {
                    Face[] involvedFaces = connectedFillets.ToArray();
                    Shell  orgShell      = involvedFaces[0].Owner as Shell;
                    if (orgShell != null)
                    {
                        RemoveFillet rf = new RemoveFillet(involvedFaces[0].Owner as Shell, new HashSet <Face>(involvedFaces));
                        Shell        sh = rf.Result();
                        if (sh != null)
                        {
                            using (soa.Frame.Project.Undo.UndoFrame)
                            {
                                sh.CopyAttributes(orgShell);
                                IGeoObjectOwner owner = orgShell.Owner;
                                owner.Remove(orgShell);
                                owner.Add(sh);
                            }
                        }
                    }
                    soa.ResetMode();
                    return(true);
                };
                fd.OnSelected = (mh, selected) =>
                {
                    currentMenuSelection.Clear();
                    currentMenuSelection.AddRange(connectedFillets.ToArray());
                    currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                };
                fch.SubMenus = new MenuWithHandler[] { fr, fd };
                res.Add(fch);
            }
            IEnumerable <Face> connected = face.GetSameSurfaceConnected();

            // if (connected.Any())
            {
                List <Face> lconnected = new List <Face>(connected);
                lconnected.Add(face);
                BoundingCube ext = BoundingCube.EmptyBoundingCube;
                foreach (Face fc in connected)
                {
                    ext.MinMax(fc.GetExtent(0.0));
                }
                // maybe a full sphere, cone, cylinder or torus:
                // except for the sphere: position axis
                // except for the cone: change radius or diameter
                // for the cone: smaller and larger diameter
                // for cone and cylinder: total length
                if (face.Surface is CylindricalSurface || face.Surface is CylindricalSurfaceNP || face.Surface is ToroidalSurface)
                {
                    MenuWithHandler mh = new MenuWithHandler("MenuId.FeatureDiameter");
                    mh.OnCommand = (menuId) =>
                    {
                        ParametricsRadius pr = new ParametricsRadius(lconnected.ToArray(), soa.Frame, false);
                        soa.Frame.SetAction(pr);
                        return(true);
                    };
                    mh.OnSelected = (menuId, selected) =>
                    {
                        currentMenuSelection.Clear();
                        currentMenuSelection.AddRange(lconnected.ToArray());
                        currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                    };
                    res.Add(mh);
                }
                if (face.Surface is CylindricalSurface || face.Surface is CylindricalSurfaceNP || face.Surface is ConicalSurface)
                {
                    Line axis = null;

                    if (face.Surface is ICylinder cyl)
                    {
                        axis = cyl.Axis.Clip(ext);
                    }
                    if (face.Surface is ConicalSurface cone)
                    {
                        axis = cone.AxisLine(face.Domain.Bottom, face.Domain.Top);
                    }
                    MenuWithHandler mh = new MenuWithHandler("MenuId.AxisPosition");
                    mh.OnCommand = (menuId) =>
                    {
                        ParametricsDistanceActionOld pd = new ParametricsDistanceActionOld(lconnected, axis, soa.Frame);
                        soa.Frame.SetAction(pd);
                        return(true);
                    };
                    mh.OnSelected = (menuId, selected) =>
                    {
                        currentMenuSelection.Clear();
                        currentMenuSelection.AddRange(lconnected.ToArray());
                        currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                    };
                    res.Add(mh);
                }
            }
            if (face.Surface is PlaneSurface pls)
            {
                // try to find parallel outline edges to modify the distance
                Edge[] outline = face.OutlineEdges;
                for (int j = 0; j < outline.Length - 1; j++)
                {
                    for (int k = j + 1; k < outline.Length; k++)
                    {
                        if (outline[j].Curve3D is Line l1 && outline[k].Curve3D is Line l2)
                        {
                            if (Precision.SameDirection(l1.StartDirection, l2.StartDirection, false))
                            {
                                // two parallel outline lines, we could parametrize the distance
                                Edge   o1   = outline[j];
                                Edge   o2   = outline[k]; // outline[i] is not captured correctly for the anonymous method. I don't know why. With local copies, it works.
                                double lmin = double.MaxValue;
                                double lmax = double.MinValue;
                                double p    = Geometry.LinePar(l1.StartPoint, l1.EndPoint, l2.StartPoint);
                                lmin = Math.Min(lmin, p);
                                lmax = Math.Max(lmax, p);
                                p    = Geometry.LinePar(l1.StartPoint, l1.EndPoint, l2.EndPoint);
                                lmin = Math.Max(Math.Min(lmin, p), 0);
                                lmax = Math.Min(Math.Max(lmax, p), 1);
                                GeoPoint p1 = Geometry.LinePos(l1.StartPoint, l1.EndPoint, (lmin + lmax) / 2.0);
                                GeoPoint p2 = Geometry.DropPL(p1, l2.StartPoint, l2.EndPoint);
                                if ((p1 | p2) > Precision.eps)
                                {
                                    MenuWithHandler mh            = new MenuWithHandler("MenuId.EdgeDistance");
                                    Line            feedback      = Line.TwoPoints(p1, p2);
                                    GeoObjectList   feedbackArrow = currentView.Projection.MakeArrow(p1, p2, pls.Plane, Projection.ArrowMode.circleArrow);
                                    mh.OnCommand = (menuId) =>
                                    {
                                        ParametricsDistanceActionOld pd = new ParametricsDistanceActionOld(o1, o2, feedback, pls.Plane, soa.Frame);
                                        soa.Frame.SetAction(pd);
                                        return(true);
                                    };
                                    mh.OnSelected = (m, selected) =>
                                    {
                                        currentMenuSelection.Clear();
                                        currentMenuSelection.AddRange(feedbackArrow);
                                        currentMenuSelection.Add(o1.OtherFace(face));
                                        currentMenuSelection.Add(o2.OtherFace(face));
                                        currentView.Invalidate(PaintBuffer.DrawingAspect.Select, currentView.DisplayRectangle);
                                    };
                                    res.Add(mh);
                                }
                            }
                        }
                    }
                }
            }
            if (res.Count > 6)
            {
                List <MenuWithHandler> lm = new List <MenuWithHandler>();
                for (int i = 4; i < res.Count; i++)
                {
                    lm.Add(res[i]);
                }
                res.RemoveRange(4, lm.Count);
                MenuWithHandler subMenu = new MenuWithHandler("MenuId.More");
                subMenu.SubMenus = lm.ToArray();
                res.Add(subMenu);
            }
            return(res);
        }
예제 #19
0
        private bool RoundObject(CurveInput sender, ICurve[] Curves, bool up)
        {   // ... nur die sinnvolen Kurven verwenden
            objectPoint1 = base.CurrentMousePosition;
            objectPoint  = objectPoint1;
            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]);
                }
            }
            //            composedSingle = false;
            composedSplit        = false;
            iCurveComposedSplit  = null;
            pathCreatedFromModel = null;
            if (Curves.Length == 1)
            {   // er hat nur eine Kurve gewählt, also roundObject2 freischalten
                iCurve1               = Curves[0];
                iCurve1Sav            = iCurve1;
                roundObject2.Optional = false;
                roundObject2.ReadOnly = false;
                roundObject.HitCursor = CursorTable.GetCursor("RoundIn.cur");
                base.ActiveObject     = null;
                base.FeedBack.ClearSelected();

                //				composedSplit = false;
                ICurve pathHit = null;
                if (Curves[0].IsComposed) // also: Pfad oder Polyline
                {
                    pathHit             = Curves[0].Clone();
                    iCurveComposedSplit = Curves[0];
                    // merken für OnDone zum löschen und Attributsetzen
                    ToolsRoundOff.pathTestIntersection(pathHit, objectPoint);
                    //                    showRoundPathTestIntersection(pathHit);
                }
                else
                {
                    Path p = CADability.GeoObject.Path.CreateFromModel(Curves[0] as ICurve, Frame.ActiveView.Model, Frame.ActiveView.Projection, true);
                    if (p != null)
                    {
                        pathHit = p as ICurve;
                    }
                    pathCreatedFromModel = p;
                    ownerCreated         = (Curves[0] as IGeoObject).Owner;
                }
                if (pathHit != null)
                {   // jetzt an der Mausposition aufknacken in 2 Pathes
                    ICurve[] tmpCurves = roundObject.SplitAtMousePosition(pathHit);
                    if (tmpCurves.Length == 2)
                    {
                        iCurve1       = tmpCurves[0];
                        iCurve2       = tmpCurves[1];
                        composedSplit = true;
                        if (showRound())
                        {
                            roundObject2.Optional = true;
                            roundObject2.ReadOnly = true;
                            roundObject.HitCursor = CursorTable.GetCursor("RoundInReady.cur");
                        }
                        else
                        {
                            iCurve1               = Curves[0];
                            composedSplit         = false;
                            roundObject2.Optional = false;
                            roundObject2.ReadOnly = false;
                            roundObject.HitCursor = CursorTable.GetCursor("RoundIn.cur");
                        }
                    }
                }
                return(true);
                //				base.SetFocus(roundObject2,true);
            }
            if (Curves.Length >= 2)
            {                            // nachsehen, ob ein realer Schnittpunkt da ist
                double[] cutPlace = CADability.GeoObject.Curves.Intersect(Curves[0], Curves[1], true);
                if (cutPlace.Length > 0) // nur reale Schnittpunkte sollen gelten
                {                        // er hat zwei Kurven gewählt, also roundObject2 ausschalten
                    iCurve1 = Curves[0];
                    iCurve2 = Curves[1];
                    if (showRound())
                    {
                        roundObject2.Optional = true;
                        roundObject2.ReadOnly = true;
                        roundObject.HitCursor = CursorTable.GetCursor("RoundInReady.cur");
                        return(true);
                    }
                    else
                    {
                        roundObject.HitCursor = CursorTable.GetCursor("RoundIn.cur");
                        roundObject2.Optional = false;
                        roundObject2.ReadOnly = false;
                        base.ActiveObject     = null;
                        base.FeedBack.ClearSelected();
                        return(false);
                    }

                    //                    return(showRound());
                }
            }
            roundObject.HitCursor = CursorTable.GetCursor("RoundIn.cur");
            roundObject2.Optional = false;
            roundObject2.ReadOnly = false;
            base.ActiveObject     = null;
            base.FeedBack.ClearSelected();
            return(false);
        }
예제 #20
0
        private bool showRound()
        {       // jetzt werden die Rundparameter bestimmt
            base.ActiveObject = null;
            base.FeedBack.ClearSelected();
            if ((iCurve1 != null) && (iCurve2 != null) && (iCurve1 != iCurve2))
            {
                Plane pl;
                if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl))
                {
                    if (composedSplit)
                    {
                        if (iCurveComposedSplit != null)
                        {
                            owner = (iCurveComposedSplit as IGeoObject).Owner;                              // owner merken für löschen und Einfügen
                        }
                        else
                        {
                            owner = ownerCreated;
                        }
                    }
                    else
                    {
                        owner = (iCurve1 as IGeoObject).Owner;  // owner merken für löschen und Einfügen
                    }
                    //				owner = (iCurve1 as IGeoObject).Owner; // owner merken für löschen und Einfügen
                    bool       rndPos = false; // Runden möglich
                    double     distCP;         // Entfernung Pickpunkt - Schnittpunkte
                    GeoPoint2D arcP1     = new GeoPoint2D(0.0, 0.0);
                    GeoPoint2D arcP2     = new GeoPoint2D(0.0, 0.0);
                    GeoPoint2D arcCenter = new GeoPoint2D(0.0, 0.0);
                    ICurve2D   curve1_2D = iCurve1.GetProjectedCurve(pl); // die 2D-Kurven
                    if (curve1_2D is Path2D)
                    {
                        (curve1_2D as Path2D).Flatten();
                    }
                    ICurve2D curve2_2D = iCurve2.GetProjectedCurve(pl);
                    if (curve2_2D is Path2D)
                    {
                        (curve2_2D as Path2D).Flatten();
                    }
                    // hier die Schnittpunkte bestimmen und den cutPoint auf den nächsten Schnittpunt setzen
                    GeoPoint2DWithParameter cutPoint;
                    rndPos = Curves2D.NearestPoint(curve1_2D.Intersect(curve2_2D), pl.Project(objectPoint), out cutPoint);
                    if (rndPos) // runden war möglich
                    {
                        arcCenter = cutPoint.p;
                        double locmin1, locmin2; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt
                        locmin1 = 0.0;           // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt
                        locmin2 = 0.0;           // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt
                        double locmax1, locmax2; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt
                        locmax1 = 1.0;
                        locmax2 = 1.0;
                        double locPar;                             // für den Fall: virtueller Schnittpunkt die Parametergrenzen anpassen
                        locPar = curve1_2D.PositionOf(cutPoint.p); // position des Schnittpunktes auf der Kurve1
                        //if ( locPar > 0.5) locmax1 = locPar;
                        //else locmin1 = locPar;
                        if (locPar > 1.0)
                        {
                            locmax1 = locPar;
                        }
                        if (locPar < 0.0)
                        {
                            locmin1 = locPar;
                        }
                        locPar = curve2_2D.PositionOf(cutPoint.p); // position des Schnittpunktes auf der Kurve2
                        if (locPar > 1.0)
                        {
                            locmax2 = locPar;
                        }
                        if (locPar < 0.0)
                        {
                            locmin2 = locPar;
                        }
                        //if (locPar > 0.5) locmax2 = locPar;
                        //else locmin2 = locPar;
                        // Kreis synthetisieren
                        arc.SetArcPlaneCenterRadius(pl, pl.ToGlobal(arcCenter), roundRad);
                        ICurve2D curveArc_2D = (arc as ICurve).GetProjectedCurve(pl);

                        // Schnittpunkte Kreisbogen mit Kurve 1
                        GeoPoint2DWithParameter[] cutPoints = curve1_2D.Intersect(curveArc_2D);
                        distCP = double.MaxValue;
                        for (int i = 0; i < cutPoints.Length; ++i) // Schleife über alle Schnittpunkte
                        {                                          // nur der Schnittpunkt innerhalb der Kurve
                            if ((cutPoints[i].par1 > locmin1) & (cutPoints[i].par1 < locmax1))
                            {
                                double distLoc = Geometry.Dist(cutPoints[i].p, pl.Project(objectPoint));
                                if (distLoc < distCP)
                                {
                                    distCP = distLoc;
                                    arcP1  = cutPoints[i].p; // Schnittpunkt schonmal merken
                                }
                                //arcP1 = cutPoints[i].p;
                                //break;
                            }
                        }
                        // Schnittpunkte Kreisbogen mit Kurve 2
                        cutPoints = curve2_2D.Intersect(curveArc_2D);
                        distCP    = double.MaxValue;
                        for (int i = 0; i < cutPoints.Length; ++i) // Schleife über alle Schnittpunkte
                        {                                          // nur der Schnittpunkt innerhalb der Kurve
                            if ((cutPoints[i].par1 > locmin2) & (cutPoints[i].par1 < locmax2))
                            {
                                double distLoc = Geometry.Dist(cutPoints[i].p, pl.Project(objectPoint));
                                if (distLoc < distCP)
                                {
                                    distCP = distLoc;
                                    arcP2  = cutPoints[i].p; // Schnittpunkt schonmal merken
                                }
                                // arcP2 = cutPoints[i].p;
                                // break;
                            }
                        }
                        if (!Precision.IsEqual(arcP1, arcP2)) // runden war möglich
                        {
                            // Mittelwert zwischen dem Kurven
                            //                            roundRadCalc = (Math.Abs(curve1_2D.Distance(pl.Project(radiusPoint))) + Math.Abs(curve2_2D.Distance(pl.Project(radiusPoint)))) / 2.0;
                            //						objectPoint = pl.ToGlobal(cutPoint.p); // merken für onDone, als Entscheidungskriterium
                            arc.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, arcCenter, arcP1, arcP2, pl, false);
                            Ellipse arc1 = Ellipse.Construct();
                            arc1.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, arcCenter, arcP1, arcP2, pl, true);
                            if (Math.Abs(arc.SweepParameter) > Math.Abs(arc1.SweepParameter)) // es ist immer der kleinere Bogen!
                            {
                                arc = arc1;
                            }
                            arc.CopyAttributes(iCurve1 as IGeoObject);
                            base.ActiveObject = arc;        // merken
                            base.FeedBack.AddSelected(arc); // darstellen
                            return(true);
                        }
                    }
                }
            }
            //            roundObject.HitCursor = CursorTable.GetCursor("RoundIn.cur");
            return(false);
        }
예제 #21
0
        private bool showCutOffOrg()
        {
            base.ActiveObject = null;
            base.FeedBack.ClearSelected();
            if (iCurveSel == null)
            {
                return(false);
            }
            iCurveOrg            = iCurveSel;                       // zum Weglöschen des Originals in onDone
            owner                = (iCurveSel as IGeoObject).Owner; // owner merken für löschen und Einfügen
            pathCreatedFromModel = CADability.GeoObject.Path.CreateFromModel(iCurveSel, Frame.ActiveView.Model, Frame.ActiveView.Projection, true);
            if (pathCreatedFromModel != null)
            {
                iCurveOrg = null;                             // zum nicht Weglöschen des Originals in onDone
                Path pa = (Path)pathCreatedFromModel.Clone(); // Kopie, da Flatten evtl. interne Pfade zerhaut
                // der Pfad wird gleich wieder aufgelöst, damit man die Einzelteile manipulieren kann
                ICurve[] paCurves   = pa.Curves;
                bool     paIsClosed = pa.IsClosed;
                pa.Clear();
                bool cutOff = false;     // zum Merken, ob mindestens 1 mal gefast wurde
                if (paCurves.Length > 1) // nur dann machts Sinn
                {
                    blk = Block.Construct();
                    base.FeedBack.ClearSelected();
                    base.FeedBack.AddSelected(blk as IGeoObject);
                    iCurve1 = paCurves[0];// 1. Linie vorbesetzen
                    (iCurve1 as IGeoObject).CopyAttributes(paCurves[0] as IGeoObject);
                    for (int i = 0; i < paCurves.Length - 1; ++i)
                    {
                        iCurve2 = paCurves[i + 1];
                        (iCurve2 as IGeoObject).CopyAttributes(paCurves[i + 1] as IGeoObject);
                        if (showCutOff())
                        {
                            cutOff = true;               // hat er mindestens 1 mal gerundet?
                        }
                    }
                    if (paIsClosed)
                    {
                        iCurve2 = blk.Item(0) as ICurve;
                        (iCurve2 as IGeoObject).CopyAttributes(blk.Item(0) as IGeoObject);
                        if (showCutOff())
                        {
                            cutOff = true; // hat er mindestens 1 mal gerundet?
                                           //                            base.FeedBack.RemoveSelected(0);
                            blk.Remove(0);
                        }
                    }
                    if (cutOff)
                    {
                        blk.Add(iCurve1 as IGeoObject); // letzte Linie einfügen
                                                        //                        base.FeedBack.AddSelected(iCurve1 as IGeoObject);// darstellen
                        base.ActiveObject = blk;        // merken
                        return(true);
                    }
                }
            }
            else
            { // also: Einzelelement, jetzt die sinnvollen abarbeiten!
                if (iCurveSel is Polyline)
                {
                    bool     cutOff = false; // zum Merken, ob mindestens 1 mal gefast wurde
                    Polyline p      = iCurveSel as Polyline;
                    if (p.PointCount > 2)    // nur dann machts Sinn
                    {
                        blk = Block.Construct();
                        base.FeedBack.ClearSelected();
                        base.FeedBack.AddSelected(blk as IGeoObject);
                        Line line = Line.Construct();
                        line.StartPoint = p.GetPoint(0);
                        line.EndPoint   = p.GetPoint(1);
                        iCurve1         = line; // 1. Linie vorbesetzen
                        (iCurve1 as IGeoObject).CopyAttributes(iCurveSel as IGeoObject);
                        for (int i = 0; i < p.PointCount - 2; ++i)
                        {
                            Line line2 = Line.Construct();
                            line2.StartPoint = p.GetPoint(i + 1);
                            line2.EndPoint   = p.GetPoint(i + 2);
                            iCurve2          = line2;
                            (iCurve2 as IGeoObject).CopyAttributes(iCurveSel as IGeoObject);
                            if (showCutOff())
                            {
                                cutOff = true;               // hat er mindestens 1 mal gerundet?
                            }
                        }
                        if (p.IsClosed)
                        {
                            Line line2 = Line.Construct();
                            line2.StartPoint = p.GetPoint(p.PointCount - 1);
                            line2.EndPoint   = p.GetPoint(0);
                            iCurve2          = line2;
                            (iCurve2 as IGeoObject).CopyAttributes(iCurveSel as IGeoObject);
                            if (showCutOff())
                            {
                                cutOff = true;               // hat er mindestens 1 mal gerundet?
                            }
                            iCurve2 = blk.Item(0) as ICurve;
                            (iCurve2 as IGeoObject).CopyAttributes(iCurveSel as IGeoObject);
                            if (showCutOff())
                            {
                                cutOff = true;               // hat er mindestens 1 mal gerundet?
                            }
                        }
                        if (cutOff)
                        {
                            blk.Add(iCurve1 as IGeoObject); // letzte Linie einfügen
                                                            //                            base.FeedBack.AddSelected(iCurve1 as IGeoObject);// darstellen
                            base.ActiveObject = blk;        // merken
                            return(true);
                        }
                    }
                }

                if (iCurveSel is Path)
                {
                    bool cutOff = false; // zum Merken, ob mindestens 1 mal gefast wurde
                    Path p      = iCurveSel as Path;
                    if (p.Count > 2)     // nur dann machts Sinn
                    {
                        blk = Block.Construct();
                        base.FeedBack.ClearSelected();
                        base.FeedBack.AddSelected(blk as IGeoObject);
                        iCurve1 = p.Curve(0).Clone();// 1. Linie vorbesetzen
                        (iCurve1 as IGeoObject).CopyAttributes(iCurveSel as IGeoObject);
                        for (int i = 0; i < p.Count - 1; ++i)
                        {
                            iCurve2 = p.Curve(i + 1).Clone();
                            (iCurve2 as IGeoObject).CopyAttributes(iCurveSel as IGeoObject);
                            if (showCutOff())
                            {
                                cutOff = true;               // hat er mindestens 1 mal gerundet?
                            }
                        }
                        if (p.IsClosed)
                        {
                            iCurve2 = blk.Item(0) as ICurve;
                            (iCurve2 as IGeoObject).CopyAttributes(iCurveSel as IGeoObject);
                            if (showCutOff())
                            {
                                cutOff = true; // hat er mindestens 1 mal gerundet?
                                               //                                base.FeedBack.RemoveSelected(0);
                                blk.Remove(0);
                            }
                        }
                        if (cutOff)
                        {
                            blk.Add(iCurve1 as IGeoObject); // letzte Linie einfügen
                                                            //                            base.FeedBack.AddSelected(iCurve1 as IGeoObject);// darstellen
                            base.ActiveObject = blk;        // merken
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
예제 #22
0
        public override void OnDone()
        {   // zerstückeln, original entfernen und Stücke einfügen
            // TODO: noch auf 0.0 aufpassen!
            // TODO: Polyline geht nicht richtig, Ellipse auch nicht, da nicht linear auf dem Umfang
            IGeoObject go = theCurve as IGeoObject;

            if (go != null)
            {
                IGeoObjectOwner owner = go.Owner;
                if (owner != null)
                {
                    using (Frame.Project.Undo.UndoFrame)
                    {
                        //if (go is Polyline)
                        //{
                        //    (go as Polyline).IsClosed = false; // aufbrechen
                        //}
                        // nicht aufbrechen, das ist jetzt in Split ordentlich geregelt
                        owner.Remove(go);
                        ICurve toSplit = theCurve;
                        double totlen  = theCurve.Length;
                        double sumlen  = 0.0;
                        for (int i = 0; i < number; ++i)
                        {
                            ICurve splitted = toSplit.Clone();
                            double start    = theCurve.PositionAtLength(sumlen);
                            sumlen += sections[i] * totlen;
                            double end = theCurve.PositionAtLength(sumlen);
                            splitted.Trim(start, end);
                            (splitted as IGeoObject).CopyAttributes(go);
                            owner.Add(splitted as IGeoObject);
                        }

                        //double[] Positions = new double[number];
                        //for (int i = 0; i < number; ++i)
                        //{
                        //    double sum = 0.0;
                        //    for (int j = i; j < number; ++j)
                        //    {
                        //        sum += sections[j];
                        //    }
                        //    Positions[i] = sections[i] / sum;
                        //}
                        //for (int i = 0; i < number-1; ++i)
                        //{
                        //    ICurve[] splitted = toSplit.Split(Positions[i]);
                        //    if (splitted.Length == 2)
                        //    {
                        //        IGeoObject toAdd = splitted[0] as IGeoObject;
                        //        toAdd.CopyAttributes(go);
                        //        owner.Add(toAdd);
                        //        toSplit = splitted[1];
                        //    }
                        //}
                        //(toSplit as IGeoObject).CopyAttributes(go);
                        //owner.Add(toSplit as IGeoObject);
                    }
                }
            }
            base.OnDone();
        }
예제 #23
0
        private bool showCutOff()
        {       // nur wenn beide Kurven gültig sind
            base.ActiveObject = null;
            base.FeedBack.ClearSelected();
            if ((iCurve1 != null) && (iCurve2 != null) && (iCurve1 != iCurve2))
            {
                Plane pl; // nur bei gemeisamer Ebene
                if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl))
                {
                    if (composedSplit)
                    {
                        if (iCurveComposedSplit != null)
                        {
                            owner = (iCurveComposedSplit as IGeoObject).Owner;                              // owner merken für löschen und Einfügen
                        }
                        else
                        {
                            owner = ownerCreated;
                        }
                    }
                    //                        owner = (iCurveComposedSplit as IGeoObject).Owner; // owner merken für löschen und Einfügen
                    else
                    {
                        owner = (iCurve1 as IGeoObject).Owner;          // owner merken für löschen und Einfügen
                    }
                    pl.Align(base.ActiveDrawingPlane, false);           // Winkel anpassen
                    ICurve2D curve1_2D = iCurve1.GetProjectedCurve(pl); // die 2D-Kurven
                    if (curve1_2D is Path2D)
                    {
                        (curve1_2D as Path2D).Flatten();
                    }
                    ICurve2D curve2_2D = iCurve2.GetProjectedCurve(pl);
                    if (curve2_2D is Path2D)
                    {
                        (curve2_2D as Path2D).Flatten();
                    }
                    ICurve newCurve = iCurve1.Clone();                                                                // neue Kurve bis zum Schnittpunkt
                                                                                                                      // hier die Schnittpunkte bestimmen und den cutPoint auf den nächsten Schnittpunt setzen
                    GeoPoint2DWithParameter cutPoint;
                    if (Curves2D.NearestPoint(curve1_2D.Intersect(curve2_2D), pl.Project(objectPoint), out cutPoint)) // fasen war möglich
                    {
                        GeoVector2D v1 = curve1_2D.DirectionAt(cutPoint.par1);                                        // die Richtung im Schnittpunkt
                        if (cutPoint.par1 > 0.5)
                        {
                            v1 = v1.Opposite();                      // evtl rumdrehen, falls am Ende
                        }
                        v1.Norm();
                        GeoVector2D v2 = curve2_2D.DirectionAt(cutPoint.par2); // die Richtung im Schnittpunkt
                        if (cutPoint.par2 > 0.5)
                        {
                            v2 = v2.Opposite();                      // evtl rumdrehen, falls am Ende
                        }
                        v2.Norm();
                        GeoVector2D v = (v1 + v2); // Winkelhalbierende
                        if (Precision.IsNullVector(pl.ToGlobal(v)))
                        {
                            return(false);
                        }
                        v.Norm();
                        v = cutOffLen * v;                                      // Winkelhalbierende mit Fas-Abstand
                        GeoPoint2D dirPoint = cutPoint.p + v;                   // wird unten auch als Auswahlpunkt für die Richtung genutzt
                        Line2D     line2D   = new Line2D(dirPoint, cutPoint.p); // Linie vorbesetzen, Punkte eigentlich egal
                        if ((methodSelect == 0) || (methodSelect == 1))
                        {                                                       // 0: Länge cutOffLen = Seitenlänge Kurve1   1: Länge cutOffLen = Fasenlänge
                            double sideLength;
                            if (methodSelect == 1)                              // Länge cutOffLen = Fasenlänge
                                                                                // Geometrie, Pythagoras, bekannt Seite=cutOffLen, Winkel 1 = cutOffAng, Winkel 2 = Winkel der Kurven im Schnittpunkt
                            {
                                sideLength = cutOffLen * (Math.Cos(cutOffAng.Radian) + (Math.Sin(cutOffAng.Radian) / Math.Tan(Math.Abs(new SweepAngle(v1, v2).Radian))));
                            }
                            else
                            {
                                sideLength = cutOffLen;
                            }
                            // neue Kurve bis zum Schnittpunkt synthetisieren, dazu: Schnittpunkt finden des Abschnitts mit der iCurve1

                            Ellipse arcTmp = Ellipse.Construct();
                            arcTmp.SetCirclePlaneCenterRadius(pl, pl.ToGlobal(cutPoint.p), sideLength);
                            ICurve2D curveArc_2D = (arcTmp as ICurve).GetProjectedCurve(pl); // die 2D-Kurve
                            GeoPoint2DWithParameter cutArc;
                            GeoPoint2D startPoint;
                            if (Curves2D.NearestPoint(curve1_2D.Intersect(curveArc_2D), dirPoint, out cutArc)) // war möglich
                            {
                                startPoint = cutArc.p;
                            }
                            else
                            {
                                return(false);
                            }

                            /*
                             *                          double parCut;
                             *
                             *                          // neue Kurve bis zum Schnittpunkt synthetisieren:
                             *                          if (cutPoint.par1 <= 0.5)
                             *                          {
                             *                              newCurve.Trim(cutPoint.par1,1.0);
                             *                              parCut = (sideLength)/newCurve.Length; // der Parameter des Fasenpunktes
                             *                          }
                             *                          else
                             *                          {
                             *                              newCurve.Trim(0.0,cutPoint.par1);
                             *                              parCut = (newCurve.Length-sideLength)/newCurve.Length; // der Parameter des Fasenpunktes
                             *                          }
                             *                          GeoPoint2D startPoint = pl.Project(newCurve.PointAt(parCut));
                             *                          GeoVector2D vc = curve1_2D.DirectionAt(parCut); // die Richtung im Schnittpunkt
                             */
                            GeoVector2D vc = curve1_2D.DirectionAt(curve1_2D.PositionOf(startPoint)); // die Richtung im Schnittpunkt
                            if (cutPoint.par1 <= 0.5)
                            {
                                vc = vc.Opposite();                            // evtl rumdrehen, falls am Ende
                            }
                            if (Geometry.OnLeftSide(dirPoint, startPoint, vc)) // Richtung festlegen für Winkeloffset
                            {
                                vc.Angle = vc.Angle + new SweepAngle(cutOffAng);
                            }
                            else
                            {
                                vc.Angle = vc.Angle - new SweepAngle(cutOffAng);
                            }
                            // Hilfslinie im Fasabstand, im Offsetwinkel
                            line2D = new Line2D(startPoint, startPoint + vc);
                        }
                        if (methodSelect == 2)                             // Länge cutOffLen = Winkelhalbierendenlänge
                        {
                            v.Angle = v.Angle + new SweepAngle(cutOffAng); // Winkelhalbierendenwinkel + Offset
                                                                           // Hilfslinie im Fasabstand, senkrecht auf der Winkelhalbierenden v
                            line2D = new Line2D(dirPoint, dirPoint + v.ToLeft());
                        }

                        GeoPoint2DWithParameter cutPoint1;
                        GeoPoint2DWithParameter cutPoint2;
                        // schnittpunkte der Hilfslinie mit den beiden Kurven
                        if (Curves2D.NearestPoint(curve1_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint1))
                        {
                            if (Curves2D.NearestPoint(curve2_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint2))
                            {   // da isse, die Fas-Linie, nur, wenn die Punkte echt auf der Kurve bis zum Schnittpunkt  liegen:
                                bool onCurve1, onCurve2;
                                // Berechnung, ob die Kurven realen Schnittpunkt haben
                                //								if ((cutPoint.par1 <= 1.0001) & (cutPoint.par1 >= -0.0001) & (cutPoint.par2 <= 1.0001) & (cutPoint.par2 >= -0.0001))
                                if (curve1_2D.IsParameterOnCurve(cutPoint.par1) & curve2_2D.IsParameterOnCurve(cutPoint.par2))
                                {
                                    onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 1.0);
                                    onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 1.0);
                                }
                                else
                                {
                                    if (cutPoint.par1 > 0.5)
                                    {
                                        onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 100);
                                    }
                                    // im Quasi-Parallelfall stehen in par1 riesige Werte
                                    else
                                    {
                                        onCurve1 = (cutPoint1.par1 < 1.0) & (cutPoint1.par1 > -100);
                                    }
                                    if (cutPoint.par2 > 0.5)
                                    {
                                        onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 100);
                                    }
                                    else
                                    {
                                        onCurve2 = (cutPoint2.par1 < 1.0) & (cutPoint2.par1 > -100);
                                    }
                                }
                                if (onCurve1 && onCurve2)
                                {
                                    line.SetTwoPoints(pl.ToGlobal(cutPoint1.p), pl.ToGlobal(cutPoint2.p));
                                    // Fasenlänge vorgegeben, aber mit obiger Berechnung falsch, da dort Linien vorausgesetzt werden
                                    if ((methodSelect == 1) && (Math.Abs(line.Length - cutOffLen) > Precision.eps))
                                    {   // jetzt mit Iteration annähern
                                        double parInd      = 0.5;
                                        double parIndDelta = 0.25;
                                        for (int i = 0; i < 49; ++i) // 48 Schritte müssen reichen, par kann zwischen 0 und 1 liegen
                                        {
                                            GeoPoint2D  startPoint = pl.Project(newCurve.PointAt(parInd));
                                            GeoVector2D vc         = curve1_2D.DirectionAt(parInd); // die Richtung im Schnittpunkt
                                            if (cutPoint.par1 <= 0.5)
                                            {
                                                vc = vc.Opposite();                            // evtl rumdrehen, falls am Ende
                                            }
                                            if (Geometry.OnLeftSide(dirPoint, startPoint, vc)) // Richtung festlegen für Winkeloffset
                                            {
                                                vc.Angle = vc.Angle + new SweepAngle(cutOffAng);
                                            }
                                            else
                                            {
                                                vc.Angle = vc.Angle - new SweepAngle(cutOffAng);
                                            }
                                            // Hilfslinie im Fasabstand, im Offsetwinkel
                                            line2D = new Line2D(startPoint, startPoint + vc);
                                            if (Curves2D.NearestPoint(curve1_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint1))
                                            {
                                                if (Curves2D.NearestPoint(curve2_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint2))
                                                {   // da isse, die Fas-Linie, nur, wenn die Punkte echt auf der Kurvr liegen:
                                                    if (cutPoint.par1 > 0.5)
                                                    {
                                                        onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 100);
                                                    }
                                                    // im Quasi-Parallelfall stehen in par1 riesige Werte
                                                    else
                                                    {
                                                        onCurve1 = (cutPoint1.par1 < 1.0) & (cutPoint1.par1 > -100);
                                                    }
                                                    if (cutPoint.par2 > 0.5)
                                                    {
                                                        onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 100);
                                                    }
                                                    else
                                                    {
                                                        onCurve2 = (cutPoint2.par1 < 1.0) & (cutPoint2.par1 > -100);
                                                    }
                                                    if (onCurve1 && onCurve2)
                                                    {
                                                        line.SetTwoPoints(pl.ToGlobal(cutPoint1.p), pl.ToGlobal(cutPoint2.p));
                                                        if ((Math.Abs(line.Length - cutOffLen) < Precision.eps)) // gefunden und raus
                                                        {
                                                            break;
                                                        }
                                                        else
                                                        {
                                                            if (line.Length < cutOffLen)
                                                            {                                    // Fase ist zu klein: Parameter parInd vergrößern
                                                                parInd      = parInd + parIndDelta;
                                                                parIndDelta = parIndDelta / 2.0; // delta halbieren (Bisection!!)
                                                                continue;                        // nächster Schritt in der For-Schleife
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            // alle anderen Fälle: // Fase ist zu gross: Parameter parInd verkleinern
                                            parInd      = parInd - parIndDelta;
                                            parIndDelta = parIndDelta / 2.0; // delta halbieren (Bisection!!)
                                        } // for schleife Iteration
                                    } // Ende Iteration
                                    line.CopyAttributes(iCurve1 as IGeoObject);
                                    base.ActiveObject = line;        // merken
                                    base.FeedBack.AddSelected(line); // darstellen
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }