예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
     }
 }
예제 #4
0
파일: Game.cs 프로젝트: samuto/Rhino-Pong
 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));
 }
예제 #5
0
 //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);
                                }
                            }
                        }
                    }
                });
            }
예제 #7
0
		/// <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;
            }