Пример #1
0
 public CS_SubsegmentImpl(Vector3 p, float r, float h, CS_SegmentImpl segment)
 {
     pos          = p;
     rad          = r;
     dist         = h;
     this.segment = segment;
 }
Пример #2
0
 public CS_SubsegmentImpl(Vector3 p, float r, float h, CS_SegmentImpl segment)
 {
     pos = p;
     rad = r;
     dist = h;
     this.segment = segment;
 }
Пример #3
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());
                }
            }
        }
Пример #4
0
        // makes the segments of the stem
        int makeSegments(int start_seg, int end_seg)
        {
            //		if (start_seg>end_seg) throw new ArbaroException("Error in segment creation end_seg<start_seg.");

            if (stemlevel == 1) tree.updateGenProgress();

            //if (par.verbose) {
            /*
            if (! pruneTest) {
                if (stemlevel==0) Console.progressChar('=');
                else if (stemlevel==1 && start_seg==0) Console.progressChar('/');
                else if (stemlevel==2 && start_seg==0) Console.progressChar();
            }
            //}
            */

            DX_Transformation trf = transf;

            for (int s = start_seg; s < end_seg; s++)
            {
                if (stemlevel == 0) tree.updateGenProgress();

                if (!pruneTest)
                {// && par.verbose) {
                    //if (stemlevel==0) Console.progressChar('|');
                }

                // curving
                trf = newDirection(trf, s);
                /*
                if (Console.debug())
                    TRF("Stem.make_segments(): after new_direction ",trf);
                */

                // segment radius
                float rad1 = stemRadius(s * segmentLength);
                float rad2 = stemRadius((s + 1) * segmentLength);

                // create new segment
                CS_SegmentImpl segment = new CS_SegmentImpl(this, s, trf, rad1, rad2);
                segment.make();
                segments.Add(segment);

                // create substems
                // self.DBG("SS-makingsubst? pt: %d, lev: %d\n"%(self.prunetest,self.level))
                if (!pruneTest && lpar.level < par.Levels - 1)
                {
                    // self.DBG("SS-making substems\n")
                    makeSubstems(segment);
                }

                if (!pruneTest && lpar.level == par.Levels - 1 && par.Leaves != 0)
                {
                    makeLeaves(segment);
                }

                // shift to next position
                trf = trf.translate(trf.getZ3()*(segmentLength));
                //self.DBG("transf: %s\n"%(transf))
                //self.DBG("pos: %s\n"%(transf.vector))

                // test if too long
                if (pruneTest && !isInsideEnvelope(trf.getT()))
                {
                    // DBG("PRUNE: not inside - return %d\n"%(s))
                    return s;
                }

                // splitting (create clones)
                if (s < end_seg - 1)
                {
                    int segm = makeClones(trf, s);
                    // trf is changed by make_clones
                    // prune test - clone not inside envelope
                    if (segm >= 0)
                    {
                        //DBG("PRUNE: clone not inside - return %d\n"%(segm))
                        return segm;
                    }
                }
            }

            return -1;
        }
