Example #1
0
        public static void AddBranchToObj(ref Obj obj, CBranch pBranch)
        {
            for (int i = 0; i < pBranch.TreePoints.Count; i++)
            {
                //for first point in branch use peak as a first point
                Vector3 p = i == 0 ? pBranch.tree.peak.Center : pBranch.TreePoints[i - 1].Center;
                //for first point set first point to connect to peak
                Vector3 nextP = i == 0 ? pBranch.TreePoints[0].Center : pBranch.TreePoints[i].Center;

                AddLineToObj(ref obj, p, nextP);
            }
        }
Example #2
0
        /// <summary>
        /// First finds most defined branch of pOtherTree.
        /// Then finds the branch on this reference tree which best matches found most defined branch.
        /// Returns index offset between these branches.
        /// </summary>
        private static int GetIndexOffsetBetweenBestMatchBranches(CRefTree pRefTree, CTree pOtherTree)
        {
            CBranch mostDefinedBranch = pOtherTree.GetMostDefinedBranch();

            CBranch bestMatchBranch = GetBestMatchBranch(pRefTree, mostDefinedBranch);

            int indexOfMostDefined = pOtherTree.Branches.IndexOf(mostDefinedBranch);
            int indexOfBestMatch   = pRefTree.Branches.IndexOf(bestMatchBranch);
            int indexOffset        = indexOfBestMatch - indexOfMostDefined;

            return(indexOffset);
        }
Example #3
0
        /// <summary>
        /// Calculates similarity between this reference tree and given tree
        /// Returns [0,1]. 1 = best match
        /// </summary>
        public static STreeSimilarity GetSimilarityWith(CRefTree pRefTree, CTree pOtherTree)
        {
            Vector3   offsetToRefTree = GetOffsetTo(pOtherTree, pRefTree);
            float     scaleRatio      = GetScaleRatioTo(pOtherTree, pRefTree);
            Matrix4x4 scaleMatrix     = Matrix4x4.CreateScale(scaleRatio, scaleRatio, scaleRatio, pRefTree.peak.Center);
            int       indexOffset     = GetIndexOffsetBetweenBestMatchBranches(pRefTree, pOtherTree);

            float similarity             = 0;
            int   definedSimilarityCount = 0;

            foreach (CBranch otherBranch in pOtherTree.Branches)
            {
                int indexOfOtherBranch = pOtherTree.Branches.IndexOf(otherBranch);
                //int offsetBranchIndex = (indexOfOtherBranch + indexOffset) % branches.Count;
                int offsetBranchIndex = indexOfOtherBranch + indexOffset;
                if (offsetBranchIndex < 0)
                {
                    offsetBranchIndex = pRefTree.Branches.Count + offsetBranchIndex;
                }
                CBranch refBranch = pRefTree.Branches[offsetBranchIndex % pRefTree.Branches.Count];
                float   similarityWithOtherBranch = refBranch.GetSimilarityWith(otherBranch, offsetToRefTree, scaleMatrix);
                if (similarityWithOtherBranch >= 0)
                {
                    similarity += similarityWithOtherBranch;
                    definedSimilarityCount++;
                }
            }
            //CDebug.WriteLine("\n---------------\nsimilarity of \n" + pRefTree + "\nwith \n" + pOtherTree);

            if (definedSimilarityCount == 0)
            {
                CDebug.WriteLine("Error. no similarity defined");
                return(new STreeSimilarity(0, 0));
            }
            similarity /= definedSimilarityCount;

            //CDebug.WriteLine("similarity = " + similarity + ". defined = " + definedSimilarityCount + "\n--------");

            return(new STreeSimilarity(similarity, indexOffset * CTree.BRANCH_ANGLE_STEP));
        }
