Пример #1
0
        private TVGLConvexHull CreateCombinedConvexHull(TVGLConvexHull refCVXHull, TVGLConvexHull movingCVXHull)
        {
            var pointCloud = new List <Vertex>(refCVXHull.Vertices);

            pointCloud.AddRange(movingCVXHull.Vertices);
            return(new TVGLConvexHull(pointCloud, 1e-8));
        }
Пример #2
0
        public SubAssembly(Part refAssembly, Part movingAssembly, TVGLConvexHull combinedCVXHull,
                           InstallCharacterType InstallCharacter, List <PolygonalFace> refFacesInCombined)
        {
            PartNames = new List <string>(refAssembly.PartNames);
            PartNames.AddRange(movingAssembly.PartNames);
            Name    = "subasm-" + PartNames.Aggregate((i, j) => i + "," + j);
            Install = new InstallAction {
                Reference = refAssembly, Moving = movingAssembly
            };
            InstallModelInputs    = new double[1, 6];
            Secure                = new SecureAction();
            Rotate                = new RotateAction();
            RotateModelInputs     = new double[1, 5];
            MoveRoate             = new MoveRotateAction();
            MoveRoateModelInputs  = new double[1, 5];
            this.InstallCharacter = InstallCharacter;
            Mass   = refAssembly.Mass + movingAssembly.Mass;
            Volume = refAssembly.Volume + movingAssembly.Volume;
            //volume of sphere = (4/3)*Math.Pi*r*r*r
            var radius = Math.Pow(0.75 * Volume / Math.PI, 1.0 / 3.0);

            AvgMomentofInertia                = Mass * radius * radius;
            CVXHull                           = combinedCVXHull;
            this.refFacesInCombined           = refFacesInCombined;
            InternalStabilityInfo             = new InternalStability();
            InternalStabilityInfo.needfixture = false;
        }
Пример #3
0
        public SubAssembly(HashSet <Component> nodes, TVGLConvexHull combinedCVXHull,
                           double Mass, double Volume, Vertex centerOfMass)
        {
            PartNames   = nodes.Select(n => n.name).ToList();
            Name        = Name = "subasm-" + PartNames.Aggregate((i, j) => i + "," + j);
            this.Mass   = Mass;
            this.Volume = Volume;
            //volume of sphere = (4/3)*Math.Pi*r*r*r
            var radius = Math.Pow(0.75 * Volume / Math.PI, 1.0 / 3.0);

            AvgMomentofInertia = Mass * radius * radius;
            CVXHull            = combinedCVXHull;
            CenterOfMass       = centerOfMass;
        }
Пример #4
0
        public Part(string name, double mass, double volume, TVGLConvexHull convexHull, Vertex centerOfMass)
        {
            Name      = name;
            PartNames = new List <string>();
            PartNames.Add(name);
            Mass   = mass;
            Volume = volume;
            //volume of sphere = (4/3)*Math.Pi*r*r*r
            var radius = Math.Pow(0.75 * volume / Math.PI, 1.0 / 3.0);

            AvgMomentofInertia = mass * radius * radius;
            CVXHull            = convexHull;

            /*var com = new Vector(0, 0, 0);
             * // find install direction by averaging all visible_DOF
             * if (convexHull!=null)
             *  foreach (var pt in convexHull.Vertices)
             *      com.AddInPlace(pt);*/
            //CenterOfMass = new Vertex(StarMath.divide(com.Position, convexHull.Points.Count(), 3));
            CenterOfMass = centerOfMass;
        }