Пример #5
0
        /**
         * Creates the leaves for the current stem segment
         *
         * @param segment
         */
        void makeLeaves(CS_SegmentImpl segment)
        {
            // creates leaves for the current segment

            if (par.Leaves > 0)
            { // ### NORMAL MODE, leaves along the stem
                // how many leaves in this segment
                float leaves_eff = (int)(leavesPerSegment + par.leavesErrorValue + 0.5);

                // adapt error value
                par.leavesErrorValue -= (leaves_eff - leavesPerSegment);

                if (leaves_eff <= 0) return;

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

                // what distance between the leaves
                float dist = (1.0f - offs) / leaves_eff;

                for (int s = 0; s < leaves_eff; s++)
                {
                    // where on the segment add the leaf

                    // FIXME: may be use the same distribution method (BranchDist) as for substems?
                    float where = offs + dist / 2 + s * dist + lpar.var(dist / 2);

                    // offset from stembase
                    float loffs = (segment.index + where) * segmentLength;
                    // get a new direction for the leaf
                    DX_Transformation trf = substemDirection(segment.transf, loffs);
                    // translate it to its position on the stem
                    trf = trf.translate(segment.transf.getZ3()*(where * segmentLength));

                    // create new leaf
                    CS_LeafImpl leaf = new CS_LeafImpl(trf); // ,loffs);
                    leaf.make(par);
                    leaves.Add(leaf);

                }
            }

            // ##### FAN MOD, leaves placed in a fan at stem end
            else if (par.Leaves < 0 && segment.index == segmentCount - 1)
            {

                CS_LevelParams lpar_1 = par.getLevelParams(stemlevel + 1);
                int cnt = (int)(leavesPerBranch() + 0.5);

                DX_Transformation trf = segment.transf.translate(segment.transf.getZ3()*(segmentLength));
                float distangle = lpar_1.nRotate / cnt;
                float varangle = lpar_1.nRotateV / cnt;
                float downangle = lpar_1.nDownAngle;
                float vardown = lpar_1.nDownAngleV;
                float offsetangle = 0;
                // use different method for odd and even number
                if (cnt % 2 == 1)
                {
                    // create one leaf in the middle
                    CS_LeafImpl leaf = new CS_LeafImpl(trf); //,segmentCount*segmentLength);
                    leaf.make(par);
                    leaves.Add(leaf);
                    offsetangle = distangle;
                }
                else
                {
                    offsetangle = distangle / 2;
                }
                // create leaves left and right of the middle
                for (int s = 0; s < cnt / 2; s++)
                {
                    for (int rot = 1; rot >= -1; rot -= 2)
                    {
                        DX_Transformation transf1 = trf.roty(rot * (offsetangle + s * distangle
                                + lpar_1.var(varangle)));
                        transf1 = transf1.rotx(downangle + lpar_1.var(vardown));
                        CS_LeafImpl leaf = new CS_LeafImpl(transf1); //,segmentCount*segmentLength);
                        leaf.make(par);
                        leaves.Add(leaf);
                    }
                }
            }
        }
Пример #6
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());
                }
            }
        }
Пример #7
0
        // makes the segments of the stem
        int makeSegments(int start_seg, int end_seg)
        {
            //		if (start_seg>end_seg) throw new ArbaroException("Error in segment creation end_seg<start_seg.");

            if (stemlevel == 1)
            {
                tree.updateGenProgress();
            }

            //if (par.verbose) {

            /*
             * if (! pruneTest) {
             *  if (stemlevel==0) Console.progressChar('=');
             *  else if (stemlevel==1 && start_seg==0) Console.progressChar('/');
             *  else if (stemlevel==2 && start_seg==0) Console.progressChar();
             * }
             * //}
             */

            DX_Transformation trf = transf;

            for (int s = start_seg; s < end_seg; s++)
            {
                if (stemlevel == 0)
                {
                    tree.updateGenProgress();
                }

                if (!pruneTest)
                {// && par.verbose) {
                 //if (stemlevel==0) Console.progressChar('|');
                }

                // curving
                trf = newDirection(trf, s);

                /*
                 * if (Console.debug())
                 *  TRF("Stem.make_segments(): after new_direction ",trf);
                 */

                // segment radius
                float rad1 = stemRadius(s * segmentLength);
                float rad2 = stemRadius((s + 1) * segmentLength);

                // create new segment
                CS_SegmentImpl segment = new CS_SegmentImpl(this, s, trf, rad1, rad2);
                segment.make();
                segments.Add(segment);

                // create substems
                // self.DBG("SS-makingsubst? pt: %d, lev: %d\n"%(self.prunetest,self.level))
                if (!pruneTest && lpar.level < par.Levels - 1)
                {
                    // self.DBG("SS-making substems\n")
                    makeSubstems(segment);
                }

                if (!pruneTest && lpar.level == par.Levels - 1 && par.Leaves != 0)
                {
                    makeLeaves(segment);
                }

                // shift to next position
                trf = trf.translate(trf.getZ3() * (segmentLength));
                //self.DBG("transf: %s\n"%(transf))
                //self.DBG("pos: %s\n"%(transf.vector))

                // test if too long
                if (pruneTest && !isInsideEnvelope(trf.getT()))
                {
                    // DBG("PRUNE: not inside - return %d\n"%(s))
                    return(s);
                }

                // splitting (create clones)
                if (s < end_seg - 1)
                {
                    int segm = makeClones(trf, s);
                    // trf is changed by make_clones
                    // prune test - clone not inside envelope
                    if (segm >= 0)
                    {
                        //DBG("PRUNE: clone not inside - return %d\n"%(segm))
                        return(segm);
                    }
                }
            }

            return(-1);
        }
