/// <summary> /// Adds a particle to this ParticleSystem. A Particle can only be in one system /// at a time. If the Particle already exists in a different system, this function /// will return false. You should remove the particle from the other system first /// before adding it. /// </summary> /// <param name="particle">A particle to be added.</param> /// <returns> /// true if this particle was added to the system or if is already in the system. /// false if the particle already exists in a different system. /// </returns> public virtual bool Add(Particle particle) { ParticleSystem existing_system = particle.ParentSystem; if (existing_system == this) { return(true); // already in system } if (existing_system != null) { return(false); } particle.Index = -1; if (m_empty_slot_count > 0) { for (int i = 0; i < m_particles.Count; i++) { if (m_particles[i] == null) { m_particles[i] = particle; particle.Index = i; if (m_points.Length == m_particles.Count) { m_points[i] = particle.Location; } m_empty_slot_count--; break; } } } if (particle.Index == -1) { m_particles.Add(particle); particle.Index = m_particles.Count - 1; } if (m_bbox.IsValid) { m_bbox.Union(particle.Location); } return(true); }
public void SpreadObjects(double step, Boolean refresh) { if (myDisplayBool == null) { } else { Rhino.Display.RhinoView myViewport = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView; Rhino.Display.RhinoViewport viewport = myViewport.ActiveViewport; //viewport.DisplayMode = Rhino.Display.DisplayModeDescription.FindByName("Wireframe"); Rhino.Geometry.BoundingBox myGlobalBbox = new Rhino.Geometry.BoundingBox(); myGlobalBbox = Rhino.Geometry.BoundingBox.Empty; List <Rhino.Geometry.Point3d> myCentroids = new List <Rhino.Geometry.Point3d>(); //myCentroids.Clear(); //Rhino.Geometry.Point3d explosionCenter; // First iteration: find initial object and initial bounding box center if (originalCentroids.Count == 0 || refresh == true) { myCentroids.Clear(); foreach (Guid guid in allGuids) { RhinoObject foundObject = Rhino.RhinoDoc.ActiveDoc.Objects.Find(guid); Rhino.Geometry.BoundingBox foundBbox = foundObject.Geometry.GetBoundingBox(true); myGlobalBbox.Union(foundBbox); myCentroids.Add(foundBbox.Center); explosionCenter = myGlobalBbox.Center; } originalCentroids = myCentroids; } else { for (int i = 0; i < allGuids.Count; i++) { RhinoObject foundObject = Rhino.RhinoDoc.ActiveDoc.Objects.Find(allGuids[i]); Rhino.Geometry.Vector3d trans = explosionCenter - originalCentroids[i]; // Brings back to original position. Rhino.Geometry.Vector3d backTrans = originalCentroids[i] - foundObject.Geometry.GetBoundingBox(true).Center; trans.Unitize(); Rhino.RhinoDoc.ActiveDoc.Objects.Transform(foundObject, Rhino.Geometry.Transform.Translation(backTrans - Rhino.Geometry.Vector3d.Multiply(step, trans)), true); Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); } } } }
protected override void CalculateBoundingBoxZoomExtents(CalculateBoundingBoxEventArgs e) { Rhino.Geometry.BoundingBox bbox = Rhino.Geometry.BoundingBox.Unset; if (null != Geometry) { var localCopy = Geometry.ToList(); foreach (var obj in localCopy) { if (obj != null) { try { bbox.Union(obj.GetBoundingBox(false)); } catch { } } } e.IncludeBoundingBox(bbox); } }
private void CreateAABB() { _bounding = _bladeLeft.GetBoundingBox(false); _bounding.Union(_bladeRight.GetBoundingBox(false)); _bounding.Union(_limitBottom.GetBoundingBox(false)); _bounding.Union(_limitTop.GetBoundingBox(false)); _bounding.Union(_ball.GetBoundingBox(false)); }
//Calculate the boundingbox of all circles BoundingBox BoundingBox() { if (!m_cached_bbox.IsValid) { m_cached_bbox = Rhino.Geometry.BoundingBox.Unset; foreach (var c in m_circles) m_cached_bbox.Union(c.BoundingBox); } return m_cached_bbox; }
public VoxelGrid_RC(Environment.RhCommon_Scene ModelSurfaces, List<Point3d> Pts, int VG_Domain) { VoxelCT = VG_Domain; VoxelInventory = new List<int>[VoxelCT, VoxelCT, VoxelCT]; Voxel = new List<Point3d>[VoxelCT, VoxelCT, VoxelCT]; //for (int q = 0; q < ModelSurfaces.Objects.Count; q++) //{ // Surfaces[q] = ModelSurfaces.Objects[q].Object(); //} BoundingBox TightOBox = new BoundingBox(); Point3d BoxMin = new Point3d(); Point3d BoxMax = new Point3d(); foreach (Point3d Pt in Pts) { TightOBox.Union(Pt); } foreach (Brep B in ModelSurfaces.Breps()) { TightOBox.Union(B.GetBoundingBox(true)); } OverallBBox = new BoundingBox(new Point3d(TightOBox.Min.X - 1, TightOBox.Min.Y - 1, TightOBox.Min.Z - 1), new Point3d(TightOBox.Max.X + 1, TightOBox.Max.Y + 1, TightOBox.Max.Z + 1)); this.X_Incr = (OverallBBox.Max.X - OverallBBox.Min.X) / VoxelCT; this.Y_Incr = (OverallBBox.Max.Y - OverallBBox.Min.Y) / VoxelCT; this.Z_Incr = (OverallBBox.Max.Z - OverallBBox.Min.Z) / VoxelCT; double X_2 = X_Incr/2; double Y_2 = Y_Incr/2; double Z_2 = Z_Incr/2; Radius2 = X_2*X_2 + Y_2*Y_2 + Z_2*Z_2; //For((int XBox = 0; XBox < VoxelCT; XBox++) Parallel.For(0, VoxelCT, XBox => { Rhino.RhinoApp.SetCommandPrompt(string.Format("Voxelizing: {0}%", Math.Round((double)XBox / VoxelCT - 1, 2) * 100)); for (int YBox = 0; YBox < VoxelCT; YBox++) { for (int ZBox = 0; ZBox < VoxelCT; ZBox++) { BoxMin = new Point3d((OverallBBox.Min.X + this.X_Incr * XBox) - X_Incr / 10, (OverallBBox.Min.Y + this.Y_Incr * YBox) - Y_Incr / 10, (OverallBBox.Min.Z + this.Z_Incr * ZBox) - Z_Incr / 10); BoxMax = new Point3d((OverallBBox.Min.X + this.X_Incr * (XBox + 1)) + X_Incr / 10, (OverallBBox.Min.Y + this.Y_Incr * (YBox + 1)) + Y_Incr / 10, (OverallBBox.Min.Z + this.Z_Incr * (ZBox + 1)) + X_Incr / 10); this.Voxel[XBox, YBox, ZBox] = new List<Point3d>(); this.Voxel[XBox, YBox, ZBox].Add(BoxMin); this.Voxel[XBox, YBox, ZBox].Add(BoxMax); this.VoxelInventory[XBox, YBox, ZBox] = new List<int>(); for (int Index = 0; Index < ModelSurfaces.Count(); Index++) { BoundingBox TestBox = new BoundingBox(); TestBox = new BoundingBox(this.Voxel[XBox, YBox, ZBox][0], this.Voxel[XBox, YBox, ZBox][1]); if (BoxIntersection(ModelSurfaces, TestBox, Index)) { this.VoxelInventory[XBox, YBox, ZBox].Add(Index); } } } } }); }
/// <summary> /// Prepare the Bounding Boxes in the ModelFile /// </summary> protected virtual void PrepareBoundingBoxes() { if (ModelFile != null) { // Prepare BBoxes // Get the entire model's bounding box BBox = ModelFile.Objects.GetBoundingBox (); if (!BBox.IsValid) BBox.MakeValid (); // Calculate the layerBBoxes LayerBBoxes = new RhinoList<Rhino.Geometry.BoundingBox> (); for (int layerIndex = 0; layerIndex < Layers.Count; layerIndex++) { File3dmObject[] objsByLayer = ModelFile.Objects.FindByLayer (LayerAtIndex (layerIndex).Name); BoundingBox bbox = new BoundingBox (); foreach (File3dmObject obj in objsByLayer) { bbox.Union (obj.Geometry.GetBoundingBox (false)); } LayerBBoxes.Insert (layerIndex, bbox); } } }
/// <summary> /// This is the method that actually does the work. /// </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) { // 1. Declare placeholder variables List<Curve> struts = new List<Curve>(); string gradientString = null; double maxRadius = 0; double minRadius = 0; // 2. Attempt to fetch data inputs if (!DA.GetDataList(0, struts)) { return; } if (!DA.GetData(1, ref gradientString)) { return; } if (!DA.GetData(2, ref maxRadius)) { return; } if (!DA.GetData(3, ref minRadius)) { return; } // 3. Validate data if (struts == null || struts.Count == 0) { return; } if (maxRadius <= 0 || minRadius <= 0) { return; } // 4. Set some variables int sides = 6; // Number of sides on each strut double tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; // 5. Instantiate ExoMesh object // This constructor cleans the curve network (removes duplicates), and formats it as an ExoMesh. ExoMesh exoMesh = new ExoMesh(struts); //==================================================================================== // PART A - Compute radii // Set the start/end radii of each sleeve, based on spatial gradient. //==================================================================================== // A0. Prepare bounding box domain for normalized gradient string BoundingBox fullBox = new BoundingBox(); foreach (ExoSleeve sleeve in exoMesh.Sleeves) { var strutBox = sleeve.Curve.GetBoundingBox(Plane.WorldXY); fullBox.Union(strutBox); } double boxSizeX = fullBox.Max.X - fullBox.Min.X; double boxSizeY = fullBox.Max.Y - fullBox.Min.Y; double boxSizeZ = fullBox.Max.Z - fullBox.Min.Z; gradientString = GH_ExpressionSyntaxWriter.RewriteForEvaluator(gradientString); // A1. Set radii foreach (ExoSleeve sleeve in exoMesh.Sleeves) { // Start node ExoHull node = exoMesh.Hulls[sleeve.HullPair.I]; var parser = new Grasshopper.Kernel.Expressions.GH_ExpressionParser(); parser.AddVariable("x", (node.Point3d.X - fullBox.Min.X) / boxSizeX); parser.AddVariable("y", (node.Point3d.Y - fullBox.Min.Y) / boxSizeY); parser.AddVariable("z", (node.Point3d.Z - fullBox.Min.Z) / boxSizeZ); sleeve.StartRadius = minRadius + (parser.Evaluate(gradientString)._Double) * (maxRadius - minRadius); parser.ClearVariables(); // End node node = exoMesh.Hulls[sleeve.HullPair.J]; parser.AddVariable("x", (node.Point3d.X - fullBox.Min.X) / boxSizeX); parser.AddVariable("y", (node.Point3d.Y - fullBox.Min.Y) / boxSizeY); parser.AddVariable("z", (node.Point3d.Z - fullBox.Min.Z) / boxSizeZ); sleeve.EndRadius = minRadius + (parser.Evaluate(gradientString)._Double) * (maxRadius - minRadius); parser.ClearVariables(); } //==================================================================================== // PART B - Compute plate offsets // Each plate is offset from its parent node, to avoid mesh overlaps. // We also need to ensure that no plates are engulfed by the hulls, so we're // looking for a convex plate layout. If any plate vertex gets engulfed, meshing will fail. //==================================================================================== // B0. Loop over nodes for (int i = 0; i < exoMesh.Hulls.Count; i++) { // If node has only 1 strut, skip it if (exoMesh.Hulls[i].SleeveIndices.Count < 2) { continue; } // Compute the offsets required to avoid plate overlaps bool success = exoMesh.ComputeOffsets(i, tol); // To improve convex hull shape at 'sharp' nodes, we add an extra plate exoMesh.FixSharpNodes(i, sides); } // IDEA : add a new loop here that adjusts radii to avoid overlapping struts //==================================================================================== // PART C - Construct sleeve meshes and hull points // //==================================================================================== // C0. Loop over all sleeves for (int i = 0; i < exoMesh.Sleeves.Count; i++) { Mesh sleeveMesh = exoMesh.MakeSleeve(i, sides); // Append the new sleeve mesh to the full lattice mesh exoMesh.Mesh.Append(sleeveMesh); } //==================================================================================== // PART D - Construct hull meshes // Generates convex hulls, then removes the faces that lie on the plates. //==================================================================================== // D0. Loop over all hulls for (int i = 0; i < exoMesh.Hulls.Count; i++) { ExoHull node = exoMesh.Hulls[i]; int plateCount = exoMesh.Hulls[i].PlateIndices.Count; // If node has a single plate, create an endmesh if (plateCount < 2) { Mesh endMesh = exoMesh.MakeEndFace(i, sides); exoMesh.Mesh.Append(endMesh); } // If node has more than 1 plate, create a hullmesh else { Mesh hullMesh = exoMesh.MakeConvexHull(i, sides, tol, true); exoMesh.Mesh.Append(hullMesh); } } // 6. Post-process the final mesh. exoMesh.Mesh.Vertices.CombineIdentical(true, true); exoMesh.Mesh.FaceNormals.ComputeFaceNormals(); exoMesh.Mesh.UnifyNormals(); exoMesh.Mesh.Normals.ComputeNormals(); // 7. Set output DA.SetData(0, exoMesh.Mesh); }
/// <summary> /// If possible, calculate the volume of the room. /// </summary> /// <param name="Breps">Surfaces that make up the model.</param> /// <param name="Volume"></param> /// <param name="SurfaceArea"></param> /// <returns>True if successful.</returns> public static bool RoomVolume(List<Brep> Breps, ref double Volume, out double[] SurfaceArea) { SurfaceArea = new double[Breps.Count]; for (int x = 0; x < Breps.Count; x++) { AreaMassProperties ap = AreaMassProperties.Compute(Breps[x]); SurfaceArea[x] = ap.Area; } Brep[] Room = Brep.JoinBreps(Breps, 0.001); Rhino.RhinoApp.WriteLine("Room is not closed. Using Bounding Volume."); BoundingBox Box = new BoundingBox(); foreach (Brep srf in Breps) { Box.Union(srf.GetBoundingBox(false)); } /////////////////////////////////////////////////////////////// //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoints(Box.GetCorners()); /////////////////////////////////////////////////////////////// try { Volume = VolumeMassProperties.Compute(Box.ToBrep()).Volume; } catch { Volume = 0; } return false; }