Example #4
0
        /// <summary>
        /// Calculates similarity with other branch.
        /// Range = [0,1]. 1 = Best match.
        /// </summary>
        public float GetSimilarityWith(CBranch pOtherBranch, Vector3 offsetToThisTree, Matrix4x4 scaleMatrix)
        {
            if (pOtherBranch.TreePoints.Count == 0)
            {
                if (TreePoints.Count == 0)
                {
                    return(1);
                }
                //situation when other branch has no points.
                //this can mean that data in this part of tree are just missing therefore it should
                return(UNDEFINED_SIMILARITY);
            }

            float similarity = 0;

            //CreateRotationY rotates point counter-clockwise => -pAngleOffset
            //rotation has to be calculated in each branch
            float     angleOffsetRadians = CUtils.ToRadians(-(angleFrom - pOtherBranch.angleFrom));
            Matrix4x4 rotationMatrix     = Matrix4x4.CreateRotationY(angleOffsetRadians, tree.peak.Center);

            foreach (CTreePoint p in pOtherBranch.TreePoints)
            {
                Vector3 movedPoint   = p.Center + offsetToThisTree;
                Vector3 scaledPoint  = Vector3.Transform(movedPoint, scaleMatrix);
                Vector3 rotatedPoint = Vector3.Transform(scaledPoint, rotationMatrix);

                const int branchToleranceMultiply = 2;
                if (Contains(rotatedPoint, branchToleranceMultiply))
                {
                    similarity += 1f / pOtherBranch.TreePoints.Count;
                }
            }
            if (similarity - 1 > 0.1f)            //similarity can be > 1 due to float imprecision
            {
                CDebug.Error("Similarity rounding error too big. " + similarity);
            }
            similarity = Math.Min(1, similarity);
            return(similarity);
        }
Example #5
0
        /// <summary>
        /// Is point closer than the "furthestPoint" of this or one
        /// of neighbouring branches
        /// </summary>
        public bool IsPointInExtent(Vector3 pPoint)
        {
            float   pointDistToPeak    = CUtils.Get2DDistance(pPoint, tree.peak);
            bool    thisBranchInExtent = furthestPointDistance > pointDistToPeak;
            Vector3 closestPoint       = GetClosestPointTo(pPoint);
            float   distToClosestPoint = Vector3.Distance(pPoint, closestPoint);

            if (thisBranchInExtent && distToClosestPoint < 1)
            {
                return(true);
            }

            CBranch branch1            = GetNeigbourBranch(-1);
            float   dist1              = branch1.furthestPointDistance;
            bool    leftBranchInExtent = dist1 > pointDistToPeak;
            float   distToLeftPoint    = CUtils.Get2DDistance(pPoint, branch1.furthestPoint);
            //restrict only to points close to the furthest point.
            //for too large branches it was including points way too far
            bool leftBranchPointClose = distToLeftPoint < 1;

            if (leftBranchInExtent && leftBranchPointClose)
            {
                return(true);
            }

            CBranch branch2               = GetNeigbourBranch(1);
            float   dist2                 = branch2.furthestPointDistance;
            bool    rightBranchInExtent   = dist2 > pointDistToPeak;
            float   distToRightPoint      = CUtils.Get2DDistance(pPoint, branch2.furthestPoint);
            bool    rightBranchPointClose = distToRightPoint < 1;

            if (rightBranchInExtent && rightBranchPointClose)
            {
                return(true);
            }

            return(false);
        }
Example #6
0
        /// <summary>
        /// Returns branch with the highest similarity with other branch
        /// </summary>
        private static CBranch GetBestMatchBranch(CRefTree pRefTree, CBranch pOtherBranch)
        {
            Vector3   offsetToRefTree = GetOffsetTo(pOtherBranch.tree, pRefTree);
            float     scaleRatio      = GetScaleRatioTo(pOtherBranch.tree, pRefTree);
            Matrix4x4 scaleMatrix     = Matrix4x4.CreateScale(scaleRatio, scaleRatio, scaleRatio, pRefTree.peak.Center);

            //CDebug.WriteLine("offsetToRefTree = " + offsetToRefTree);
            //CDebug.WriteLine("scaleRatio = " + scaleRatio);

            float   bestSimilarity  = 0;
            CBranch bestMatchBranch = pRefTree.Branches[0];

            foreach (CBranch b in pRefTree.Branches)
            {
                float similarity = b.GetSimilarityWith(pOtherBranch, offsetToRefTree, scaleMatrix);
                if (similarity > bestSimilarity)
                {
                    bestSimilarity  = similarity;
                    bestMatchBranch = b;
                }
            }
            //CDebug.WriteLine(bestSimilarity + " GetBestMatchBranch = " + bestMatchBranch);
            return(bestMatchBranch);
        }
