示例#1
0
        /**
         * Make a clone of the stem at this position
         *
         * @param trf The base transformation for the clone
         * @param start_segm Start segment number, i.e. the height, where
         *        the clone spreads out
         * @return The clone stem object
         */

        CS_StemImpl make_clone(DX_Transformation trf, int start_segm)
        {
            // creates a clone stem with same atributes as this stem
            CS_StemImpl clone = new CS_StemImpl(tree, this, stemlevel, trf, offset);

            clone.segmentLength   = segmentLength;
            clone.segmentCount    = segmentCount;
            clone.length          = length;
            clone.baseRadius      = baseRadius;
            clone.splitCorrection = splitCorrection;
            clone.pruneTest       = pruneTest;
            clone.index           = index;

            //DBG("Stem.clone(): clone_index "+clone_index);
            clone.cloneIndex.AddRange(cloneIndex);

            //DBG("Stem.clone(): level: "+stemlevel+" clones "+clones);
            clone.cloneIndex.Add(clones.Count);
            if (!pruneTest)
            {
                clone.lengthChildMax = lengthChildMax;
                //clone.substem_cnt = substem_cnt;
                clone.substemsPerSegment = substemsPerSegment;
                //clone.substemdist = substemdist;
                //clone.substemdistv = substemdistv;
                //clone.seg_splits = self.seg_splits
                // FIXME: for more then one clone this angle should somehow
                // correspond to the rotation angle of the clone
                clone.substemRotangle  = substemRotangle + 180;
                clone.leavesPerSegment = leavesPerSegment;
            }
            return(clone);
        }
示例#2
0
        /* (non-Javadoc)
         * @see net.sourceforge.arbaro.tree.TraversableStem#getTreePosition()
         */
        public override String getTreePosition()
        {
            // returns the position of the stem in the tree as a string, e.g. 0c0.1
            // for the second substem of the first clone of the trunk
            CS_StemImpl stem = this;
            int         lev  = stemlevel;
            String      pos  = "";

            while (lev >= 0)
            {
                if (stem.cloneIndex.Count > 0)
                {
                    String clonestr = "";
                    for (int i = 0; i < stem.cloneIndex.Count; i++)
                    {
                        clonestr += "c" + ((int)stem.cloneIndex[i]).ToString();
                    }
                    pos = "" + stem.index + clonestr + "." + pos;
                }
                else
                {
                    pos = "" + stem.index + "." + pos;
                }
                if (lev > 0)
                {
                    stem = stem.parent;
                }
                lev--;
            }
            if (pos[pos.Length - 1] == '.')
            {
                pos = pos.Substring(0, pos.Length - 1);
            }
            return(pos);
        }
