/// <summary> /// Wrap input geometry into module cages. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from /// input parameters and to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { var slotCenters = new List <Point3d>(); var productionGeometryRaw = new List <IGH_GeometricGoo>(); var nameRaw = new ModuleName(); var basePlane = new Plane(); var slotDiagonal = new Vector3d(); if (!DA.GetData(0, ref nameRaw)) { return; } if (!DA.GetDataList(1, slotCenters)) { return; } DA.GetDataList(2, productionGeometryRaw); if (!DA.GetData(3, ref basePlane)) { return; } if (!DA.GetData(4, ref slotDiagonal)) { return; } var name = nameRaw.Name.ToLower(); if (name.Length == 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Monoceros Module name is empty."); return; } if (Config.RESERVED_CHARS.Any(chars => name.Contains(chars))) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Monoceros Module name contains " + "a forbidden content: :, ->, = or newline."); return; } if (Config.RESERVED_NAMES.Contains(name)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The Monoceros Module name cannot be \"" + name + "\" because it is reserved by Monoceros."); return; } if (!slotCenters.Any()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Failed to collect Slot Points."); return; } if (slotDiagonal.X <= 0 || slotDiagonal.Y <= 0 || slotDiagonal.Z <= 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "One or more slot dimensions are not larger than 0."); return; } // Scale down to unit size var normalizationTransform = Transform.Scale(basePlane, 1 / slotDiagonal.X, 1 / slotDiagonal.Y, 1 / slotDiagonal.Z); // Orient to the world coordinate system var worldAlignmentTransform = Transform.PlaneToPlane(basePlane, Plane.WorldXY); // Slot dimension is for the sake of this calculation 1,1,1 var partCenters = slotCenters.Select(center => { center.Transform(normalizationTransform); center.Transform(worldAlignmentTransform); return(new Point3i(center)); }).Distinct() .ToList(); var gooClean = productionGeometryRaw .Where(goo => goo != null); var productionGeometryClean = gooClean .Where(goo => !goo.IsReferencedGeometry) .Select(ghGeo => { var geo = ghGeo.Duplicate(); return(GH_Convert.ToGeometryBase(geo)); }); var productionGeometryReferencedClean = gooClean .Where(goo => goo.IsReferencedGeometry) .Select(ghGeo => { var geo = ghGeo.Duplicate(); return(GH_Convert.ToGeometryBase(geo)); }); var guidsClean = gooClean .Where(goo => goo.IsReferencedGeometry) .Select(ghGeo => ghGeo.ReferenceID); var module = new Module(name, productionGeometryClean, productionGeometryReferencedClean, guidsClean, basePlane, partCenters, slotDiagonal); if (module.Geometry.Count + module.ReferencedGeometry.Count != productionGeometryRaw.Count) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Some geometry was not used."); } if (!module.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, module.IsValidWhyNot); } DA.SetData(0, module); }