protected override void SolveInstance(IGH_DataAccess DA) { // 0.import data Autodesk.Revit.DB.Wall wall = null; Autodesk.Revit.DB.PointCloudInstance element = null; double bufferDistance = 0.30; int numPoints = 50000; if (!DA.GetData("Revit Wall", ref wall)) { return; } if (!DA.GetData("Revit Point Cloud Instance", ref element)) { return; } if (!DA.GetData("bufferDistance", ref bufferDistance)) { return; } if (!DA.GetData("numPoints", ref numPoints)) { return; } // 1.Create selection filter var width = wall.Width + bufferDistance * 2; //var width = wall.get_Parameter(BuiltInParameter.WALL_ATTR_WIDTH_PARAM).AsDouble(); //double width = UnitUtils.ConvertFromInternalUnits(wall.WallType.Width, DisplayUnitType); BoundingBoxXYZ boundingBox = wall.get_BoundingBox(null); // 2. Compute boundary U LocationCurve locationCurve_u = wall.Location as LocationCurve; XYZ endPoint0_u = locationCurve_u.Curve.GetEndPoint(0); XYZ endPoint1_u = locationCurve_u.Curve.GetEndPoint(1); var ux = endPoint1_u.X - endPoint0_u.X; var uy = endPoint1_u.Y - endPoint0_u.Y; XYZ uxy = new XYZ(ux, uy, 0); // 3. Compute boudary V XYZ midpoint = endPoint0_u + ((endPoint1_u - endPoint0_u) / 2); //var axis = Autodesk.Revit.DB.Line.CreateUnbound(midpoint, XYZ.BasisZ); //var locationCurve_v=locationCurve_u.Rotate(axis, Math.PI * 0.5); var endPoint0_v = locationCurve_u.Curve.Evaluate(locationCurve_u.Curve.Length * 0.5 - width * 0.5 * 10 - bufferDistance * 10, false); var endPoint1_v = locationCurve_u.Curve.Evaluate(locationCurve_u.Curve.Length * 0.5 + width * 0.5 * 10 + bufferDistance * 10, false); // rotate points 90° var endPoint0_v_X = (endPoint0_v.X - midpoint.X) * Math.Cos(Math.PI * 0.5) + (endPoint0_v.Y - midpoint.Y) * Math.Sin(Math.PI * 0.5) + midpoint.X; var endPoint0_v_Y = (endPoint0_v.X - midpoint.X) * -Math.Sin(Math.PI * 0.5) + (endPoint0_v.Y - midpoint.Y) * Math.Cos(Math.PI * 0.5) + midpoint.Y; var endPoint1_v_X = (endPoint1_v.X - midpoint.X) * Math.Cos(Math.PI * 0.5) + (endPoint1_v.Y - midpoint.Y) * Math.Sin(Math.PI * 0.5) + midpoint.X; var endPoint1_v_Y = (endPoint1_v.X - midpoint.X) * -Math.Sin(Math.PI * 0.5) + (endPoint1_v.Y - midpoint.Y) * Math.Cos(Math.PI * 0.5) + midpoint.Y; XYZ boundary0_v = new XYZ(endPoint0_v_X, endPoint0_v_Y, 0); XYZ boundary1_v = new XYZ(endPoint1_v_X, endPoint1_v_Y, 0); //XYZ endPoint0_v = locationCurve_u.Curve.GetEndPoint(0); //XYZ endPoint1_v = locationCurve_u.Curve.GetEndPoint(1); var vx = boundary1_v.X - boundary0_v.X; var vy = boundary1_v.Y - boundary0_v.Y; XYZ vxy = new XYZ(vx, vy, 0); // 4. Create boundary planes List <Autodesk.Revit.DB.Plane> planes = new List <Autodesk.Revit.DB.Plane>(); // U boundaries planes.Add(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(uxy, endPoint0_u)); planes.Add(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(-uxy, endPoint1_u)); // V boundaries planes.Add(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(vxy, boundary0_v)); planes.Add(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(-vxy, boundary1_v)); // Z boundaries planes.Add(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(XYZ.BasisZ, boundingBox.Min)); planes.Add(Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(-XYZ.BasisZ, boundingBox.Max)); // Create filter PointCloudFilter filter = PointCloudFilterFactory.CreateMultiPlaneFilter(planes); // 5.Fetch point cloud PointCollection cloudPoints = element.GetPoints(filter, bufferDistance, numPoints); PointCloud Rh_pointCloud = new PointCloud(); // 6.Convert CloudPoints to rhino point cloud if (element.HasColor()) { foreach (CloudPoint point in cloudPoints) { // Process each point Point3d point3d = new Point3d(point.X * 1000, point.Y * 1000, point.Z * 1000); byte[] bArray = BitConverter.GetBytes(point.Color); var color = System.Drawing.Color.FromArgb(bArray[0], bArray[1], bArray[2]); Rh_pointCloud.Add(point3d, color); } } else { foreach (CloudPoint point in cloudPoints) { // Process each point Point3d point3d = new Point3d(point.X * 1000, point.Y * 1000, point.Z * 1000); Rh_pointCloud.Add(point3d); } } // 7.Return Grasshopper Cloud GH_Cloud GH_pointCloud = new GH_Cloud(Rh_pointCloud); DA.SetData(0, GH_pointCloud); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Selection sel = uidoc.Selection; try { if (uidoc.ActiveView is View3D == false) { message = "Você deve estar em uma vista 3d para utilizar este comando. Por favor, entre em uma vista compatível e rode o comando novamente."; return(Result.Failed); } PointCloudInstance pcInstance = doc.GetElement(sel.PickObject(ObjectType.Element, new PointCloundSelectionFilter(), "Por favor, selecione uma nuvem de pontos")) as PointCloudInstance; if (pcInstance == null) { message = "Objeto inválido selecionado. Este comando funciona somente com instancias de nuvem de pontos, por favor, rode o comando novamente e selecione uma nuvem de pontos."; return(Result.Failed); } View3D this3dView = uidoc.ActiveView as View3D; BoundingBoxXYZ boundingBox = null; //Use CropBox if there is one to use if (this3dView.CropBoxActive == true) { boundingBox = this3dView.CropBox; } else { boundingBox = pcInstance.get_BoundingBox(uidoc.ActiveView); } List <Plane> planes = new List <Plane>(); XYZ midpoint = (boundingBox.Min + boundingBox.Max) / 2.0; #if R2016 // X boundaries planes.Add(new Plane(XYZ.BasisX, boundingBox.Min)); planes.Add(new Plane(-XYZ.BasisX, boundingBox.Max)); // Y boundaries planes.Add(new Plane(XYZ.BasisY, boundingBox.Min)); planes.Add(new Plane(-XYZ.BasisY, boundingBox.Max)); // Z boundaries planes.Add(new Plane(XYZ.BasisZ, boundingBox.Min)); planes.Add(new Plane(-XYZ.BasisZ, boundingBox.Max)); #else // X boundaries planes.Add(Plane.CreateByNormalAndOrigin(XYZ.BasisX, boundingBox.Min)); planes.Add(Plane.CreateByNormalAndOrigin(-XYZ.BasisX, boundingBox.Max)); // Y boundaries planes.Add(Plane.CreateByNormalAndOrigin(XYZ.BasisY, boundingBox.Min)); planes.Add(Plane.CreateByNormalAndOrigin(-XYZ.BasisY, boundingBox.Max)); // Z boundaries planes.Add(Plane.CreateByNormalAndOrigin(XYZ.BasisZ, boundingBox.Min)); planes.Add(Plane.CreateByNormalAndOrigin(-XYZ.BasisZ, boundingBox.Max)); #endif using (Transaction t = new Transaction(doc, "Criar Topografia")) { t.Start(); // Create filter PointCloudFilter pcFilter = PointCloudFilterFactory.CreateMultiPlaneFilter(planes); pcInstance.FilterAction = SelectionFilterAction.Highlight; PointCollection pcColection = pcInstance.GetPoints(pcFilter, pointDistance, pointMaxQuantity); IList <XYZ> pcPoints = new List <XYZ>(); XYZ origin = pcInstance.GetTotalTransform().Origin; if (pcColection.Count < 3) { t.RollBack(); message = "Número de pontos insuficiente para criar a topografia. Por favor utilize outra nuvem de pontos."; return(Result.Failed); } foreach (XYZ currentPoint in pcColection) { XYZ pointCopy = new XYZ(currentPoint.X, currentPoint.Y, currentPoint.Z); pointCopy = pcInstance.GetTotalTransform().OfPoint(pointCopy); if (!ListContainsPoint(pcPoints, pointCopy)) { pcPoints.Add(pointCopy); } } TopographySurface topoSurface = TopographySurface.Create(doc, pcPoints); t.Commit(); } } catch (Exception excep) { ExceptionManager eManager = new ExceptionManager(excep); return(Result.Cancelled); } return(Result.Succeeded); }