/// <summary> /// Called by Rhino when the user wants to run the command. /// </summary> protected override Result RunCommand(RhinoDoc doc, RunMode mode) { var log_type = RockfishServerPlugIn.LogType(); var go = new GetOption(); go.SetCommandPrompt("Configuration options"); go.AddOptionEnumList("Logging", log_type); while (true) { var res = go.Get(); if (res == GetResult.Option) { var option = go.Option(); if (null != option) { var list = Enum.GetValues(typeof(RockfishLog.LogType)).Cast <RockfishLog.LogType>().ToList(); log_type = list[option.CurrentListOptionIndex]; } continue; } break; } RockfishServerPlugIn.SetLogType(log_type); return(Result.Success); }
/// <summary> /// RunCommand /// </summary> protected override Result RunCommand(RhinoDoc doc, RunMode mode) { Tolerance = doc.ModelAbsoluteTolerance; // Get persistent settings var settings = Settings; var radius = settings.GetDouble("Radius", RADIUS); var cut_type = settings.GetEnumValue("CutType", CUTTYPE); // Select closed,planar curve var go = new GetClosedPlanarPolyline(Tolerance); go.SetCommandPrompt("Select closed, planar polyline"); go.Get(); if (go.CommandResult() != Result.Success) { return(go.CommandResult()); } // Get curve var obj_ref = go.Object(0); var curve = obj_ref.Curve(); if (null == curve || !curve.IsClosed || !curve.IsPlanar()) { return(Result.Failure); } // Get polyline Polyline polyline; if (!curve.TryGetPolyline(out polyline)) { return(Result.Failure); } // Since first and last point are the same, remove the last point. polyline.RemoveAt(polyline.Count - 1); // Get curve plane Plane plane; if (!curve.TryGetPlane(out plane, Tolerance)) { return(Result.Failure); } // Get corner point indices var indices = FindInnerCornerPoints(curve, polyline, plane); if (0 == indices.Length) { RhinoApp.WriteLine("No inner corners found."); return(Result.Nothing); } // Show preview conduit var conduit = new SampleCsOverCutConduit { Circles = CalculateCuttingCircles(curve, polyline, indices, plane, radius, cut_type), Enabled = true }; doc.Views.Redraw(); Result rc; // Choose overcut options var gp = new GetOption(); gp.SetCommandPrompt("Choose overcut option"); gp.AcceptNothing(true); for (;;) { gp.ClearCommandOptions(); var cut_type_index = gp.AddOptionEnumList("CutType", cut_type); var radius_option = new OptionDouble(radius, true, Tolerance); var radius_index = gp.AddOptionDouble("Radius", ref radius_option); var res = gp.Get(); if (res == GetResult.Option) { var option = gp.Option(); if (null != option) { if (option.Index == cut_type_index) { var list = Enum.GetValues(typeof(CutType)).Cast <CutType>().ToList(); cut_type = list[option.CurrentListOptionIndex]; } else if (option.Index == radius_index) { radius = radius_option.CurrentValue; } conduit.Circles = CalculateCuttingCircles(curve, polyline, indices, plane, radius, cut_type); doc.Views.Redraw(); } continue; } if (res == GetResult.Nothing) { rc = Result.Success; break; } rc = Result.Cancel; break; } conduit.Enabled = false; if (rc == Result.Success) { // Try differencing circles from curve var success = true; var new_curve = curve; for (var i = 0; i < conduit.Circles.Count && success; i++) { var new_curves = Curve.CreateBooleanDifference(new_curve, new ArcCurve(conduit.Circles[i]), doc.ModelAbsoluteTolerance); if (1 == new_curves.Length && null != new_curves[0]) { new_curve = new_curves[0]; } else { success = false; } } // Add geometry to document if (success && null != new_curve) { doc.Objects.Replace(obj_ref, new_curve); } else { for (var i = 0; i < conduit.Circles.Count; i++) { doc.Objects.AddCircle(conduit.Circles[i]); } } // Set persistent settings settings.SetDouble("Radius", radius); settings.SetEnumValue("CutType", cut_type); } doc.Views.Redraw(); return(rc); }
/// <summary> /// Command.RunCommand override /// </summary> protected override Result RunCommand(RhinoDoc doc, RunMode mode) { Potrace.Clear(); // Prompt the user for the name of the image file to vectorize. string path = GetImageFileName(mode); if (string.IsNullOrEmpty(path)) { return(Result.Cancel); } // Creates a bitmap from the specified file. var bitmap = Image.FromFile(path) as Bitmap; if (null == bitmap) { RhinoApp.WriteLine("The specified file cannot be identifed as a supported type."); return(Result.Failure); } // Verify bitmap size if (0 == bitmap.Width || 0 == bitmap.Height) { RhinoApp.WriteLine("Error reading the specified file."); return(Result.Failure); } // Calculate scale factor so curves of a reasonable size are added to Rhino var unit_scale = (doc.ModelUnitSystem != UnitSystem.Inches) ? RhinoMath.UnitScale(UnitSystem.Inches, doc.ModelUnitSystem) : 1.0; var scale = (double)(1.0 / bitmap.HorizontalResolution * unit_scale); // I'm not convinced this is useful... if (true) { var format = $"F{doc.DistanceDisplayPrecision}"; // Print image size in pixels RhinoApp.WriteLine("Image size in pixels: {0} x {1}", bitmap.Width, bitmap.Height ); // Print image size in inches var width = (double)(bitmap.Width / bitmap.HorizontalResolution); var height = (double)(bitmap.Height / bitmap.VerticalResolution); RhinoApp.WriteLine("Image size in inches: {0} x {1}", width.ToString(format, CultureInfo.InvariantCulture), height.ToString(format, CultureInfo.InvariantCulture) ); // Image size in in model units, if needed if (doc.ModelUnitSystem != UnitSystem.Inches) { width = (double)(bitmap.Width / bitmap.HorizontalResolution * unit_scale); height = (double)(bitmap.Height / bitmap.VerticalResolution * unit_scale); RhinoApp.WriteLine("Image size in {0}: {1} x {2}", doc.ModelUnitSystem.ToString().ToLower(), width.ToString(format, CultureInfo.InvariantCulture), height.ToString(format, CultureInfo.InvariantCulture) ); } } // Convert the bitmap to an Eto bitmap var eto_bitmap = ConvertBitmapToEto(bitmap); if (null == eto_bitmap) { RhinoApp.WriteLine("Unable to convert image to Eto bitmap."); return(Result.Failure); } // 12-Jan-2021 Dale Fugier // This should prevent Eto.Drawing.BitmapData.GetPixels() from throwing an exception if (!IsCompatibleBitmap(eto_bitmap)) { RhinoApp.WriteLine("The image has an incompatible pixel format. Please select an image with 24 or 32 bits per pixel, or 8 bit indexed."); return(Result.Failure); } // This bitmap is not needed anymore, so dispose of it bitmap.Dispose(); // Gets the Potrace settings from the plug-in settings file GetPotraceSettings(); // Create the conduit, which does most of the work var conduit = new VectorizeConduit( eto_bitmap, scale, doc.ModelAbsoluteTolerance, m_select_output ? Rhino.ApplicationSettings.AppearanceSettings.SelectedObjectColor : doc.Layers.CurrentLayer.Color ) { Enabled = true }; if (mode == RunMode.Interactive) { // Show the interactive dialog box var dialog = new VectorizeDialog(doc, conduit); dialog.RestorePosition(); var result = dialog.ShowSemiModal(doc, RhinoEtoApp.MainWindow); dialog.SavePosition(); if (result != Result.Success) { conduit.Enabled = false; Potrace.Clear(); doc.Views.Redraw(); return(Result.Cancel); } } else { // Show the command line options var go = new GetOption(); go.SetCommandPrompt("Vectorization options. Press Enter when done"); go.AcceptNothing(true); while (true) { conduit.TraceBitmap(); doc.Views.Redraw(); go.ClearCommandOptions(); // IgnoreArea var turdsize_opt = new OptionInteger(Potrace.turdsize, 2, 100); var turdsize_idx = go.AddOptionInteger("FilterSize", ref turdsize_opt, "Filter speckles of up to this size in pixels"); // TurnPolicy var turnpolicy_idx = go.AddOptionEnumList("TurnPolicy", Potrace.turnpolicy); // Optimizing var curveoptimizing_opt = new OptionToggle(Potrace.curveoptimizing, "No", "Yes"); var curveoptimizing_idx = go.AddOptionToggle("Optimizing", ref curveoptimizing_opt); // Tolerance var opttolerance_opt = new OptionDouble(Potrace.opttolerance, 0.0, 1.0); var opttolerance_idx = go.AddOptionDouble("Tolerance", ref opttolerance_opt, "Optimizing tolerance"); // CornerThreshold var alphamax_opt = new OptionDouble(Potrace.alphamax, 0.0, 100.0); var alphamax_idx = go.AddOptionDouble("CornerRounding", ref alphamax_opt, "Corner rounding threshold"); // Threshold var threshold_opt = new OptionDouble(Potrace.Treshold, 0.0, 100.0); var threshold_idx = go.AddOptionDouble("Threshold", ref threshold_opt, "Threshold"); // RestoreDefaults var defaults_idx = go.AddOption("RestoreDefaults"); var res = go.Get(); if (res == GetResult.Option) { var option = go.Option(); if (null != option) { if (turdsize_idx == option.Index) { Potrace.turdsize = turdsize_opt.CurrentValue; } if (turnpolicy_idx == option.Index) { var list = Enum.GetValues(typeof(TurnPolicy)).Cast <TurnPolicy>().ToList(); Potrace.turnpolicy = list[option.CurrentListOptionIndex]; } if (curveoptimizing_idx == option.Index) { Potrace.curveoptimizing = curveoptimizing_opt.CurrentValue; } if (opttolerance_idx == option.Index) { Potrace.opttolerance = opttolerance_opt.CurrentValue; } if (alphamax_idx == option.Index) { Potrace.alphamax = alphamax_opt.CurrentValue; } if (threshold_idx == option.Index) { Potrace.Treshold = threshold_opt.CurrentValue; } if (defaults_idx == option.Index) { Potrace.RestoreDefaults(); } } continue; } if (res != GetResult.Nothing) { conduit.Enabled = false; doc.Views.Redraw(); Potrace.Clear(); return(Result.Cancel); } break; } } // Group curves var attributes = doc.CreateDefaultAttributes(); attributes.AddToGroup(doc.Groups.Add()); for (var i = 0; i < conduit.OutlineCurves.Count; i++) { var rhobj_id = doc.Objects.AddCurve(conduit.OutlineCurves[i], attributes); if (m_select_output) { var rhobj = doc.Objects.Find(rhobj_id); if (null != rhobj) { rhobj.Select(true); } } } conduit.Enabled = false; Potrace.Clear(); doc.Views.Redraw(); // Set the Potrace settings to the plug -in settings file. SetPotraceSettings(); return(Result.Success); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { var go = new GetObject(); go.SetCommandPrompt("Select curves"); go.GeometryFilter = ObjectType.Curve; go.Get(); if (go.CommandResult() != Result.Success) { return(go.CommandResult()); } var curve = go.Object(0).Curve(); if (null == curve) { return(Result.Failure); } var continuity = Continuity.G1_continuous; var gd = new GetOption(); gd.SetCommandPrompt("Discontinuity to search"); gd.AddOptionEnumList("Discontinuity", continuity); gd.AcceptNothing(true); var res = gd.Get(); if (res == GetResult.Option) { var option = gd.Option(); if (null == option) { return(Result.Failure); } var list = Enum.GetValues(typeof(Continuity)).Cast <Continuity>().ToList(); continuity = list[option.CurrentListOptionIndex]; } else if (res != GetResult.Nothing) { return(Result.Cancel); } var t0 = curve.Domain.Min; var t1 = curve.Domain.Max; for (; ;) { double t; var rc = curve.GetNextDiscontinuity(continuity, t0, t1, out t); if (rc) { doc.Objects.AddPoint(curve.PointAt(t)); t0 = t; } else { break; } } doc.Views.Redraw(); return(Result.Success); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { var go = new GetObject(); go.SetCommandPrompt("Select curves"); go.GeometryFilter = ObjectType.Curve; go.Get(); if (go.CommandResult() != Result.Success) { return(go.CommandResult()); } var curve = go.Object(0).Curve(); if (null == curve) { return(Result.Failure); } var continuity = Continuity.G1_continuous; var gd = new GetOption(); gd.SetCommandPrompt("Discontinuity to search"); gd.AddOptionEnumList("Discontinuity", continuity); gd.AcceptNothing(true); var res = gd.Get(); if (res == GetResult.Option) { var option = gd.Option(); if (null == option) { return(Result.Failure); } var list = Enum.GetValues(typeof(Continuity)).Cast <Continuity>().ToList(); continuity = list[option.CurrentListOptionIndex]; } else if (res != GetResult.Nothing) { return(Result.Cancel); } var t0 = curve.Domain.Min; var t1 = curve.Domain.Max; var parameters = new List <double>(); parameters.Add(t0); for (; ;) { double t; var rc = curve.GetNextDiscontinuity(continuity, t0, t1, out t); if (rc) { parameters.Add(t); t0 = t; } else { break; } } parameters.Add(t1); if (parameters.Count > 2) { for (var i = 0; i < parameters.Count - 1; i++) { t0 = parameters[i]; t1 = parameters[i + 1]; var dom = new Interval(t0, t1); var new_curve = curve.Trim(dom); if (null != new_curve) { doc.Objects.AddCurve(new_curve); } } doc.Objects.Delete(go.Object(0), false); } return(Result.Success); }