示例#3
0
        /**
         * Sets (i.e. calcs) the progress for the process of making the tree
         * object.
         */
        //long genProgress;

        // TODO ! synchronized
        //public synchronized void updateGenProgress() {
        public void updateGenProgress()
        {
            try
            {
                // how much of 0Branches*0CurveRes*(1Branches+1) are created yet
                long sum = 0;
                for (int i = 0; i < trunks.Count; i++)
                {
                    CS_StemImpl trunk = ((CS_StemImpl)trunks[i]);
                    if (trunk.substems != null)
                    {
                        sum += trunk.segments.Count * (trunk.substems.Count + 1);
                    }
                    else
                    {
                        sum += trunk.segments.Count;
                    }
                }

                // TODO Progress

                /*
                 * if (sum-genProgress > progress.getMaxProgress()/100) {
                 *  genProgress = sum;
                 *  progress.setProgress(genProgress);
                 * }*/
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
示例#4
0
        /**
         * Creates a new stem
         *
         * @param tr the tree object
         * @param params the general tree parameters
         * @param lparams the parameters for the stem level
         * @param parnt the parent stem, from wich the stems grows out
         * @param stlev the stem level
         * @param trf the base transformation of the stem
         * @param offs the offset of ste stem within the parent stem (0..1)
         */
        public CS_StemImpl(CS_TreeImpl tr, CS_StemImpl growsOutOf, int stlev,
                           DX_Transformation trf, float offs) /* offs=0 */
        {
            tree      = tr;
            stemlevel = stlev;
            transf    = trf;
            offset    = offs;

            if (growsOutOf != null)
            {
                if (growsOutOf.stemlevel < stemlevel)
                {
                    parent = growsOutOf;
                }
                else
                {
                    clonedFrom = growsOutOf;
                    parent     = growsOutOf.parent;
                }
            }

            par  = tree.csparams;
            lpar = par.getLevelParams(stemlevel);

            // initialize lists
            segments = new List <CS_SegmentImpl>(lpar.nCurveRes);

            if (lpar.nSegSplits > 0 || par._0BaseSplits > 0)
            {
                clones = new List <CS_StemImpl>();        // lpar.nSegSplits*lpar.nCurveRes+1);
            }

            if (stemlevel < par.Levels - 1)
            {
                CS_LevelParams lpar_1 = par.getLevelParams(lpar.level + 1);
                substems = new List <CS_StemImpl>(lpar_1.nBranches);
            }

            if (stemlevel == par.Levels - 1 && par.Leaves != 0)
            {
                leaves = new List <CS_LeafImpl>(Math.Abs(par.Leaves));
            }

            // inialize other variables
            leavesPerSegment = 0;
            splitCorrection  = 0;

            index = 0;         // substem number

            cloneIndex = new List <int>();
            pruneTest  = false;        // flag used for pruning

            //...
            maxPoint = new Vector3(-float.MaxValue, -float.MaxValue, -float.MaxValue);
            minPoint = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
        }
示例#5
0
        /* offs=0 */
        /**
         * Creates a new stem
         *
         * @param tr the tree object
         * @param params the general tree parameters
         * @param lparams the parameters for the stem level
         * @param parnt the parent stem, from wich the stems grows out
         * @param stlev the stem level
         * @param trf the base transformation of the stem
         * @param offs the offset of ste stem within the parent stem (0..1)
         */
        public CS_StemImpl(CS_TreeImpl tr, CS_StemImpl growsOutOf, int stlev,
                DX_Transformation trf, float offs)
        {
            tree = tr;
                    stemlevel = stlev;
                    transf = trf;
                    offset = offs;

                    if (growsOutOf != null)
                    {
                        if (growsOutOf.stemlevel < stemlevel)
                            parent = growsOutOf;
                        else
                        {
                            clonedFrom = growsOutOf;
                            parent = growsOutOf.parent;
                        }
                    }

                    par = tree.csparams;
                    lpar = par.getLevelParams(stemlevel);

                    // initialize lists
                    segments = new List<CS_SegmentImpl>(lpar.nCurveRes);

                    if (lpar.nSegSplits > 0 || par._0BaseSplits > 0)
                    {
                        clones = new List<CS_StemImpl>(); // lpar.nSegSplits*lpar.nCurveRes+1);
                    }

                    if (stemlevel < par.Levels - 1)
                    {
                        CS_LevelParams lpar_1 = par.getLevelParams(lpar.level + 1);
                        substems = new List<CS_StemImpl>(lpar_1.nBranches);
                    }

                    if (stemlevel == par.Levels - 1 && par.Leaves != 0)
                    {
                        leaves = new List<CS_LeafImpl>(Math.Abs(par.Leaves));
                    }

                    // inialize other variables
                    leavesPerSegment = 0;
                    splitCorrection = 0;

                    index = 0; // substem number

                    cloneIndex = new List<int>();
                    pruneTest = false; // flag used for pruning

                    //...
                    maxPoint = new Vector3(-float.MaxValue, -float.MaxValue, -float.MaxValue);
                    minPoint = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
        }
示例#6
0
        /**
         * Generates the tree. The following collaboration diagram
         * shows the recursion trough the make process:
         * <p>
         * <img src="doc-files/Tree-2.png" />
         * <p>
         *
         * @throws Exception
         */

        public void make(Object progress)
        {
            this.progress = progress;

            setupGenProgress();
            csparams.prepare(seed);
            maxPoint = new Vector3(-float.MaxValue, -float.MaxValue, -float.MaxValue);
            minPoint = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            Console.WriteLine("Tree species: " + csparams.Species + ", Seed: " + seed);
            Console.WriteLine("making " + csparams.Species + "(" + seed + ") ");

            // create the trunk and all its stems and leaves
            DX_Transformation transf = new DX_Transformation();
            DX_Transformation trf;
            float             angle;
            float             dist;
            CS_LevelParams    lpar = csparams.getLevelParams(0);

            for (int i = 0; i < lpar.nBranches; i++)
            {
                trf   = trunkDirection(transf, lpar);
                angle = lpar.var(360);
                dist  = lpar.var(lpar.nBranchDist);
                trf   = trf.translate(new Vector3(dist * (float)Math.Sin(angle), dist * (float)Math.Cos(angle), 0));
                CS_StemImpl trunk = new CS_StemImpl(this, null, 0, trf, 0);
                trunks.Add(trunk);
                trunk.index = 0;
                trunk.make();
            }


            // set leafCount and stemCount for the tree
            if (csparams.Leaves == 0)
            {
                setLeafCount(0);
            }
            else
            {
                CS_LeafCounter leafCounter = new CS_LeafCounter();
                traverseTree(leafCounter);
                setLeafCount(leafCounter.getLeafCount());
            }
            CS_StemCounter stemCounter = new CS_StemCounter();

            traverseTree(stemCounter);
            setStemCount(stemCounter.getStemCount());

            // making finished
            Console.WriteLine("making " + csparams.Species + " Done.   ");

            // TODO
            //progress.endPhase();
        }
示例#7
0
        public CS_SegmentImpl(/*Params params, LevelParams lparams,*/
            CS_StemImpl stm, int inx, DX_Transformation trf,
            float r1, float r2)
        {
            index  = inx;
            transf = trf;
            rad1   = r1;
            rad2   = r2;
            stem   = stm;

            par    = stem.par;
            lpar   = stem.lpar;
            length = stem.segmentLength;

            // FIXME: rad1 and rad2 could be calculated only when output occurs (?)
            // or here in the constructor ?
            // FIXME: inialize subsegs with a better estimation of size
            subsegments = new List <CS_SubsegmentImpl>(10);
        }
示例#8
0
        public CS_SegmentImpl(/*Params params, LevelParams lparams,*/
            CS_StemImpl stm, int inx, DX_Transformation trf,
            float r1, float r2)
        {
            index = inx;
            transf = trf;
            rad1 = r1;
            rad2 = r2;
            stem = stm;

            par = stem.par;
            lpar = stem.lpar;
            length = stem.segmentLength;

            // FIXME: rad1 and rad2 could be calculated only when output occurs (?)
            // or here in the constructor ?
            // FIXME: inialize subsegs with a better estimation of size
            subsegments = new List<CS_SubsegmentImpl>(10);
        }
示例#9
0
        /**
         * Make a clone of the stem at this position
         *
         * @param trf The base transformation for the clone
         * @param start_segm Start segment number, i.e. the height, where
         *        the clone spreads out
         * @return The clone stem object
         */
        CS_StemImpl make_clone(DX_Transformation trf, int start_segm)
        {
            // creates a clone stem with same atributes as this stem
            CS_StemImpl clone = new CS_StemImpl(tree, this, stemlevel, trf, offset);
            clone.segmentLength = segmentLength;
            clone.segmentCount = segmentCount;
            clone.length = length;
            clone.baseRadius = baseRadius;
            clone.splitCorrection = splitCorrection;
            clone.pruneTest = pruneTest;
            clone.index = index;

            //DBG("Stem.clone(): clone_index "+clone_index);
            clone.cloneIndex.AddRange(cloneIndex);

            //DBG("Stem.clone(): level: "+stemlevel+" clones "+clones);
            clone.cloneIndex.Add(clones.Count);
            if (!pruneTest)
            {
                clone.lengthChildMax = lengthChildMax;
                //clone.substem_cnt = substem_cnt;
                clone.substemsPerSegment = substemsPerSegment;
                //clone.substemdist = substemdist;
                //clone.substemdistv = substemdistv;
                //clone.seg_splits = self.seg_splits
                // FIXME: for more then one clone this angle should somehow
                // correspond to the rotation angle of the clone
                clone.substemRotangle = substemRotangle + 180;
                clone.leavesPerSegment = leavesPerSegment;
            }
            return clone;
        }
示例#10
0
        /**
         * Make substems of the current stem
         *
         * @param segment
         */
        void makeSubstems(CS_SegmentImpl segment)
        {
            // creates substems for the current segment
            CS_LevelParams lpar_1 = par.getLevelParams(stemlevel + 1);

            /*
            if (Console.debug())
                DBG("Stem.make_substems(): substems_per_segment "+substemsPerSegment);
            */
            float subst_per_segm;
            float offs;

            if (stemlevel > 0)
            {
                // full length of stem can have substems
                subst_per_segm = substemsPerSegment;

                if (segment.index == 0)
                {
                    offs = parent.stemRadius(offset) / segmentLength;
                }
                else { offs = 0; }

            }
            else if (segment.index * segmentLength > par.BaseSize * length)
            {
                // segment is fully out of the bare trunk region => normal nb of substems
                subst_per_segm = substemsPerSegment;
                offs = 0;
            }
            else if ((segment.index + 1) * segmentLength <= par.BaseSize * length)
            {
                // segment is fully part of the bare trunk region => no substems
                return;
            }
            else
            {
                // segment has substems in the upper part only
                offs = (par.BaseSize * length - segment.index * segmentLength) / segmentLength;
                subst_per_segm = substemsPerSegment * (1 - offs);
            }

            // how many substems in this segment
            int substems_eff = (int)(subst_per_segm + lpar.substemErrorValue + 0.5);

            // adapt error value
            lpar.substemErrorValue -= (substems_eff - subst_per_segm);

            if (substems_eff <= 0) return;

            //DBG("Stem.make_substems(): substems_eff: "+substems_eff);

            // what distance between the segements substems
            float dist = (1.0f - offs) / substems_eff * lpar_1.nBranchDist;
            float distv = dist * 0.25f; // lpar_1.nBranchDistV/2;

            //DBG("Stem.make_substems(): offs: "+offs+" dist: "+dist+" distv: "+distv);

            for (int s = 0; s < substems_eff; s++)
            {
                // where on the segment add the substem
                float where = offs + dist / 2 + s * dist + lpar_1.var(distv);

                //offset from stembase
                float offset = (segment.index + where) * segmentLength;

                /*
                DBG("Stem.make_substems(): offset: "+ offset+" segminx: "+segment.index
                        +" where: "+where+ " seglen: "+segmentLength);
                */
                DX_Transformation trf = substemDirection(segment.transf, offset);
                trf = segment.substemPosition(trf, where);

                // create new substem
                CS_StemImpl substem = new CS_StemImpl(tree, this, stemlevel + 1, trf, offset);
                substem.index = substems.Count;
                //DBG("Stem.make_substems(): make new substem");
                if (substem.make())
                {
                    substems.Add(substem);
                    //
                    //if (substem.segments.size()==0)
                    //	throw new ArbaroException("No segments created for substem "+substem.getTreePosition());
                }
            }
        }
示例#11
0
        /**
         * Generates the tree. The following collaboration diagram
         * shows the recursion trough the make process:
         * <p>
         * <img src="doc-files/Tree-2.png" />
         * <p>
         *
         * @throws Exception
         */
        public void make(Object progress)
        {
            this.progress = progress;

            setupGenProgress();
            csparams.prepare(seed);
            maxPoint = new Vector3(-float.MaxValue, -float.MaxValue, -float.MaxValue);
            minPoint = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            Console.WriteLine("Tree species: " + csparams.Species + ", Seed: " + seed);
            Console.WriteLine("making " + csparams.Species + "(" + seed + ") ");

            // create the trunk and all its stems and leaves
            DX_Transformation transf = new DX_Transformation();
            DX_Transformation trf;
            float angle;
            float dist;
            CS_LevelParams lpar = csparams.getLevelParams(0);
            for (int i = 0; i < lpar.nBranches; i++)
            {
                trf = trunkDirection(transf, lpar);
                angle = lpar.var(360);
                dist = lpar.var(lpar.nBranchDist);
                trf = trf.translate(new Vector3(dist * (float)Math.Sin(angle), dist * (float)Math.Cos(angle), 0));
                CS_StemImpl trunk = new CS_StemImpl(this, null, 0, trf, 0);
                trunks.Add(trunk);
                trunk.index = 0;
                trunk.make();
            }

            // set leafCount and stemCount for the tree
            if (csparams.Leaves == 0) setLeafCount(0);
            else
            {
                CS_LeafCounter leafCounter = new CS_LeafCounter();
                traverseTree(leafCounter);
                setLeafCount(leafCounter.getLeafCount());
            }
            CS_StemCounter stemCounter = new CS_StemCounter();
            traverseTree(stemCounter);
            setStemCount(stemCounter.getStemCount());

            // making finished
            Console.WriteLine("making " + csparams.Species + " Done.   ");

            // TODO
            //progress.endPhase();
        }
示例#12
0
        /**
         * Make substems of the current stem
         *
         * @param segment
         */

        void makeSubstems(CS_SegmentImpl segment)
        {
            // creates substems for the current segment
            CS_LevelParams lpar_1 = par.getLevelParams(stemlevel + 1);

            /*
             * if (Console.debug())
             *  DBG("Stem.make_substems(): substems_per_segment "+substemsPerSegment);
             */
            float subst_per_segm;
            float offs;

            if (stemlevel > 0)
            {
                // full length of stem can have substems
                subst_per_segm = substemsPerSegment;

                if (segment.index == 0)
                {
                    offs = parent.stemRadius(offset) / segmentLength;
                }
                else
                {
                    offs = 0;
                }
            }
            else if (segment.index * segmentLength > par.BaseSize * length)
            {
                // segment is fully out of the bare trunk region => normal nb of substems
                subst_per_segm = substemsPerSegment;
                offs           = 0;
            }
            else if ((segment.index + 1) * segmentLength <= par.BaseSize * length)
            {
                // segment is fully part of the bare trunk region => no substems
                return;
            }
            else
            {
                // segment has substems in the upper part only
                offs           = (par.BaseSize * length - segment.index * segmentLength) / segmentLength;
                subst_per_segm = substemsPerSegment * (1 - offs);
            }

            // how many substems in this segment
            int substems_eff = (int)(subst_per_segm + lpar.substemErrorValue + 0.5);

            // adapt error value
            lpar.substemErrorValue -= (substems_eff - subst_per_segm);

            if (substems_eff <= 0)
            {
                return;
            }

            //DBG("Stem.make_substems(): substems_eff: "+substems_eff);

            // what distance between the segements substems
            float dist  = (1.0f - offs) / substems_eff * lpar_1.nBranchDist;
            float distv = dist * 0.25f; // lpar_1.nBranchDistV/2;

            //DBG("Stem.make_substems(): offs: "+offs+" dist: "+dist+" distv: "+distv);

            for (int s = 0; s < substems_eff; s++)
            {
                // where on the segment add the substem
                float where = offs + dist / 2 + s * dist + lpar_1.var(distv);

                //offset from stembase
                float offset = (segment.index + where) * segmentLength;

                /*
                 * DBG("Stem.make_substems(): offset: "+ offset+" segminx: "+segment.index
                 +" where: "+where+ " seglen: "+segmentLength);
                 */
                DX_Transformation trf = substemDirection(segment.transf, offset);
                trf = segment.substemPosition(trf, where);

                // create new substem
                CS_StemImpl substem = new CS_StemImpl(tree, this, stemlevel + 1, trf, offset);
                substem.index = substems.Count;
                //DBG("Stem.make_substems(): make new substem");
                if (substem.make())
                {
                    substems.Add(substem);
                    //
                    //if (substem.segments.size()==0)
                    //	throw new ArbaroException("No segments created for substem "+substem.getTreePosition());
                }
            }
        }
示例#13
0
        /**
         * Make clones of the current stem at the current segment
         *
         * @param trf The current segments's direction
         * @param nseg The number of the current segment
         * @return Segments outside the pruning envelope, -1
         *         if stem clone is completely inside the envelope
         */

        int makeClones(DX_Transformation trf, int nseg)
        {
            // splitting
            // FIXME: maybe move this calculation to LevelParams
            // but pay attention to saving errorValues and restoring when making prune tests
            int seg_splits_eff;

            if (stemlevel == 0 && nseg == 0 && par._0BaseSplits > 0)
            {
                seg_splits_eff = par._0BaseSplits;
            }
            else
            {
                // how many clones?
                float seg_splits = lpar.nSegSplits;
                seg_splits_eff = (int)(seg_splits + lpar.splitErrorValue + 0.5);

                // adapt error value
                lpar.splitErrorValue -= (seg_splits_eff - seg_splits);
            }

            if (seg_splits_eff < 1)
            {
                return(-1);
            }

            float s_angle = 360 / (seg_splits_eff + 1);

            // make clones
            // if seg_splits_eff > 0:
            for (int i = 0; i < seg_splits_eff; i++)
            {
                // copy params
                CS_StemImpl clone = make_clone(trf, nseg + 1);

                // NOTE: its a little bit problematic here
                // when the clone is given as a parent to
                // the substems, it should have the same
                // params for length and segment_cnt like
                // the original stem, but this could be
                // somewhat confusing(?)
                // clone.segment_cnt = remaining_segs;
                // clone.length = remaining_segs * self.segment_len

                // change the direction for the clone
                //if self.debug: sys.stderr.write("-SPLIT_CORE_BEFOR: %s, dir: %s\n" % \
                //	(str(clone.split_corr),str(clone.direction)))

                clone.transf = clone.split(trf, s_angle * (1 + i), nseg, seg_splits_eff);

                //if self.debug: sys.stderr.write("-SPLIT_CORE_AFTER: %s, dir: %s\n" %
                //	(str(clone.split_corr),str(clone.direction)))

                // make segments etc. for the clone
                int segm = clone.makeSegments(nseg + 1, clone.segmentCount);
                if (segm >= 0)
                { // prune test - clone not inside envelope
                    return(segm);
                }
                // add clone to the list
                clones.Add(clone);
            }
            // get another direction for the original stem too
            trf = split(trf, 0, nseg, seg_splits_eff);
            return(-1);
        }