diff --git a/Components/Materialize.cs b/Components/Materialize.cs index a741768..2c984c1 100644 --- a/Components/Materialize.cs +++ b/Components/Materialize.cs @@ -28,7 +28,7 @@ public ComponentMaterializeSlots( ) : base("Materialize Slots", /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddParameter(new ModuleParameter(), - "Module", + "Modules", "M", "All Monoceros Modules", GH_ParamAccess.list); diff --git a/Components/ModuleConstruct.cs b/Components/ModuleConstruct.cs index e7167aa..a293018 100644 --- a/Components/ModuleConstruct.cs +++ b/Components/ModuleConstruct.cs @@ -105,11 +105,11 @@ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pM "Points inside the Module Parts. Module parts will be fit" + " into the Slots of the Envelope.", GH_ParamAccess.list); - pManager.AddGeometryParameter("Production Geometry", + pManager.AddGeometryParameter("Geometry", "G", "Geometry used to materialize the result of the " + - "Monoceros Solver. Production geometry does not have to fit " + - "into the generated module cage and can be larger, " + + "Monoceros Solver. The Module geometry does not have to fit " + + "into the generated Module cage and can be larger, " + "smaller, different or none.", GH_ParamAccess.list); pManager[2].Optional = true; diff --git a/Components/ModuleDeconstruct.cs b/Components/ModuleDeconstruct.cs index cf89e55..1ebd4be 100644 --- a/Components/ModuleDeconstruct.cs +++ b/Components/ModuleDeconstruct.cs @@ -78,11 +78,11 @@ protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager.AddVectorParameter("Connector Directions", "CD", "Directions of connectors as unit vectors aligned to the " + - "base plane - a list parallel to C.", + "base plane - a list parallel to CP.", GH_ParamAccess.list); pManager.AddBooleanParameter("Connector Use Pattern", "UP", - "Connector use pattern - a list parallel to C. " + + "Connector use pattern - a list parallel to CP. " + "(only if R are provided)", GH_ParamAccess.list); pManager.AddBooleanParameter("Is Compact", diff --git a/Components/PopulateGeometryWithSlotCenters.cs b/Components/PopulateGeometryWithSlotCenters.cs index 666384a..fd32258 100644 --- a/Components/PopulateGeometryWithSlotCenters.cs +++ b/Components/PopulateGeometryWithSlotCenters.cs @@ -62,7 +62,7 @@ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pM protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddPointParameter("Slot Centers", "Pt", - "Points ready to be used as Monoceros Slot centers", + "Points ready to be used as Monoceros Slot centers or Module Part centers", GH_ParamAccess.list); } diff --git a/Components/RuleAssemble.cs b/Components/RuleAssemble.cs index 6325f9d..941f7af 100644 --- a/Components/RuleAssemble.cs +++ b/Components/RuleAssemble.cs @@ -31,7 +31,7 @@ public ComponentAssembleRule( ) : base("Assemble Rule", /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddParameter(new ModuleParameter(), - "Module", + "Modules", "M", "All Monoceros Modules", GH_ParamAccess.list); @@ -145,8 +145,6 @@ protected override void SolveInstance(IGH_DataAccess DA) { return; } - //_sourceModuleGeometry = sourceModule.Geometry; - //_sourceModuleGuids = sourceModule.ReferencedGeometryGuids; var sourceModuleTransform = Transform.PlaneToPlane(sourceModule.Pivot, basePlane); var sourceModuleGeometry = sourceModule.Geometry.Select(geo => { var placedGeometry = geo.Duplicate(); @@ -164,7 +162,6 @@ protected override void SolveInstance(IGH_DataAccess DA) { var transformedSourceConnectorPlane = sourceConnector.AnchorPlane.Clone(); transformedSourceConnectorPlane.Transform(sourceModuleTransform); - transformedSourceConnectorPlane.Rotate(Math.PI, transformedSourceConnectorPlane.YAxis); var targetModuleTransform = Transform.PlaneToPlane(targetConnector.AnchorPlane, transformedSourceConnectorPlane); var targetModuleGeometry = targetModule.Geometry.Select(geo => { diff --git a/Components/RuleExplicitFromCurve.cs b/Components/RuleExplicitFromCurve.cs index e586ad1..6b4e5af 100644 --- a/Components/RuleExplicitFromCurve.cs +++ b/Components/RuleExplicitFromCurve.cs @@ -73,7 +73,7 @@ protected override void SolveInstance(IGH_DataAccess DA) { } for (var startConnectorIndex = 0; startConnectorIndex < startModule.Connectors.Count; startConnectorIndex++) { var startConnector = startModule.Connectors[startConnectorIndex]; - if (startConnector.ContaininsPoint(curve.PointAtStart)) { + if (startConnector.ContainsPoint(curve.PointAtStart)) { foreach (var endModule in modules) { if (endModule == null || !endModule.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The module is null or invalid."); @@ -81,7 +81,7 @@ protected override void SolveInstance(IGH_DataAccess DA) { } for (var endConnectorIndex = 0; endConnectorIndex < endModule.Connectors.Count; endConnectorIndex++) { var endConnector = endModule.Connectors[endConnectorIndex]; - if (endConnector.ContaininsPoint(curve.PointAtEnd) + if (endConnector.ContainsPoint(curve.PointAtEnd) && startConnector.Direction.IsOpposite(endConnector.Direction)) { rules.Add(new Rule(startModule.Name, (uint)startConnectorIndex, diff --git a/Components/RuleIndifferentConstruct.cs b/Components/RuleIndifferentConstruct.cs index a2f9f9d..6bbb96c 100644 --- a/Components/RuleIndifferentConstruct.cs +++ b/Components/RuleIndifferentConstruct.cs @@ -33,7 +33,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager) { /// protected override void RegisterOutputParams(GH_OutputParamManager pManager) { pManager.AddParameter(new RuleParameter(), - "Rule", + "Rule Indifferent", "R", "Monoceros Rule", GH_ParamAccess.item); diff --git a/Components/RuleIndifferentFromPoint.cs b/Components/RuleIndifferentFromPoint.cs index e1b9722..1f1bf58 100644 --- a/Components/RuleIndifferentFromPoint.cs +++ b/Components/RuleIndifferentFromPoint.cs @@ -35,7 +35,7 @@ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pM /// protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddParameter(new RuleParameter(), - "Rules", + "Rules Indifferent", "R", "Monoceros Rules", GH_ParamAccess.list); @@ -68,7 +68,7 @@ protected override void SolveInstance(IGH_DataAccess DA) { } for (var connectorIndex = 0; connectorIndex < module.Connectors.Count; connectorIndex++) { var connector = module.Connectors[connectorIndex]; - if (connector.ContaininsPoint(point)) { + if (connector.ContainsPoint(point)) { rules.Add(new Rule(module.Name, (uint)connectorIndex, type)); } } diff --git a/Components/RuleIndifferentUnused.cs b/Components/RuleIndifferentUnused.cs index a152c6d..92eadb2 100644 --- a/Components/RuleIndifferentUnused.cs +++ b/Components/RuleIndifferentUnused.cs @@ -37,7 +37,7 @@ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pM /// protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddParameter(new RuleParameter(), - "Rules", + "Rules Indifferent", "R", "Monoceros Rules", GH_ParamAccess.list); diff --git a/Components/RuleIsTyped.cs b/Components/RuleIsTyped.cs index 3edee5d..28e5f32 100644 --- a/Components/RuleIsTyped.cs +++ b/Components/RuleIsTyped.cs @@ -13,7 +13,11 @@ public ComponentIsRuleTyped( ) : base("Is Rule Typed", "IsRuleTyp", /// Registers all the input parameters for this component. /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { - pManager.AddParameter(new RuleParameter(), "Rule", "R", "Monoceros Rule", GH_ParamAccess.item); + pManager.AddParameter(new RuleParameter(), + "Rule", + "R", + "Monoceros Rule", + GH_ParamAccess.item); } /// diff --git a/Components/RuleOuterContruct.cs b/Components/RuleOuterContruct.cs index 55aa654..83908f4 100644 --- a/Components/RuleOuterContruct.cs +++ b/Components/RuleOuterContruct.cs @@ -21,14 +21,14 @@ public ComponentRuleOuterConstruct( ) /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddParameter(new ModuleParameter(), - "Modules", + "Module", "M", - "All available Monoceros modules", + "Monoceros Module to be placed at the envelope boundary", GH_ParamAccess.item); pManager.AddParameter(new ConnectorIndexParameter(), - "Source Connector Index", - "SC", - "Source connector number", + "Connector Index", + "C", + "Connector number to be adjacent to the envelope boundary", GH_ParamAccess.item); } diff --git a/Components/RuleOuterFromPoint.cs b/Components/RuleOuterFromPoint.cs index 851b959..cba0bce 100644 --- a/Components/RuleOuterFromPoint.cs +++ b/Components/RuleOuterFromPoint.cs @@ -27,7 +27,7 @@ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pM GH_ParamAccess.list); pManager.AddPointParameter("Point Tag", "Pt", - "Point marking a connector", + "Point marking a connector to be adjacent to the envelope boundary", GH_ParamAccess.item); } @@ -70,7 +70,7 @@ protected override void SolveInstance(IGH_DataAccess DA) { for (var connectorIndex = 0; connectorIndex < module.Connectors.Count; connectorIndex++) { var connector = module.Connectors[connectorIndex]; var oppositeDirection = connector.Direction.ToFlipped(); - if (connector.ContaininsPoint(point)) { + if (connector.ContainsPoint(point)) { rules.Add( new Rule(module.Name, (uint)connectorIndex, diff --git a/Components/RulePreview.cs b/Components/RulePreview.cs index 3996a04..035e8de 100644 --- a/Components/RulePreview.cs +++ b/Components/RulePreview.cs @@ -29,14 +29,14 @@ public ComponentPreviewRules( ) /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddParameter(new ModuleParameter(), - "Module", + "Modules", "M", - "Monoceros module for indifferent rule generation", + "Monoceros Modules", GH_ParamAccess.list); pManager.AddParameter(new RuleParameter(), "Rules", "R", - "All existing Monoceros rules", + "All existing Monoceros Rules", GH_ParamAccess.list); pManager[0].Optional = true; pManager[1].Optional = true; diff --git a/Components/RuleSuggest.cs b/Components/RuleSuggest.cs new file mode 100644 index 0000000..3e7071e --- /dev/null +++ b/Components/RuleSuggest.cs @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Grasshopper.Kernel; +using Rhino; +using Rhino.DocObjects; +using Rhino.Geometry; + +namespace Monoceros { + public class ComponentRuleGuesser : GH_Component { + public ComponentRuleGuesser( ) + : base("Suggest Rules from Geometry", + "RuleSuggest", + "Suggest Rules based on naked geometry at connectors. " + + "The two Modules described by the generated Rule can " + + "be joined or welded. Supports Curves, BReps and Meshes.", + "Monoceros", + "Rule") { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { + pManager.AddParameter(new ModuleParameter(), + "Modules", + "M", + "All available Monoceros Modules", + GH_ParamAccess.list); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { + pManager.AddParameter(new RuleParameter(), + "Rules", + "R", + "Suggested Monoceros Rules", + GH_ParamAccess.list); + pManager.AddParameter(new RuleParameter(), + "Rules Indifferent", + "RI", + "Suggested Indifferent Monoceros Rules", + GH_ParamAccess.list); + } + + /// + /// Wrap input geometry into module cages. + /// + /// The DA object can be used to retrieve data from + /// input parameters and to store data in output parameters. + protected override void SolveInstance(IGH_DataAccess DA) { + var modules = new List(); + + if (!DA.GetDataList(0, modules)) { + return; + } + + var rules = new List(); + var rulesIndifferent = new List(); + + var connectorGeometries = new List(); + + foreach (var module in modules) { + var precision = module.PartDiagonal.Length / 100; + if (module == null || !module.IsValid) { + AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The Module is null or invalid."); + continue; + } + + var allGeometry = module.Geometry.Concat(module.ReferencedGeometry); + + var nakedPolylinesBrep = allGeometry + .Where(geo => geo.HasBrepForm) + .SelectMany(geo => Brep.TryConvertBrep(geo).DuplicateNakedEdgeCurves(true, false)) + .Select(curve => curve.ToPolyline(0, 0, 0.05, 0.1, 0, precision, precision * 2, 0, true).ToPolyline()); + var nakedPolylinesMesh = allGeometry + .Where(geo => geo.ObjectType == ObjectType.Mesh) + .SelectMany(geo => ((Mesh)geo).GetNakedEdges()); + var curveEndPoints = allGeometry + .Where(geo => geo.ObjectType == ObjectType.Curve) + .Select(geo => (Curve)geo) + .Where(curve => !curve.IsPeriodic && !curve.IsClosed) + .SelectMany(curve => new Point3d[] { curve.PointAtEnd, curve.PointAtStart }); + + for (var connectorIndex = 0; connectorIndex < module.Connectors.Count; connectorIndex++) { + var connector = module.Connectors[connectorIndex]; + var transform = Transform.PlaneToPlane(connector.AnchorPlane, Plane.WorldXY); + + ConnectorGeometry connectorGeometry; + connectorGeometry.ModuleName = module.Name; + connectorGeometry.ConnectorIndex = (uint)connectorIndex; + connectorGeometry.ConnectorDirection = connector.Direction; + connectorGeometry.BrepNakedEdgePoints = new List(); + connectorGeometry.MeshNakedEdgePoints = new List(); + connectorGeometry.CurveEndPoints = new List(); + + connectorGeometry.BrepNakedEdgePoints = nakedPolylinesBrep + .Where(polyline => polyline.All(point => connector.ContainsPoint(point))) + .SelectMany(polyline => polyline.Distinct().ToArray()) + .Select(point => { + var transformedPoint = point; + transformedPoint.Transform(transform); + return transformedPoint; + }).ToList(); + connectorGeometry.BrepNakedEdgePoints.Sort(); + + connectorGeometry.MeshNakedEdgePoints = nakedPolylinesMesh + .Where(polyline => polyline.All(point => connector.ContainsPoint(point))) + .SelectMany(polyline => polyline.Distinct().ToArray()) + .Select(point => { + var transformedPoint = point; + transformedPoint.Transform(transform); + return transformedPoint; + }).ToList(); + connectorGeometry.MeshNakedEdgePoints.Sort(); + + + connectorGeometry.CurveEndPoints = curveEndPoints + .Where(point => connector.ContainsPoint(point)) + .Select(point => { + var transformedPoint = point; + transformedPoint.Transform(transform); + return transformedPoint; + }).ToList(); + + connectorGeometry.CurveEndPoints.Sort(); + + if (connectorGeometry.BrepNakedEdgePoints.Any() + || connectorGeometry.MeshNakedEdgePoints.Any() + || connectorGeometry.CurveEndPoints.Any()) { + connectorGeometries.Add(connectorGeometry); + } else { + rulesIndifferent.Add(new Rule(module.Name, (uint)connectorIndex, Config.INDIFFERENT_TAG)); + } + } + } + + foreach (var current in connectorGeometries) { + if (current.ConnectorDirection.Orientation == Orientation.Positive) { + foreach (var other in connectorGeometries) { + if (other.ConnectorDirection.IsOpposite(current.ConnectorDirection) + && ArePointListsEpsilonEqual(current.BrepNakedEdgePoints, other.BrepNakedEdgePoints) + && ArePointListsEpsilonEqual(current.MeshNakedEdgePoints, other.MeshNakedEdgePoints) + && ArePointListsEpsilonEqual(current.CurveEndPoints, other.CurveEndPoints)) { + rules.Add(new Rule(current.ModuleName, + current.ConnectorIndex, + other.ModuleName, + other.ConnectorIndex)); + } + } + } + } + + if (!rules.Any()) { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, + "Could not identify any matching naked geometry."); + } + + foreach (var rule in rules) { + if (!rule.IsValid) { + AddRuntimeMessage(GH_RuntimeMessageLevel.Error, rule.IsValidWhyNot); + } + } + + var outRules = rules.Distinct().ToList(); + outRules.Sort(); + var outIndifferentRules = rulesIndifferent.Distinct().ToList(); + outIndifferentRules.Sort(); + DA.SetDataList(0, outRules); + DA.SetDataList(1, outIndifferentRules); + } + + private static bool ArePointListsEpsilonEqual(List a, List b) { + if (a.Count != b.Count) { + return false; + } + for (var i = 0; i < a.Count; i++) { + var pointCurrent = a[i]; + var pointOther = b[i]; + if (!pointCurrent.EpsilonEquals(pointOther, RhinoMath.SqrtEpsilon)) { + return false; + } + } + return true; + } + + /// + /// The Exposure property controls where in the panel a component icon + /// will appear. There are seven possible locations (primary to + /// septenary), each of which can be combined with the + /// GH_Exposure.obscure flag, which ensures the component will only be + /// visible on panel dropdowns. + /// + public override GH_Exposure Exposure => GH_Exposure.quinary; + + /// + /// Provides an Icon for every component that will be visible in the + /// User Interface. Icons need to be 24x24 pixels. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.rule_suggest; + + /// + /// Each component must have a unique Guid to identify it. It is vital + /// this Guid doesn't change otherwise old ghx files that use the old ID + /// will partially fail during loading. + /// + public override Guid ComponentGuid => new Guid("2E45553C-62DE-4649-9D6B-F3F9A148A10E"); + } + + internal struct ConnectorGeometry { + public string ModuleName; + public uint ConnectorIndex; + public Direction ConnectorDirection; + public List BrepNakedEdgePoints; + public List MeshNakedEdgePoints; + public List CurveEndPoints; + } + +} diff --git a/Components/RuleTypedFromPoint.cs b/Components/RuleTypedFromPoint.cs index 566a97d..f6bfaef 100644 --- a/Components/RuleTypedFromPoint.cs +++ b/Components/RuleTypedFromPoint.cs @@ -85,7 +85,7 @@ protected override void SolveInstance(IGH_DataAccess DA) { } for (var connectorIndex = 0; connectorIndex < module.Connectors.Count; connectorIndex++) { var connector = module.Connectors[connectorIndex]; - if (connector.ContaininsPoint(point)) { + if (connector.ContainsPoint(point)) { rules.Add(new Rule(module.Name, (uint)connectorIndex, type)); } } diff --git a/Components/RuleUnwrap.cs b/Components/RuleUnwrap.cs index f00c4b4..45dcf46 100644 --- a/Components/RuleUnwrap.cs +++ b/Components/RuleUnwrap.cs @@ -19,14 +19,14 @@ public ComponentUnwrapRules( ) /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddParameter(new ModuleParameter(), - "Module", + "Modules", "M", - "Monoceros module for indifferent rule generation", + "All Monoceros Modules", GH_ParamAccess.list); pManager.AddParameter(new RuleParameter(), "Rules", "R", - "All Monoceros rules, including Explicit", + "All Monoceros Rules (Explicit will pass through intact)", GH_ParamAccess.list); } @@ -35,9 +35,9 @@ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pM /// protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddParameter(new RuleParameter(), - "Rules", + "Rules Explicit", "R", - "Monoceros Rules", + "Explicit Monoceros Rules", GH_ParamAccess.list); } diff --git a/Components/RulesCollect.cs b/Components/RulesCollect.cs index b1c303a..b9c0ab5 100644 --- a/Components/RulesCollect.cs +++ b/Components/RulesCollect.cs @@ -20,7 +20,7 @@ public ComponentCollectRules( ) : base("Collect Rules", /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddParameter(new ModuleParameter(), - "Module", + "Modules", "M", "All Monoceros Modules", GH_ParamAccess.list); @@ -93,10 +93,12 @@ protected override void SolveInstance(IGH_DataAccess DA) { ); modulesClean.Add(moduleOut); - var allowedClean = allowed.Where(rule => rule.IsValidWithModules(modulesClean)); + var allowedClean = allowed.Where(rule => rule.IsValidWithModules(modulesClean)).Distinct(); if (disallowed == null || !disallowed.Any()) { - DA.SetDataList(0, allowedClean); + var earlyRules = allowedClean.ToList(); + earlyRules.Sort(); + DA.SetDataList(0, earlyRules); return; } diff --git a/Components/SlotDeconstruct.cs b/Components/SlotDeconstruct.cs index 8e74277..4b6bab0 100644 --- a/Components/SlotDeconstruct.cs +++ b/Components/SlotDeconstruct.cs @@ -20,7 +20,11 @@ public ComponentDeconstructSlot( ) /// Registers all the input parameters for this component. /// protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { - pManager.AddParameter(new SlotParameter(), "Slot", "S", "Monoceros Slot", GH_ParamAccess.item); + pManager.AddParameter(new SlotParameter(), + "Slot", + "S", + "Monoceros Slot", + GH_ParamAccess.item); pManager.AddParameter(new ModuleNameParameter(), "Module Names", "MN", diff --git a/Components/SlotsAreBoundary.cs b/Components/SlotsAreBoundary.cs index 56dc458..dcbd7a4 100644 --- a/Components/SlotsAreBoundary.cs +++ b/Components/SlotsAreBoundary.cs @@ -36,7 +36,7 @@ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pM protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddBooleanParameter("Boolean Pattern", "B", - "True if the Monoceros Slot is on the boundary of the world", + "True if the Monoceros Slot is on the boundary of the envelope", GH_ParamAccess.list); } diff --git a/Monoceros.csproj b/Monoceros.csproj index dda1c49..5e6bfb0 100644 --- a/Monoceros.csproj +++ b/Monoceros.csproj @@ -57,6 +57,7 @@ + @@ -125,6 +126,7 @@ + diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index dabcf82..a24417c 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -35,5 +35,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.1.1")] -[assembly: AssemblyFileVersion("1.2.1.1")] +[assembly: AssemblyVersion("1.2.2.0")] +[assembly: AssemblyFileVersion("1.2.2.0")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 96d809a..75ff884 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -270,6 +270,16 @@ internal static System.Drawing.Bitmap rule_out { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rule_suggest { + get { + object obj = ResourceManager.GetObject("rule_suggest", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index 5fa4b14..16b87f2 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -187,6 +187,9 @@ ..\Resources\rule-out.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\rule-suggest.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\rule-typed-construct.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/Resources/rule-suggest.png b/Resources/rule-suggest.png new file mode 100644 index 0000000..3d7d5a6 Binary files /dev/null and b/Resources/rule-suggest.png differ diff --git a/Types/Module.cs b/Types/Module.cs index 638aed7..f996165 100644 --- a/Types/Module.cs +++ b/Types/Module.cs @@ -359,7 +359,7 @@ private List ComputeModuleConnectors(List partCenters, if (!isInternalXNegative) { var faceCenterXNegative = partCenter + xNegativeVectorUnit * 0.5; var planeXNegative = new Plane(faceCenterXNegative, - basePlane.YAxis * (-1), + basePlane.YAxis, basePlane.ZAxis); var faceXNegative = new Rectangle3d( planeXNegative, @@ -380,7 +380,7 @@ private List ComputeModuleConnectors(List partCenters, if (!isInternalYNegative) { var faceCenterYNegative = partCenter + yNegativeVectorUnit * 0.5; var planeYNegative = new Plane(faceCenterYNegative, - basePlane.XAxis, + basePlane.XAxis * (-1), basePlane.ZAxis); var faceYNegative = new Rectangle3d( planeYNegative, @@ -400,7 +400,7 @@ private List ComputeModuleConnectors(List partCenters, if (!isInternalZNegative) { var faceCenterZNegative = partCenter + zNegativeVectorUnit * 0.5; var planeZNegative = new Plane(faceCenterZNegative, - basePlane.XAxis * (-1), + basePlane.XAxis, basePlane.YAxis); var faceZNegative = new Rectangle3d( planeZNegative, @@ -1101,7 +1101,7 @@ public ModuleConnector(string moduleName, /// /// The point. /// True if contains. - public bool ContaininsPoint(Point3d point) { + public bool ContainsPoint(Point3d point) { return Math.Abs(AnchorPlane.DistanceTo(point)) < RhinoMath.SqrtEpsilon && Face.Contains(point) == PointContainment.Inside; } diff --git a/bin/Monoceros.pdb b/bin/Monoceros.pdb index 78263f8..ca7cbe7 100644 Binary files a/bin/Monoceros.pdb and b/bin/Monoceros.pdb differ