static double InHostUnits(double value, DB.ParameterType type, RhinoDoc rhinoDoc) { if (rhinoDoc is null) { return(double.NaN); } switch (type) { case DB.ParameterType.Length: return(value * RhinoMath.UnitScale(rhinoDoc.ModelUnitSystem, UnitSystem.Feet)); //value *= Math.Pow(RhinoMath.UnitScale(rhinoDoc.ModelUnitSystem, UnitSystem.Millimeters), 1.0); //return DB.UnitUtils.ConvertToInternalUnits(value, DB.DisplayUnitType.DUT_MILLIMETERS); case DB.ParameterType.Area: return(value * Math.Pow(RhinoMath.UnitScale(rhinoDoc.ModelUnitSystem, UnitSystem.Feet), 1.0)); //value *= Math.Pow(RhinoMath.UnitScale(rhinoDoc.ModelUnitSystem, UnitSystem.Millimeters), 2.0); //return DB.UnitUtils.ConvertToInternalUnits(value, DB.DisplayUnitType.DUT_SQUARE_MILLIMETERS); case DB.ParameterType.Volume: return(value * Math.Pow(RhinoMath.UnitScale(rhinoDoc.ModelUnitSystem, UnitSystem.Feet), 1.0)); //value *= Math.Pow(RhinoMath.UnitScale(rhinoDoc.ModelUnitSystem, UnitSystem.Millimeters), 3.0); //return DB.UnitUtils.ConvertToInternalUnits(value, DB.DisplayUnitType.DUT_CUBIC_MILLIMETERS); default: Debug.WriteLine(false, $"{nameof(InHostUnits)} do not implement conversion for {type}"); break; } return(value); }
public static Dictionary <OSMTag, List <PolylineCurve> > WayPolylinesFromCoords(RequestHandler result) { var geometryResult = new Dictionary <OSMTag, List <PolylineCurve> >(); var unitScale = RhinoMath.UnitScale(UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem); // OSM conversion assumes meters Coord lengthPerDegree = GetDegreesPerAxis(result.MinBounds, result.MaxBounds, unitScale); foreach (var entry in result.FoundData) { geometryResult[entry.Key] = new List <PolylineCurve>(); foreach (FoundItem item in entry.Value) { var linePoints = new List <Point3d>(); foreach (var coord in item.Coords) { var pt = GetPointFromLatLong(coord, lengthPerDegree, result.MinBounds); linePoints.Add(pt); } var polyLine = new PolylineCurve(linePoints); // Creating a polylinecurve from scratch makes invalid geometry geometryResult[entry.Key].Add(polyLine); } } return(geometryResult); }
static ToUnitSystemStatic() { foreach (var unit in DB.UnitUtils.GetValidDisplayUnits(DB.UnitType.UT_Length)) { var revit = DB.UnitUtils.Convert(1.0, DB.DisplayUnitType.DUT_METERS, unit); var rhino = RhinoMath.UnitScale(UnitSystem.Meters, unit.ToUnitSystem()); //Debug.Assert(Rhino.RhinoMath.EpsilonEquals(revit, rhino, Rhino.RhinoMath.ZeroTolerance), $"ToRhinoLengthUnits({unit}) fails!!"); } }
public double ScaleToFitDocument(double input) { //The input is coming in from 0-300 //This correlates with roughly 20 feet double scaledToFeet = input / 8; UnitSystem currentDocUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits); return(scaledToFeet * unitSystemScaler); }
public static double[] AreaOf(List <Curve> curves) { UnitSystem currentDocUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitSystemScaler = RhinoMath.UnitScale(currentDocUnits, UnitSystem.Feet); double[] areas = new double[curves.Count()]; for (int i = 0; i < curves.Count(); i++) { areas[i] = Math.Round(AreaMassProperties.Compute(curves[i]).Area *unitSystemScaler *unitSystemScaler, 2); } return(areas); }
public static Result Import3DMFile(string filePath, Document doc, BuiltInCategory builtInCategory) { using (var model = File3dm.Read(filePath)) { var scaleFactor = RhinoMath.UnitScale(model.Settings.ModelUnitSystem, Revit.ModelUnitSystem); using (var trans = new Transaction(doc, "Import 3D Model")) { if (trans.Start() == TransactionStatus.Started) { var categoryId = new ElementId(builtInCategory); var ds = DirectShape.CreateElement(doc, categoryId); ds.Name = Path.GetFileName(filePath); foreach (var obj in model.Objects) { if (!obj.Attributes.Visible) { continue; } var layer = model.AllLayers.FindIndex(obj.Attributes.LayerIndex); if (layer?.IsVisible != true) { continue; } var geometryList = ImportObject(obj.Geometry, obj.Attributes, scaleFactor); if (geometryList == null) { continue; } try { ds.AppendShape(geometryList); } catch (Autodesk.Revit.Exceptions.ArgumentException) { } } if (trans.Commit() == TransactionStatus.Committed) { var elements = new ElementId[] { ds.Id }; Revit.ActiveUIDocument.Selection.SetElementIds(elements); Revit.ActiveUIDocument.ShowElements(elements); return(Result.Succeeded); } } } } return(Result.Failed); }
static void UpdateViewConstructionPlanesFrom(RhinoDoc rhinoDoc, DB.Document revitDoc) { if (!string.IsNullOrEmpty(rhinoDoc.TemplateFileUsed)) { return; } if (rhinoDoc.IsCreating) { Revit.EnqueueAction(doc => UpdateViewConstructionPlanesFrom(rhinoDoc, doc)); return; } bool imperial = rhinoDoc.ModelUnitSystem == UnitSystem.Feet || rhinoDoc.ModelUnitSystem == UnitSystem.Inches; var modelGridSpacing = imperial ? 1.0 * RhinoMath.UnitScale(UnitSystem.Yards, rhinoDoc.ModelUnitSystem) : 1.0 * RhinoMath.UnitScale(UnitSystem.Meters, rhinoDoc.ModelUnitSystem); var modelSnapSpacing = imperial ? 1 / 16.0 * RhinoMath.UnitScale(UnitSystem.Inches, rhinoDoc.ModelUnitSystem) : 1.0 * RhinoMath.UnitScale(UnitSystem.Millimeters, rhinoDoc.ModelUnitSystem); var modelThickLineFrequency = imperial ? 6 : 5; // Views { foreach (var view in rhinoDoc.Views) { var cplane = view.MainViewport.GetConstructionPlane(); cplane.GridSpacing = modelGridSpacing; cplane.SnapSpacing = modelSnapSpacing; cplane.ThickLineFrequency = modelThickLineFrequency; view.MainViewport.SetConstructionPlane(cplane); var min = cplane.Plane.PointAt(-cplane.GridSpacing * cplane.GridLineCount, -cplane.GridSpacing * cplane.GridLineCount, 0.0); var max = cplane.Plane.PointAt(+cplane.GridSpacing * cplane.GridLineCount, +cplane.GridSpacing * cplane.GridLineCount, 0.0); var bbox = new BoundingBox(min, max); // Zoom to grid view.MainViewport.ZoomBoundingBox(bbox); // Adjust to extens in case There is anything in the viewports like Grasshopper previews. view.MainViewport.ZoomExtents(); } } }
public static void AddTextLabel(Point3d pt, string text) { UnitSystem currentDocUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits); var doc = RhinoDoc.ActiveDoc; double height = (0.35 * unitSystemScaler); const string font = "Arial"; Rhino.Geometry.Plane plane = doc.Views.ActiveView.ActiveViewport.ConstructionPlane(); plane.Origin = pt; Guid id = doc.Objects.AddText(text, plane, height, font, false, false); if (id != Guid.Empty) { doc.Views.Redraw(); } }
static void AuditTolerances(RhinoDoc doc) { if (doc is object) { var maxDistanceTolerance = Revit.VertexTolerance * RhinoMath.UnitScale(UnitSystem.Feet, doc.ModelUnitSystem); if (doc.ModelAbsoluteTolerance > maxDistanceTolerance) { doc.ModelAbsoluteTolerance = maxDistanceTolerance; } var maxAngleTolerance = Revit.AngleTolerance; if (doc.ModelAngleToleranceRadians > maxAngleTolerance) { doc.ModelAngleToleranceRadians = maxAngleTolerance; } } }
public static List <Rectangle3d> GetBoundariesFromResult(RequestHandler result) { var unitScale = RhinoMath.UnitScale(UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem); Coord lengthPerDegree = TranslateToXYManually.GetDegreesPerAxis(result.MinBounds, result.MaxBounds, unitScale); var boundaries = new List <Rectangle3d>(); for (var i = 0; i < result.AllBounds.Count; i++) { var lowerCoord = result.AllBounds[i].Item1; var upperCoord = result.AllBounds[i].Item2; var lowerLeft = TranslateToXYManually.GetPointFromLatLong(lowerCoord, lengthPerDegree, result.MinBounds); var upperRight = TranslateToXYManually.GetPointFromLatLong(upperCoord, lengthPerDegree, result.MinBounds); var boundary = new Rectangle3d(Plane.WorldXY, lowerLeft, upperRight); boundaries.Add(boundary); } return(boundaries); }
public static Dictionary <OSMTag, List <Point3d> > NodePointsFromCoords(RequestHandler result) { var geometryResult = new Dictionary <OSMTag, List <Point3d> >(); var unitScale = RhinoMath.UnitScale(UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem); // OSM conversion assumes meters Coord lengthPerDegree = GetDegreesPerAxis(result.MinBounds, result.MaxBounds, unitScale); foreach (var entry in result.FoundData) { geometryResult[entry.Key] = new List <Point3d>(); foreach (FoundItem item in entry.Value) { var pt = GetPointFromLatLong(item.Coords[0], lengthPerDegree, result.MinBounds); geometryResult[entry.Key].Add(pt); } } return(geometryResult); }
public static Point3d AddTextLabel(Curve curve, string text, List <Point3d> oldPts) { UnitSystem currentDocUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits); double param; curve.ClosestPoint(new Point3d(-1000 * unitSystemScaler, -1000 * unitSystemScaler, 0), out param); Point3d pt = curve.PointAt(param); foreach (Point3d point in oldPts) { if (pt.Y == point.Y && Math.Abs(pt.X - point.X) < 10 * unitSystemScaler) { pt = pt + new Point3d(0, 2 * unitSystemScaler, 0); } } AddTextLabel(pt, text); return(pt); }
static void UpdateDocumentUnits(RhinoDoc rhinoDoc, DB.Document revitDoc = null) { bool docModified = rhinoDoc.Modified; try { if (revitDoc is null) { rhinoDoc.ModelUnitSystem = UnitSystem.None; rhinoDoc.ModelAbsoluteTolerance = Revit.VertexTolerance; rhinoDoc.ModelAngleToleranceRadians = Revit.AngleTolerance; } else if (rhinoDoc.ModelUnitSystem == UnitSystem.None) { var units = revitDoc.GetUnits(); var lengthFormatoptions = units.GetFormatOptions(DB.UnitType.UT_Length); rhinoDoc.ModelUnitSystem = lengthFormatoptions.DisplayUnits.ToRhinoLengthUnits(); rhinoDoc.ModelAngleToleranceRadians = Revit.AngleTolerance; rhinoDoc.ModelDistanceDisplayPrecision = ((int)-Math.Log10(lengthFormatoptions.Accuracy)).Clamp(0, 7); rhinoDoc.ModelAbsoluteTolerance = Revit.VertexTolerance * RhinoMath.UnitScale(UnitSystem.Feet, rhinoDoc.ModelUnitSystem); //switch (rhinoDoc.ModelUnitSystem) //{ // case UnitSystem.None: break; // case UnitSystem.Feet: // case UnitSystem.Inches: // newDoc.ModelAbsoluteTolerance = (1.0 / 160.0) * RhinoMath.UnitScale(UnitSystem.Inches, newDoc.ModelUnitSystem); // break; // default: // newDoc.ModelAbsoluteTolerance = 0.1 * RhinoMath.UnitScale(UnitSystem.Millimeters, newDoc.ModelUnitSystem); // break; //} UpdateViewConstructionPlanesFrom(rhinoDoc, revitDoc); } } finally { rhinoDoc.Modified = docModified; } }
public static MenuBarManager.CallbackStatus Import3DMFile(string filePath) { using (File3dm model = File3dm.Read(filePath)) { var scaleFactor = RhinoMath.UnitScale(model.Settings.ModelUnitSystem, PartUnit.ToRhinoUnits()); var elements = new List <NXOpen.NXObject>(); //model.Objects.Select(obj => obj.Geometry.GetType().ToString()).ToList().ForEach(obj => obj.ListingWindowWriteLine()); foreach (var obj in model.Objects.Where(x => !x.Attributes.IsInstanceDefinitionObject && x.Attributes.Space == ActiveSpace.ModelSpace)) { if (!obj.Attributes.Visible) { continue; } var layer = model.AllLayers.FindIndex(obj.Attributes.LayerIndex); if (layer?.IsVisible != true) { continue; } var geometry = obj.Geometry; if (geometry is Extrusion extrusion) { geometry = extrusion.ToBrep(); } else if (geometry is SubD subD) { geometry = subD.ToBrep(new SubDToBrepOptions()); } try { switch (geometry) { case Point point: var referncePoint = WorkPart.Points.CreatePoint(point.Location.ToXYZ(scaleFactor)); referncePoint.SetVisibility(NXOpen.SmartObject.VisibilityOption.Visible); elements.Add(referncePoint); break; case Curve curve: if (curve.TryGetPlane(out var plane, DistanceTolerance)) // 平面曲线转换 { if (CurveEncoder.ToNXCurve(curve, scaleFactor) is NXOpen.Curve crv) { elements.Add(crv); } } else { var shape = curve.ToShape(scaleFactor); elements.AddRange(shape); } break; case Brep brep: BrepEncoder.ToSolid(brep); //if (brep.ToSolid(scaleFactor) is DB.Solid solid) //{ // if (DB.FreeFormElement.Create(doc, solid) is DB.FreeFormElement freeForm) // { // elements.Add(freeForm.Id); // { // var categoryId = ImportLayer(doc, model, layer, categories, materials); // if (categoryId != DB.ElementId.InvalidElementId) // freeForm.get_Parameter(DB.BuiltInParameter.FAMILY_ELEM_SUBCATEGORY).Set(categoryId); // } // if (obj.Attributes.MaterialSource == ObjectMaterialSource.MaterialFromObject) // { // if (model.AllMaterials.FindIndex(obj.Attributes.MaterialIndex) is Material material) // { // var categoryId = ImportMaterial(doc, material, materials); // if (categoryId != DB.ElementId.InvalidElementId) // freeForm.get_Parameter(DB.BuiltInParameter.MATERIAL_ID_PARAM).Set(categoryId); // } // } // } //} break; } } catch (NXOpen.NXException ex) { } } } return(MenuBarManager.CallbackStatus.Continue); }
static void AuditUnits(RhinoDoc doc) { if (Command.InScriptRunnerCommand()) { return; } if (Revit.ActiveUIDocument.Document is DB.Document revitDoc) { var units = revitDoc.GetUnits(); var lengthFormatoptions = units.GetFormatOptions(DB.UnitType.UT_Length); var RevitModelUnitSystem = lengthFormatoptions.DisplayUnits.ToRhinoLengthUnits(); var GrasshopperModelUnitSystem = GH.Guest.ModelUnitSystem != UnitSystem.Unset ? GH.Guest.ModelUnitSystem : doc.ModelUnitSystem; if (doc.ModelUnitSystem != RevitModelUnitSystem || doc.ModelUnitSystem != GrasshopperModelUnitSystem) { using ( var taskDialog = new TaskDialog("Units") { MainIcon = TaskDialogIcons.IconInformation, TitleAutoPrefix = true, AllowCancellation = true, MainInstruction = "Model units mismatch.", MainContent = "What units do you want to use?", ExpandedContent = $"The model you are opening is in {doc.ModelUnitSystem}{Environment.NewLine}Active Revit model '{revitDoc.Title}' units are {RevitModelUnitSystem}", FooterText = "Current version: " + Addin.DisplayVersion } ) { taskDialog.AddCommandLink(Autodesk.Revit.UI.TaskDialogCommandLinkId.CommandLink1, $"Continue opening in {doc.ModelUnitSystem}", $"Rhino and Grasshopper will work in {doc.ModelUnitSystem}"); taskDialog.AddCommandLink(Autodesk.Revit.UI.TaskDialogCommandLinkId.CommandLink2, $"Adjust Rhino model to {RevitModelUnitSystem} like Revit", $"Scale Rhino model by {RhinoMath.UnitScale(doc.ModelUnitSystem, RevitModelUnitSystem)}"); taskDialog.DefaultButton = Autodesk.Revit.UI.TaskDialogResult.CommandLink2; if (GH.Guest.ModelUnitSystem != UnitSystem.Unset) { taskDialog.ExpandedContent += $"{Environment.NewLine}Documents opened in Grasshopper were working in {GH.Guest.ModelUnitSystem}"; if (GrasshopperModelUnitSystem != doc.ModelUnitSystem && GrasshopperModelUnitSystem != RevitModelUnitSystem) { taskDialog.AddCommandLink(Autodesk.Revit.UI.TaskDialogCommandLinkId.CommandLink3, $"Adjust Rhino model to {GH.Guest.ModelUnitSystem} like Grasshopper", $"Scale Rhino model by {RhinoMath.UnitScale(doc.ModelUnitSystem, GH.Guest.ModelUnitSystem)}"); taskDialog.DefaultButton = Autodesk.Revit.UI.TaskDialogResult.CommandLink3; } } switch (taskDialog.Show()) { case Autodesk.Revit.UI.TaskDialogResult.CommandLink2: doc.ModelAngleToleranceRadians = Revit.AngleTolerance; doc.ModelDistanceDisplayPrecision = ((int)-Math.Log10(lengthFormatoptions.Accuracy)).Clamp(0, 7); doc.ModelAbsoluteTolerance = Revit.VertexTolerance * RhinoMath.UnitScale(UnitSystem.Feet, RevitModelUnitSystem); doc.AdjustModelUnitSystem(RevitModelUnitSystem, true); UpdateViewConstructionPlanesFrom(doc, revitDoc); break; case Autodesk.Revit.UI.TaskDialogResult.CommandLink3: doc.ModelAngleToleranceRadians = Revit.AngleTolerance; doc.ModelDistanceDisplayPrecision = Grasshopper.CentralSettings.FormatDecimalDigits.Clamp(0, 7); doc.ModelAbsoluteTolerance = Revit.VertexTolerance * RhinoMath.UnitScale(UnitSystem.Feet, GH.Guest.ModelUnitSystem); doc.AdjustModelUnitSystem(GH.Guest.ModelUnitSystem, true); UpdateViewConstructionPlanesFrom(doc, revitDoc); break; default: AuditTolerances(doc); break; } } } } }
public static Result Import3DMFile(string filePath, Document doc, BuiltInCategory builtInCategory) { try { DirectShapeLibrary.GetDirectShapeLibrary(doc).Reset(); using (var model = File3dm.Read(filePath)) { var scaleFactor = RhinoMath.UnitScale(model.Settings.ModelUnitSystem, Revit.ModelUnitSystem); using (var trans = new Transaction(doc, "Import 3D Model")) { if (trans.Start() == TransactionStatus.Started) { var categoryId = new ElementId(builtInCategory); var materials = GetMaterialsByName(doc); var type = DirectShapeType.Create(doc, Path.GetFileName(filePath), categoryId); foreach (var obj in model.Objects.Where(x => !x.Attributes.IsInstanceDefinitionObject && x.Attributes.Space == ActiveSpace.ModelSpace)) { if (!obj.Attributes.Visible) { continue; } var geometryList = ImportObject(model, obj.Geometry, obj.Attributes, doc, materials, scaleFactor).ToArray(); if (geometryList == null) { continue; } try { type.AppendShape(geometryList); } catch (Autodesk.Revit.Exceptions.ArgumentException) { } } var ds = DirectShape.CreateElement(doc, type.Category.Id); ds.SetTypeId(type.Id); var library = DirectShapeLibrary.GetDirectShapeLibrary(doc); if (!library.ContainsType(type.UniqueId)) { library.AddDefinitionType(type.UniqueId, type.Id); } ds.SetShape(DirectShape.CreateGeometryInstance(doc, type.UniqueId, Autodesk.Revit.DB.Transform.Identity)); if (trans.Commit() == TransactionStatus.Committed) { var elements = new ElementId[] { ds.Id }; Revit.ActiveUIDocument.Selection.SetElementIds(elements); Revit.ActiveUIDocument.ShowElements(elements); return(Result.Succeeded); } } } } } finally { DirectShapeLibrary.GetDirectShapeLibrary(doc).Reset(); } return(Result.Failed); }
public static Dictionary <OSMTag, List <Brep> > BuildingBrepsFromCoords(ref RequestHandler result, bool outputHeighted) { var geometryResult = new Dictionary <OSMTag, List <Brep> >(); var unitScale = RhinoMath.UnitScale(UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem); // OSM conversion assumes meters var tolerance = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; Coord lengthPerDegree = GetDegreesPerAxis(result.MinBounds, result.MaxBounds, unitScale); foreach (var entry in result.FoundData) { geometryResult[entry.Key] = new List <Brep>(); for (int i = entry.Value.Count - 1; i >= 0; i--) { var outlinePoints = new List <Point3d>(); foreach (var coord in entry.Value[i].Coords) { outlinePoints.Add(GetPointFromLatLong(coord, lengthPerDegree, result.MinBounds)); } var outline = new PolylineCurve(outlinePoints); // Creating a polylinecurve from scratch makes invalid geometry if (!outline.IsClosed) { if (outline.IsClosable(ALLOWABLE_CLOSURE)) // Force-close the curve { outline.MakeClosed(ALLOWABLE_CLOSURE); } else // Skip this curve as no valid Brep can be made { entry.Value.RemoveAt(i); continue; } } var height = GetBuildingHeights.ParseHeight(entry.Value[i].Tags, unitScale); if (outputHeighted && height > 0.0) // Output heighted buildings { var toHeight = new Vector3d(0, 0, height); var envelope = Surface.CreateExtrusion(outline, toHeight); var floor = Brep.CreatePlanarBreps(outline, tolerance); outline.Translate(toHeight); var roof = Brep.CreatePlanarBreps(outline, tolerance); var volume = Brep.JoinBreps(new Brep[] { floor[0], envelope.ToBrep(), roof[0] }, tolerance); geometryResult[entry.Key].Add(volume[0]); } else if (!outputHeighted && height == 0.0) // Output unheighted buildings { var builtSurface = Brep.CreatePlanarBreps(outline, tolerance); if (builtSurface != null && builtSurface.Length > 0) { geometryResult[entry.Key].Add(builtSurface[0]); } } else // Item wasn't matched, so should be removed from result so its metadata is not output { entry.Value.RemoveAt(i); } } geometryResult[entry.Key].Reverse(); // We iterated in reverse order, so swap list back to right direction } return(geometryResult); }
/// <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 void SolveInstance(IGH_DataAccess DA) { string val = ""; if (!DA.GetData("Formatted Value", ref val)) { return; } string splitchars = "'"; string[] ftParts = val.Split(splitchars.ToCharArray()); string ftPart = ftParts[0]; string remains = String.Join("", ftParts, 1, ftParts.Length - 1); double ft; Double.TryParse(ftPart, out ft); splitchars = "- \""; string[] inchParts = remains.Split(splitchars.ToCharArray()); double inchVal = 0.0; foreach (string str in removeEmpties(inchParts)) { //Print(String.Format("parsing string chunk {0}", str)); double tempVal = 0; if (str.Contains("/")) { try { string[] fracParts = removeEmpties(str.Split("/".ToCharArray())); double tempVal2 = 1.0; Double.TryParse(fracParts[0], out tempVal); Double.TryParse(fracParts[1], out tempVal2); if (tempVal2 != 0) { //Print(String.Format("Adding Fraction {0}/{1} = {2}", tempVal, tempVal2, (tempVal / tempVal2))); inchVal += (tempVal / tempVal2); } } catch (Exception ex) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, ex.Message); //Print(ex.ToString()); } } else { Double.TryParse(str, out tempVal); inchVal += tempVal; } //Print(String.Format("inchVal = {0}", inchVal)); } //Print(String.Format("inchVal/12 = {0}", inchVal / 12.0)); double feet = ft + inchVal / 12.0; double inches = ft * 12 + inchVal; DA.SetData("Value in Feet", feet); DA.SetData("Value in Inches", inches); //Convert to document units UnitSystem docUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitConvert = RhinoMath.UnitScale(Rhino.UnitSystem.Feet, docUnits); double docUnitVal = feet * unitConvert; DA.SetData("Value in Document Units", docUnitVal); }
static Result Import3DMFileToFamily ( DB.Document doc, string filePath ) { using (var model = File3dm.Read(filePath)) { var scaleFactor = RhinoMath.UnitScale(model.Settings.ModelUnitSystem, Revit.ModelUnitSystem); using (var trans = new DB.Transaction(doc, "Import 3D Model")) { if (trans.Start() == DB.TransactionStatus.Started) { var materials = GetMaterialsByName(doc); var categories = GetCategoriesByName(doc); var elements = new List <DB.ElementId>(); var view3D = default(DB.View); using (var collector = new DB.FilteredElementCollector(doc)) { var elementCollector = collector.OfClass(typeof(DB.View3D)); view3D = elementCollector.Cast <DB.View3D>().Where(x => x.Name == "{3D}").FirstOrDefault(); } if (view3D is object) { foreach (var cplane in model.AllNamedConstructionPlanes) { var plane = cplane.Plane; var bubbleEnd = plane.Origin.ToXYZ(scaleFactor); var freeEnd = (plane.Origin + plane.XAxis).ToXYZ(scaleFactor); var cutVec = plane.YAxis.ToXYZ(); var refrencePlane = doc.FamilyCreate.NewReferencePlane(bubbleEnd, freeEnd, cutVec, view3D); refrencePlane.Name = cplane.Name; refrencePlane.Maximize3DExtents(); } } foreach (var obj in model.Objects.Where(x => !x.Attributes.IsInstanceDefinitionObject && x.Attributes.Space == ActiveSpace.ModelSpace)) { if (!obj.Attributes.Visible) { continue; } var layer = model.AllLayers.FindIndex(obj.Attributes.LayerIndex); if (layer?.IsVisible != true) { continue; } var geometry = obj.Geometry; if (geometry is Extrusion extrusion) { geometry = extrusion.ToBrep(); } else if (geometry is SubD subD) { geometry = subD.ToBrep(SubDToBrepOptions.Default); } try { switch (geometry) { case Point point: if (doc.OwnerFamily.IsConceptualMassFamily) { var referncePoint = doc.FamilyCreate.NewReferencePoint(point.Location.ToXYZ(scaleFactor)); elements.Add(referncePoint.Id); } break; case Curve curve: if (curve.TryGetPlane(out var plane, Revit.VertexTolerance)) { if (curve.ToCurve(scaleFactor) is DB.Curve crv) { var sketchPlane = DB.SketchPlane.Create(doc, plane.ToPlane(scaleFactor)); var modelCurve = doc.FamilyCreate.NewModelCurve(crv, sketchPlane); elements.Add(modelCurve.Id); { var subCategoryId = ImportLayer(doc, model, layer, categories, materials); if (DB.Category.GetCategory(doc, subCategoryId) is DB.Category subCategory) { var familyGraphicsStyle = subCategory?.GetGraphicsStyle(DB.GraphicsStyleType.Projection); if (familyGraphicsStyle is object) { modelCurve.Subcategory = familyGraphicsStyle; } } } } } else if (DB.DirectShape.IsSupportedDocument(doc) && DB.DirectShape.IsValidCategoryId(doc.OwnerFamily.FamilyCategory.Id, doc)) { var subCategoryId = ImportLayer(doc, model, layer, categories, materials); var shape = curve.ToShape(); if (shape.Length > 0) { var ds = DB.DirectShape.CreateElement(doc, doc.OwnerFamily.FamilyCategory.Id); ds.SetShape(shape); elements.Add(ds.Id); } } break; case Brep brep: if (brep.ToSolid(scaleFactor) is DB.Solid solid) { if (DB.FreeFormElement.Create(doc, solid) is DB.FreeFormElement freeForm) { elements.Add(freeForm.Id); { var categoryId = ImportLayer(doc, model, layer, categories, materials); if (categoryId != DB.ElementId.InvalidElementId) { freeForm.get_Parameter(DB.BuiltInParameter.FAMILY_ELEM_SUBCATEGORY).Set(categoryId); } } if (obj.Attributes.MaterialSource == ObjectMaterialSource.MaterialFromObject) { if (model.AllMaterials.FindIndex(obj.Attributes.MaterialIndex) is Material material) { var categoryId = ImportMaterial(doc, material, materials); if (categoryId != DB.ElementId.InvalidElementId) { freeForm.get_Parameter(DB.BuiltInParameter.MATERIAL_ID_PARAM).Set(categoryId); } } } } } break; } } catch (Autodesk.Revit.Exceptions.ArgumentException) { } } if (trans.Commit() == DB.TransactionStatus.Committed) { Revit.ActiveUIDocument.Selection.SetElementIds(elements); Revit.ActiveUIDocument.ShowElements(elements); return(Result.Succeeded); } } } } return(Result.Failed); }
/// <summary> /// Generate a series of planes on the glulam cross-section. TODO: Re-implement as GlulamOrientation function /// </summary> /// <param name="N">Number of planes to extract.</param> /// <param name="extension">Extension of the centreline curve</param> /// <param name="frames">Output cross-section planes.</param> /// <param name="parameters">Output t-values along centreline curve.</param> /// <param name="interpolation">Type of interpolation to use (default is Linear).</param> public override void GenerateCrossSectionPlanes(int N, out Plane[] frames, out double[] parameters, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR) { Curve curve = Centreline; double multiplier = RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, UnitSystem.Millimeters); //PolylineCurve discrete = curve.ToPolyline(Glulam.Tolerance * 10, Glulam.AngleTolerance, 0.0, 0.0); PolylineCurve discrete = curve.ToPolyline(multiplier * Tolerance, AngleTolerance, multiplier * MininumSegmentLength, curve.GetLength() / MinimumNumSegments); if (discrete.TryGetPolyline(out Polyline discrete2)) { N = discrete2.Count; parameters = new double[N]; for (int i = 0; i < N; ++i) { curve.ClosestPoint(discrete2[i], out parameters[i]); } } else { parameters = curve.DivideByCount(N - 1, true).ToArray(); } //frames = parameters.Select(x => GetPlane(x)).ToArray(); //return; frames = new Plane[parameters.Length]; var vectors = Orientation.GetOrientations(curve, parameters); Plane temp; for (int i = 0; i < parameters.Length; ++i) { temp = Misc.PlaneFromNormalAndYAxis( curve.PointAt(parameters[i]), curve.TangentAt(parameters[i]), vectors[i]); if (temp.IsValid) { frames[i] = temp; } else { throw new Exception(string.Format("Plane is invalid: vector {0} tangent {1}", vectors[i], curve.TangentAt(parameters[i]))); } // TODO: Make back-up orientation direction in this case. } return; N = Math.Max(N, 2); frames = new Plane[N]; Curve CL; double extension = 0; if (Centreline.IsClosed) { CL = Centreline.DuplicateCurve(); } else { CL = Centreline.Extend(CurveEnd.Both, extension, CurveExtensionStyle.Smooth); } parameters = CL.DivideByCount(N - 1, true); GlulamOrientation TempOrientation = Orientation.Duplicate(); TempOrientation.Remap(Centreline, CL); for (int i = 0; i < N; ++i) { Vector3d v = TempOrientation.GetOrientation(CL, parameters[i]); frames[i] = tas.Core.Util.Misc.PlaneFromNormalAndYAxis(CL.PointAt(parameters[i]), CL.TangentAt(parameters[i]), v); } return; /* * double[] ft = new double[Frames.Count]; * double[] fa = new double[Frames.Count]; * * Plane temp; * for (int i = 0; i < Frames.Count; ++i) * { * CL.PerpendicularFrameAt(Frames[i].Item1, out temp); * ft[i] = Frames[i].Item1; * //fa[i] = Math.Acos(temp.YAxis * Frames[i].Item2.YAxis); * fa[i] = Vector3d.VectorAngle(temp.YAxis, Frames[i].Item2.YAxis, Frames[i].Item2); * } * * for (int i = 1; i < fa.Length; ++i) * { * if (fa[i] - fa[i - 1] > Math.PI) * fa[i] -= Constants.Tau; * else if (fa[i] - fa[i - 1] < -Math.PI) * fa[i] += Constants.Tau; * } * * int res; * int max = ft.Length - 1; * double mu; * * double[] angles = new double[N]; * * if (Frames.Count < 3) * interpolation = GlulamData.Interpolation.LINEAR; * * switch (interpolation) * { * case (GlulamData.Interpolation.HERMITE): // Hermite Interpolation * for (int i = 0; i < N; ++i) * { * if (t[i] < ft[0]) * { * angles[i] = fa[0]; * continue; * } * else if (t[i] > ft.Last()) * { * angles[i] = fa.Last(); * continue; * } * * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * * if (res == 0 && res < max - 1) * { * mu = (t[i] - ft[0]) / (ft[1] - ft[0]); * angles[i] = Interpolation.HermiteInterpolate(fa[0], fa[0], fa[1], fa[2], mu, 0, 0); * } * else if (res > 0 && res < max - 1) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu, 0, 0); * * } * else if (res > 0 && res < max) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu, 0, 0); * } * else if (res == max) * { * angles[i] = fa[res]; * } * * else * continue; * } * break; * * case (GlulamData.Interpolation.CUBIC): // Cubic Interpolation * for (int i = 0; i < N; ++i) * { * if (t[i] <= ft[0]) * { * angles[i] = fa[0]; * continue; * } * else if (t[i] >= ft.Last()) * { * angles[i] = fa.Last(); * continue; * } * * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * * if (res == 0 && res < max - 1) * { * mu = (t[i] - ft[0]) / (ft[1] - ft[0]); * angles[i] = Interpolation.CubicInterpolate(fa[0], fa[0], fa[1], fa[2], mu); * } * else if (res > 0 && res < max - 1) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu); * * } * else if (res > 0 && res < max) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu); * } * else if (res == max) * { * angles[i] = fa[res]; * } * * else * continue; * } * break; * * default: // Default linear interpolation * for (int i = 0; i < N; ++i) * { * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * if (res >= 0 && res < max) * { * if (ft[res + 1] - ft[res] == 0) * mu = 0.5; * else * mu = Math.Min(1.0, Math.Max(0, (t[i] - ft[res]) / (ft[res + 1] - ft[res]))); * angles[i] = Interpolation.Lerp(fa[res], fa[res + 1], mu); * } * else if (res < 0) * angles[i] = fa[0]; * else if (res >= max) * angles[i] = fa[max]; * } * break; * } * * for (int i = 0; i < N; ++i) * { * CL.PerpendicularFrameAt(t[i], out temp); * temp.Transform(Rhino.Geometry.Transform.Rotation(angles[i], temp.ZAxis, temp.Origin)); * planes[i] = temp; * } */ }
internal static bool LoadScan(string path, int step) { LoadSettings(); //Task.Run(() => ProcessDataAsync(path)); Task.Run(() => { PointCloud temp = null; if (path.EndsWith("fls")) { Workspace.Initialize(); Rhino.RhinoApp.WriteLine("FaroScan: Initialized. Loading scan..."); Workspace.ReflectionMode(2); FNResult res = Workspace.Load(path); if (res != FNResult.Success) { Rhino.RhinoApp.WriteLine("FaroScan: Failed to load scan: " + res.ToString()); return; } double[] points_raw; int[] color_raw; Workspace.GetXYZPoints(0, out points_raw, out color_raw, step); foreach (var attrName in Workspace.attribute_names) { Rhino.RhinoApp.WriteLine(string.Format("{0} : {1}", attrName, Workspace.GetAttribute(attrName))); } var children = Workspace.GetChildren(); foreach (string str in children) { RhinoApp.WriteLine(str); } Workspace.Unload(0); Workspace.Uninitialize(); Rhino.RhinoApp.WriteLine("FaroScan: Faro done."); int N = points_raw.Length / 3; Point3d[] points = new Point3d[N]; Color[] colors = new Color[N]; double factor = RhinoMath.UnitScale(UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem); for (int i = 0; i < N; ++i) { if (RFContext.Abort) { Abort = false; break; } if (N % 1000000 == 0) { RhinoApp.WriteLine("Still working: {0}", N); } points[i] = new Point3d(points_raw[i * 3] * factor, points_raw[i * 3 + 1] * factor, points_raw[i * 3 + 2] * factor); colors[i] = Color.FromArgb(color_raw[i]); } temp = new PointCloud(points); for (int i = 0; i < temp.Count; ++i) { temp[i].Color = colors[i]; } Rhino.RhinoApp.WriteLine("Farhino: Loaded " + path + " finally."); } /* * else if (path.EndsWith("pcd")) * { * tasTools.IO.PCD_Importer pcd = new tasTools.IO.PCD_Importer(); * pcd.use_transform = true; * pcd.Import(path, out temp, true); * * Rhino.RhinoApp.WriteLine("PCD: Loaded " + path + " finally."); * Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); * } */ temp.Transform(Xform); if (Clip) { Rhino.RhinoApp.WriteLine("Using clipping box."); List <int> indices = new List <int>(); for (int i = 0; i < temp.Count; ++i) { if (ClippingBox.Contains(temp[i].Location)) { indices.Add(i); } } PointCloud cliptemp = new PointCloud(); List <Color> colors = new List <Color>(); for (int i = 0; i < indices.Count; ++i) { cliptemp.Add(temp[indices[i]].Location); colors.Add(temp[indices[i]].Color); } for (int i = 0; i < colors.Count; ++i) { cliptemp[i].Color = colors[i]; } Cloud = cliptemp; } else { Cloud = temp; } Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); }); Rhino.RhinoApp.WriteLine("Farhino: Loading " + path + " asynchronously. Keep working, it will appear soon."); return(true); }
static double InOtherUnits(double value, DB.ParameterType type, UnitSystem from, UnitSystem to) { switch (type) { #region Length case DB.ParameterType.Length: case DB.ParameterType.ForceLengthPerAngle: case DB.ParameterType.LinearForceLengthPerAngle: case DB.ParameterType.ReinforcementLength: case DB.ParameterType.AreaForcePerLength: case DB.ParameterType.ReinforcementAreaPerUnitLength: return(value * RhinoMath.UnitScale(from, to)); case DB.ParameterType.ForcePerLength: case DB.ParameterType.LinearForcePerLength: case DB.ParameterType.MassPerUnitLength: case DB.ParameterType.WeightPerUnitLength: case DB.ParameterType.PipeMassPerUnitLength: return(value / RhinoMath.UnitScale(from, to)); #endregion #region Area case DB.ParameterType.Area: case DB.ParameterType.AreaForce: case DB.ParameterType.HVACAreaDividedByCoolingLoad: case DB.ParameterType.HVACAreaDividedByHeatingLoad: case DB.ParameterType.SurfaceArea: case DB.ParameterType.ReinforcementArea: case DB.ParameterType.SectionArea: return(value * Math.Pow(RhinoMath.UnitScale(from, to), 2.0)); case DB.ParameterType.HVACCoolingLoadDividedByArea: case DB.ParameterType.HVACHeatingLoadDividedByArea: case DB.ParameterType.MassPerUnitArea: return(value / Math.Pow(RhinoMath.UnitScale(from, to), 2.0)); #endregion #region Volume case DB.ParameterType.Volume: case DB.ParameterType.PipingVolume: case DB.ParameterType.ReinforcementVolume: return(value * Math.Pow(RhinoMath.UnitScale(from, to), 3.0)); case DB.ParameterType.HVACCoolingLoadDividedByVolume: case DB.ParameterType.HVACHeatingLoadDividedByVolume: case DB.ParameterType.HVACAirflowDividedByVolume: return(value * Math.Pow(RhinoMath.UnitScale(from, to), 3.0)); #endregion default: Debug.WriteLine($"{nameof(InOtherUnits)} do not implement conversion for {type}"); break; } return(value); }
public static void PlaceDoorsAt(string schemeName) { string inputLayerPath = schemeName + "::EJLT Shapes"; string outputLayerPath = schemeName + "::Doors"; UnitSystem currentDocUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits); double doorW = 2.5 * unitSystemScaler; double doorH = 0.2 * unitSystemScaler; // get curves List <int> layerIndexs; List <Curve> curves = LayerHelper.GetCurvesFromChild(inputLayerPath, out layerIndexs); // explode curves List <Polyline> polies = new List <Polyline>(); List <Line[]> exploded = new List <Line[]>(); foreach (Curve c in curves) { Polyline poly; c.TryGetPolyline(out poly); polies.Add(poly); exploded.Add(poly.GetSegments()); } List <Point3d> centers = new List <Point3d>(); List <bool> vertical = new List <bool>(); // find overlapping curves, find center, find direction of lines for (int i = 0; i < polies.Count; i++) { foreach (Line line in exploded[i]) { for (int j = 0; j < polies.Count; j++) { if (i == j) { continue; // skip intersection check with current rectangle } foreach (Line otherline in exploded[j]) { Curve c1 = line.ToNurbsCurve(); Curve c2 = otherline.ToNurbsCurve(); // get all intersections var intersects = Intersection.CurveCurve(c1, c2, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, 0.1); if (intersects != null && intersects.Count > 0) { foreach (var inter in intersects) { if (inter.IsOverlap) // a overlap found { double length = inter.OverlapA.Length * c1.GetLength(); if (length > 3.5 * unitSystemScaler) // overlap is long enough { Point3d mid = c1.PointAt(inter.OverlapA.Mid); double mindis = 10000.0; foreach (Point3d oldpt in centers) { double distance = mid.DistanceTo(oldpt); if (distance < mindis) { mindis = distance; } } if (mindis > 1.0) // no duplicates { centers.Add(c1.PointAt(inter.OverlapA.Mid)); if (c1.PointAt(0).X == c1.PointAt(1).X) { vertical.Add(true); } else { vertical.Add(false); } } } } } } } } } } // draws rectangle for (int i = 0; i < centers.Count; i++) { if (vertical[i]) { Point3d corner = new Point3d(centers[i].X - doorH / 2, centers[i].Y - doorW / 2, 0.0); Rectangle3d rec = new Rectangle3d(new Plane(corner, Vector3d.ZAxis), doorH, doorW); LayerHelper.BakeObjectToLayer(rec.ToPolyline().ToPolylineCurve(), "Doors", schemeName); } else { Point3d corner = new Point3d(centers[i].X - doorW / 2, centers[i].Y - doorH / 2, 0.0); Rectangle3d rec = new Rectangle3d(new Plane(corner, Vector3d.ZAxis), doorW, doorH); LayerHelper.BakeObjectToLayer(rec.ToPolyline().ToPolylineCurve(), "Doors", schemeName); } } Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); }
/// <summary> /// Generate a series of planes on the glulam cross-section. TODO: Re-implement as GlulamOrientation function /// </summary> /// <param name="N">Number of planes to extract.</param> /// <param name="extension">Extension of the centreline curve</param> /// <param name="frames">Output cross-section planes.</param> /// <param name="parameters">Output t-values along centreline curve.</param> /// <param name="interpolation">Type of interpolation to use (default is Linear).</param> public override void GenerateCrossSectionPlanes(int N, out Plane[] frames, out double[] parameters, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR) { Curve curve = Centreline; double multiplier = RhinoMath.UnitScale(UnitSystem.Millimeters, Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem); //PolylineCurve discrete = curve.ToPolyline(Glulam.Tolerance * 10, Glulam.AngleTolerance, 0.0, 0.0); PolylineCurve discrete = curve.ToPolyline(multiplier * Tolerance, AngleTolerance, multiplier * MininumSegmentLength, curve.GetLength() / MinimumNumSegments); if (discrete == null) { parameters = curve.DivideByCount(N - 1, true).ToArray(); //discrete = new PolylineCurve(new Point3d[] { curve.PointAtStart, curve.PointAtEnd }); } else { if (discrete.TryGetPolyline(out Polyline discrete2)) { N = discrete2.Count; parameters = new double[N]; for (int i = 0; i < N; ++i) { curve.ClosestPoint(discrete2[i], out parameters[i]); } } else { parameters = curve.DivideByCount(N - 1, true).ToArray(); } } //frames = parameters.Select(x => GetPlane(x)).ToArray(); //return; frames = new Plane[parameters.Length]; var vectors = Orientation.GetOrientations(curve, parameters); Plane temp; for (int i = 0; i < parameters.Length; ++i) { temp = Utility.PlaneFromNormalAndYAxis( curve.PointAt(parameters[i]), curve.TangentAt(parameters[i]), vectors[i]); if (temp.IsValid) { frames[i] = temp; } else { throw new Exception(string.Format("Plane is invalid: vector {0} tangent {1}", vectors[i], curve.TangentAt(parameters[i]))); } } return; }
public static void Make3d(string schemeName) { string inputLayerPath = schemeName + "::EJLT Shapes"; string outputLayerPath = schemeName + "::Walls"; string doorsLayerPath = schemeName + "::Doors"; List <int> layerIndexs; List <Curve> curves = LayerHelper.GetCurvesFromChild(inputLayerPath, out layerIndexs); List <Curve> doors = LayerHelper.GetCurvesFrom(doorsLayerPath); List <LineCurve> afterCut = new List <LineCurve>(); List <Line> exploded = new List <Line>(); foreach (Curve c in curves) { Polyline poly; c.TryGetPolyline(out poly); exploded.AddRange(poly.GetSegments()); } List <Line> lineSegDoor = new List <Line>(); List <List <LineCurve> > doorsPerSeg = new List <List <LineCurve> >(); foreach (Line lineSeg in exploded) { List <LineCurve> doorsThisSeg = new List <LineCurve>(); foreach (Curve door in doors) { CurveIntersections inter = Intersection.CurveLine(door, lineSeg, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, 0.0); if (inter.Count == 2) { LineCurve l1; Point3d p1 = inter.First().PointA; Point3d p2 = inter[1].PointA; l1 = new LineCurve(p1, p2); doorsThisSeg.Add(l1); } } if (doorsThisSeg.Count > 0) { lineSegDoor.Add(lineSeg); doorsPerSeg.Add(doorsThisSeg); } else { // no intersection, add to after cut afterCut.Add(new LineCurve(lineSeg)); } } for (int i = 0; i < lineSegDoor.Count; i++) { // points from all intersection points List <Point3d> intersectionPts = new List <Point3d>(); intersectionPts.Add(lineSegDoor[i].From); intersectionPts.Add(lineSegDoor[i].To); foreach (LineCurve doorLine in doorsPerSeg[i]) { intersectionPts.Add(doorLine.PointAtStart); intersectionPts.Add(doorLine.PointAtEnd); } List <Point3d> sortedPoints = intersectionPts.OrderBy(pnt => pnt.Y).ThenBy(pnt => pnt.X).ToList(); // construct line segments for (int pi = 0; pi < sortedPoints.Count; pi = pi + 2) { LineCurve cuttedSegment = new LineCurve(sortedPoints[pi], sortedPoints[pi + 1]); bool indoor = false; foreach (Curve door in doors) { if (door.Contains(cuttedSegment.PointAt(0.5), Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == PointContainment.Inside) { indoor = true; break; } } if (!indoor) { afterCut.Add(cuttedSegment); } } } UnitSystem currentDocUnits = RhinoDoc.ActiveDoc.ModelUnitSystem; double unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits); foreach (LineCurve wallLine in afterCut) { LayerHelper.BakeObjectToLayer(Extrusion.Create(wallLine, 8 * unitSystemScaler, false).ToBrep(), "Walls", schemeName); } Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); }