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(); }
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(); }
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); }
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 } } } }
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(); }
/// <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); }
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); }
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); }
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(); }
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(); } } }
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(); } } }
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)); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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(); }
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); }