Пример #5
0
        private InstallCharacterType shouldReferenceAndMovingBeSwitched(Part refAssembly, Part movingAssembly,
                                                                        TVGLConvexHull combinedCVXHull,
                                                                        out List <PolygonalFace> refFacesInCombined,
                                                                        out List <PolygonalFace> movingFacesInCombined)
        {
            /* first, create a list of vertices from the reference hull that are present in the combined hull.
             * likewise, with the moving. */
            var refVertsInCombined    = new List <Vertex>();
            var movingVertsInCombined = new List <Vertex>();

            foreach (var pt in combinedCVXHull.Vertices)
            {
                if (refAssembly.CVXHull.Vertices.Contains(pt))
                {
                    refVertsInCombined.Add(pt);
                }
                else
                {
                    /* this additional Contains function is unnecessary and potential time-consuming.
                     * It was implemented for initial validiation, but it is commented out now.
                     * if (!movingAssembly.CVXHull.Points.Contains(pt))
                     *  throw new Exception("The point is in neither original part!");  */
                    movingVertsInCombined.Add(pt);
                }
            }
            /* If none of the combined vertices are from the moving, we can end this function early and save time. */
            if (movingVertsInCombined.Count == 0)
            {
                movingFacesInCombined = null;
                refFacesInCombined    = new List <PolygonalFace>(combinedCVXHull.Faces);
                return(InstallCharacterType.MovingIsInsideReference);
            }
            /* ...likewise for the original reference */
            if (refVertsInCombined.Count == 0)
            {
                refFacesInCombined    = null;
                movingFacesInCombined = new List <PolygonalFace>(combinedCVXHull.Faces);
                return(InstallCharacterType.ReferenceIsInsideMoving);
            }

            /* we could just count the number of vertices, but that would not be as accurate a prediction
             * as the area of the faces */
            refFacesInCombined    = new List <PolygonalFace>();
            movingFacesInCombined = new List <PolygonalFace>();
            double refFaceArea    = 0.0;
            var    movingFaceArea = 0.0;
            var    totalFaceArea  = 0.0;

            foreach (var face in combinedCVXHull.Faces)
            {
                var faceArea = findFaceArea(face);
                totalFaceArea += faceArea;
                if (face.Vertices.All(v => refAssembly.CVXHull.Vertices.Contains(v)))
                {
                    refFacesInCombined.Add(face);
                    refFaceArea += faceArea;
                }
                else if (face.Vertices.All(v => movingAssembly.CVXHull.Vertices.Contains(v)))
                {
                    movingFacesInCombined.Add(face);
                    movingFaceArea += faceArea;
                }
            }
            /* former faces is the sum areas of faces from prior cvx hulls */
            var formerFacesArea = refFaceArea + movingFaceArea;

            /* if the former face area does not take up a significant portion of
             * the new faces then we do not have the confidence to make the judgement
             * based on this fact. */
            if (formerFacesArea / totalFaceArea > Constants.CVXFormerFaceConfidence)
            {
                /* there are two check here: if the common area is very small, we assume the
                 * subassembly is inside the other. If not, maybe it is more on the outside
                 * but a smaller effect on resulting convex hull. */
                if (refFaceArea / formerFacesArea < Constants.CVXOnInsideThreshold)
                {
                    return(InstallCharacterType.ReferenceIsInsideMoving);
                }
                if (movingFaceArea / formerFacesArea < Constants.CVXOnInsideThreshold)
                {
                    return(InstallCharacterType.MovingIsInsideReference);
                }
                if (refFaceArea / formerFacesArea < Constants.CVXOnOutsideThreshold)
                {
                    return(InstallCharacterType.ReferenceIsOnOutsideOfMoving);
                }
                if (movingFaceArea / formerFacesArea < Constants.CVXOnOutsideThreshold)
                {
                    return(InstallCharacterType.MovingIsOnOutsideOfReference);
                }
            }

            /* if we cannot confidently use face area then we switch to comparing
             * the magnitudes of the moment of inertia. */
            else
            {
                if (refAssembly.AvgMomentofInertia >= movingAssembly.AvgMomentofInertia)
                {
                    return(InstallCharacterType.MovingReferenceSimiliar);
                }
                else
                {
                    return(InstallCharacterType.ReferenceMovingSimiliarSwitch);
                }
            }
            /* this will not be invoked, but it is left as a final result in case these heuristic cases should change. */
            return(InstallCharacterType.Unknown);
        }