Пример #8
0
        /**
         * Creates the leaves for the current stem segment
         *
         * @param segment
         */

        void makeLeaves(CS_SegmentImpl segment)
        {
            // creates leaves for the current segment

            if (par.Leaves > 0)
            { // ### NORMAL MODE, leaves along the stem
                // how many leaves in this segment
                float leaves_eff = (int)(leavesPerSegment + par.leavesErrorValue + 0.5);

                // adapt error value
                par.leavesErrorValue -= (leaves_eff - leavesPerSegment);

                if (leaves_eff <= 0)
                {
                    return;
                }

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

                // what distance between the leaves
                float dist = (1.0f - offs) / leaves_eff;

                for (int s = 0; s < leaves_eff; s++)
                {
                    // where on the segment add the leaf

                    // FIXME: may be use the same distribution method (BranchDist) as for substems?
                    float where = offs + dist / 2 + s * dist + lpar.var(dist / 2);

                    // offset from stembase
                    float loffs = (segment.index + where) * segmentLength;
                    // get a new direction for the leaf
                    DX_Transformation trf = substemDirection(segment.transf, loffs);
                    // translate it to its position on the stem
                    trf = trf.translate(segment.transf.getZ3() * (where * segmentLength));

                    // create new leaf
                    CS_LeafImpl leaf = new CS_LeafImpl(trf); // ,loffs);
                    leaf.make(par);
                    leaves.Add(leaf);
                }
            }

            // ##### FAN MOD, leaves placed in a fan at stem end
            else if (par.Leaves < 0 && segment.index == segmentCount - 1)
            {
                CS_LevelParams lpar_1 = par.getLevelParams(stemlevel + 1);
                int            cnt    = (int)(leavesPerBranch() + 0.5);

                DX_Transformation trf         = segment.transf.translate(segment.transf.getZ3() * (segmentLength));
                float             distangle   = lpar_1.nRotate / cnt;
                float             varangle    = lpar_1.nRotateV / cnt;
                float             downangle   = lpar_1.nDownAngle;
                float             vardown     = lpar_1.nDownAngleV;
                float             offsetangle = 0;
                // use different method for odd and even number
                if (cnt % 2 == 1)
                {
                    // create one leaf in the middle
                    CS_LeafImpl leaf = new CS_LeafImpl(trf); //,segmentCount*segmentLength);
                    leaf.make(par);
                    leaves.Add(leaf);
                    offsetangle = distangle;
                }
                else
                {
                    offsetangle = distangle / 2;
                }
                // create leaves left and right of the middle
                for (int s = 0; s < cnt / 2; s++)
                {
                    for (int rot = 1; rot >= -1; rot -= 2)
                    {
                        DX_Transformation transf1 = trf.roty(rot * (offsetangle + s * distangle
                                                                    + lpar_1.var(varangle)));
                        transf1 = transf1.rotx(downangle + lpar_1.var(vardown));
                        CS_LeafImpl leaf = new CS_LeafImpl(transf1); //,segmentCount*segmentLength);
                        leaf.make(par);
                        leaves.Add(leaf);
                    }
                }
            }
        }