Example #7
0
        public CRefTree(string pFileName, string[] pSerializedLines)
        {
            DeserialiseMode currentMode = DeserialiseMode.None;

            fileName = pFileName;
            isValid  = true;

            branches = new List <CBranch>();
            List <CTreePoint> _treepointsOnBranch = new List <CTreePoint>();

            //if first line is not version then it is the old version and
            //the file needs to be regenerated
            if (pSerializedLines.Length == 0 || pSerializedLines[0] != KEY_VERSION)
            {
                return;
            }

            foreach (string line in pSerializedLines)
            {
                switch (line)
                {
                case KEY_VERSION:
                    currentMode = DeserialiseMode.Version;
                    continue;

                case KEY_TREE_INDEX:
                    currentMode = DeserialiseMode.TreeIndex;
                    continue;

                case KEY_TREE_POINT_EXTENT:
                    currentMode = DeserialiseMode.TreePointExtent;
                    continue;

                case KEY_PEAK:
                    currentMode = DeserialiseMode.Peak;
                    continue;

                case KEY_BRANCHES:
                    currentMode = DeserialiseMode.Branches;
                    continue;

                case KEY_STEM:
                    currentMode = DeserialiseMode.Stem;
                    branches.Last().SetTreePoints(_treepointsOnBranch);
                    _treepointsOnBranch = new List <CTreePoint>();
                    continue;

                case KEY_BOUNDING_BOX:
                    currentMode = DeserialiseMode.BoundingBox;
                    continue;
                }

                switch (currentMode)
                {
                case DeserialiseMode.Version:
                    version = line;
                    if (!IsCurrentVersion())
                    {
                        CDebug.Warning($"reftree version {version} is not up to date {CURRENT_REFTREE_VERSION}. Generating new file.");
                        return;
                    }
                    break;

                case DeserialiseMode.TreeIndex:
                    treeIndex = int.Parse(line);
                    break;

                case DeserialiseMode.TreePointExtent:
                    treePointExtent = float.Parse(line);
                    break;

                case DeserialiseMode.Peak:
                    peak = CPeak.Deserialize(line, treePointExtent);
                    stem = new CBranch(this, 0, 0);
                    break;

                case DeserialiseMode.Branches:
                    if (line.Contains(KEY_BRANCH))
                    {
                        int branchIndex = branches.Count;
                        if (branchIndex > 0)
                        {
                            branches.Last().SetTreePoints(_treepointsOnBranch);
                        }

                        branches.Add(new CBranch(
                                         this,
                                         branchIndex * BRANCH_ANGLE_STEP,
                                         branchIndex * BRANCH_ANGLE_STEP + BRANCH_ANGLE_STEP));
                        _treepointsOnBranch = new List <CTreePoint>();
                    }
                    else
                    {
                        CTreePoint treePointOnBranch = CTreePoint.Deserialize(line, treePointExtent);
                        _treepointsOnBranch.Add(treePointOnBranch);
                        Points.Add(treePointOnBranch.Center);
                    }
                    break;

                case DeserialiseMode.Stem:
                    _treepointsOnBranch.Add(CTreePoint.Deserialize(line, treePointExtent));
                    break;

                case DeserialiseMode.BoundingBox:
                    string[] split = line.Split(null);
                    minBB = new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2]));
                    maxBB = new Vector3(float.Parse(split[3]), float.Parse(split[4]), float.Parse(split[5]));
                    break;
                }
            }
            stem.SetTreePoints(_treepointsOnBranch);
            LoadObj(pFileName);
        }