Пример #6
0
        public SubAssembly Update(option opt, List <Component> rest, Dictionary <string, TVGLConvexHull> convexHullForParts)
        {
            Part refAssembly, movingAssembly;
            //if (ActionIsAssemblyByAssembly())
            //{
            //    //var node0 = (Component)opt.nodes[0];
            //    //var node1 = (Component)opt.nodes[1];
            //    //var node0name = node0.name;
            //    //var node1name = node1.name;
            //    //refAssembly = Subassemblies.FirstOrDefault(subasm => subasm.PartNames.Contains(node0name));
            //    //if (refAssembly == null)
            //    //    refAssembly = new Part(node0name, GetPartMass(node0), GetPartVolume(node0),
            //    //        convexHullForParts[node0name], GetPartCenterOfMass(node0));
            //    //else Subassemblies.Remove((SubAssembly) refAssembly);
            //    //movingAssembly = Subassemblies.FirstOrDefault(subasm => subasm.PartNames.Contains(node1name));
            //    //if (movingAssembly == null)
            //    //    movingAssembly = new Part(node1name, GetPartMass(node1), GetPartVolume(node1),
            //    //        convexHullForParts[node1name], GetPartCenterOfMass(node0));
            //    //else Subassemblies.Remove((SubAssembly) movingAssembly);
            //}
            //else if (ActionIsRemoveSCC())
            //{
            var movingNodes    = opt.Nodes.Cast <Component>().ToList();
            var newSubAsmNodes = rest;

            if (movingNodes.Count == 1)
            {
                var nodeName = movingNodes[0].name;
                movingAssembly = new Part(nodeName,
                                          GetPartMass(movingNodes[0]), GetPartVolume(movingNodes[0]),
                                          convexHullForParts[nodeName], GetPartCenterOfMass(movingNodes[0]));
            }
            else
            {
                var combinedCVXHullM = CreateCombinedConvexHull2(movingNodes, convexHullForParts);
                var VolumeM          = GetSubassemblyVolume(movingNodes);
                var MassM            = GetSubassemblyMass(movingNodes);
                var centerOfMass     = GetSubassemblyCenterOfMass(movingNodes);
                movingAssembly = new SubAssembly(new HashSet <Component>(movingNodes), combinedCVXHullM, MassM, VolumeM, centerOfMass);
            }

            var referenceHyperArcnodes = new List <Component>();

            referenceHyperArcnodes = newSubAsmNodes.Where(a => !movingNodes.Contains(a)).ToList();
            if (referenceHyperArcnodes.Count == 1)
            {
                var nodeName = referenceHyperArcnodes[0].name;
                refAssembly = new Part(nodeName,
                                       GetPartMass(referenceHyperArcnodes[0]), GetPartVolume(referenceHyperArcnodes[0]),
                                       convexHullForParts[nodeName], GetPartCenterOfMass(referenceHyperArcnodes[0]));
            }
            else
            {
                var combinedCVXHullR = CreateCombinedConvexHull2(referenceHyperArcnodes, convexHullForParts);
                var VolumeR          = GetSubassemblyVolume(referenceHyperArcnodes);
                var MassR            = GetSubassemblyMass(referenceHyperArcnodes);
                var centerOfMass     = GetSubassemblyCenterOfMass(referenceHyperArcnodes);
                refAssembly = new SubAssembly(new HashSet <Component>(referenceHyperArcnodes), combinedCVXHullR, MassR, VolumeR, centerOfMass);
            }
            //}
            //else throw new Exception("Only install rules in assembly at this point.");
            TVGLConvexHull combinedCVXHull = CreateCombinedConvexHull(
                refAssembly.CVXHull, movingAssembly.CVXHull);
            //List<PolygonalFace> refFacesInCombined, movingFacesInCombined;
            var InstallCharacter = shouldReferenceAndMovingBeSwitched(refAssembly, movingAssembly, combinedCVXHull,
                                                                      out refFacesInCombined, out movingFacesInCombined);

            if ((int)InstallCharacter < 0)
            {
                var tempASM = refAssembly;
                refAssembly        = movingAssembly;
                movingAssembly     = tempASM;
                refFacesInCombined = movingFacesInCombined; // no need to use temp here, as the movingFaces in the
                // combined convex hull are not needed.
                InstallCharacter = (InstallCharacterType)(-((int)InstallCharacter));
            }
            string refName        = NameMaker(refAssembly);
            string movName        = NameMaker(movingAssembly);
            var    newSubassembly = new SubAssembly(refAssembly, movingAssembly, combinedCVXHull, InstallCharacter,
                                                    refFacesInCombined);

            //newSubassembly.Name = refName +"   on   "+movName;
            newSubassembly.CenterOfMass = CombinedCenterOfMass(newSubassembly);
            // instead of adding to Subassemblies, newSubassembly must be added to its preceeding subassembly (to its parent)
            Subassemblies.Add(newSubassembly);
            return(newSubassembly);
        }