Fest implementierte Formeln.
        /// <summary>
        /// Hier können eigene Renderer zugeschaltet werden:
        /// </summary>
        /// <returns></returns>
        public static Renderer Create(PictureData pdata,Formulas formula)
        {
            Renderer retVal = null;

              switch (ParameterDict.Current["Composite.Renderer"]) {

            case "":
            case "PlasicRenderer":
            case "6":
                    //retVal = new PlasicRenderer(pdata.Clone());
                    retVal = new FloatPlasicRenderer(pdata.Clone());
                    break;

            case "FastPreviewRenderer":
            case "8":
              retVal = new FastPreviewRenderer(pdata.Clone());
              break;

            default:
                    //retVal = new PlasicRenderer(pdata.Clone());
                    retVal = new FloatPlasicRenderer(pdata.Clone());
                    break;
              }

              if (retVal != null)
              retVal.Init(formula);

            return retVal;
        }
Esempio n. 2
0
        /// <summary>
        /// Compute surface data.
        /// </summary>
        protected void Generate(FracValues act_val, int zyklen, double screensize, int formula, bool perspective)
        {
            Random rand = new Random();
            _maxUpdateSteps = ParameterDict.Current.GetInt("View.UpdateSteps");
            double[] col = null;
            double xd, yd, zd;
            double x, y, z;
            double dephAdd = ParameterDict.Current.GetInt("View.DephAdd") * screensize;
            act_val = act_val.Clone();
            Formulas formulas = new Formulas(_pData);
            _lastUsedFormulas = formulas;
            if (ParameterDict.Current["Intern.Formula.Source"].Trim() == "")
            {
                formulas.InternFormula = new Fractrace.TomoGeometry.VecRotMandel2d();
            }
            else
            {
                Fractrace.TomoGeometry.TomoFormulaFactory fac = new Fractrace.TomoGeometry.TomoFormulaFactory();
                formulas.InternFormula = fac.CreateFromString(ParameterDict.Current["Intern.Formula.Source"]);
            }
            if (formulas.InternFormula == null)
                return;
            formulas.InternFormula.Init();

            double centerX = ParameterDict.Current.GetDouble("Scene.CenterX");
            double centerY = ParameterDict.Current.GetDouble("Scene.CenterY");
            double centerZ = ParameterDict.Current.GetDouble("Scene.CenterZ");

            Rotation rotView = new Rotation();
            rotView.Init(centerX, centerY, centerZ, ParameterDict.Current.GetDouble("Transformation.Camera.AngleX"), ParameterDict.Current.GetDouble("Transformation.Camera.AngleY"),
                ParameterDict.Current.GetDouble("Transformation.Camera.AngleZ"));
            formulas.Transforms.Add(rotView);

            // TODO: only use in compatibility mode.
            Rotation rot = new Rotation();
            rot.Init();
            formulas.Transforms.Add(rot);

            if (_isRightView)
            {
                RightEyeView stereoTransform = new RightEyeView();
                stereoTransform.Init();
                formulas.Transforms.Add(stereoTransform);
            }

            col = formulas.col;
            _maxxIter = _width;
            _maxyIter = (int)(ParameterDict.Current.GetDouble("View.Deph") * screensize);
            if(IsSmallPreview())
                _maxyIter = _maxxIter;
            _maxzIter = _height;

            int MINX_ITER = 0;
            int MINY_ITER = 0;
            int MINZ_ITER = 0;
            double fa1;
            int xschl = 0, yschl = 0, zschl = 0, xx = 0, yy = 0;
            double wix = 0, wiy = 0, wiz = 0;
            double jx = 0, jy = 0, jz = 0, jzz = 0;

            jx = ParameterDict.Current.GetDouble("Formula.Static.jx");
            jy = ParameterDict.Current.GetDouble("Formula.Static.jy");
            jz = ParameterDict.Current.GetDouble("Formula.Static.jz");
            jzz = ParameterDict.Current.GetDouble("Formula.Static.jzz");

            // Innenbereich
            int minCycle = (int)ParameterDict.Current.GetDouble("Formula.Static.MinCycle");
            if (minCycle == 0)
                minCycle = zyklen;

            // Offset für den Maximalzyklus für die klassische 2D-Darstellung
            int cycleAdd = 128;

            wix = act_val.arc.x;
            wiy = act_val.arc.y;
            wiz = act_val.arc.z;

            xd = (act_val.end_tupel.x - act_val.start_tupel.x) / (_maxxIter - MINX_ITER);
            yd = (act_val.end_tupel.y - act_val.start_tupel.y) / (_maxyIter - MINY_ITER);
            zd = (act_val.end_tupel.z - act_val.start_tupel.z) / (_maxzIter - MINZ_ITER);

            if (_oldData != null)
            {
                yd = yd / (_updateCount);
                if (_updateCount < 5)
                {
                    _maxyIter *= _updateCount;
                }
            }
            if (_transformUpdate)
            {
                yd *= 3.0;
            }

            double xcenter = (act_val.start_tupel.x + act_val.end_tupel.x) / 2.0;
            double ycenter = (act_val.start_tupel.y + act_val.end_tupel.y) / 2.0;
            double zcenter = (act_val.start_tupel.z + act_val.end_tupel.z) / 2.0;
            bool isYborder = true;

            // Projektion initialisieren und der Berechnung zuordnen:
            // TODO: Projektion über Einstellungen abwählbar machen
            double cameraDeph = act_val.end_tupel.y - act_val.start_tupel.y;
            cameraDeph *= ParameterDict.Current.GetDouble("Transformation.Perspective.Cameraposition");
            Vec3 camera = new Vec3(xcenter, act_val.end_tupel.y + cameraDeph, zcenter);
            Vec3 viewPoint = new Vec3(xcenter, act_val.end_tupel.y, zcenter);
            Projection proj = new Projection(camera, viewPoint);
            if (ParameterDict.Current.GetBool("View.Perspective"))
                formulas.Projection = proj;

            // Bei der Postererstellung werden die Parameter der räumlichen Projektion auf das mittlere Bild
            // ausgerichtet und anschließend die Grenzen verschoben
            double xPoster = ParameterDict.Current.GetInt("View.PosterX");
            double zPoster = ParameterDict.Current.GetInt("View.PosterZ");

            double xDiff = act_val.end_tupel.x - act_val.start_tupel.x;
            double zDiff = act_val.end_tupel.z - act_val.start_tupel.z;
            act_val.end_tupel.x += xDiff * xPoster;
            act_val.start_tupel.x += xDiff * xPoster;
            act_val.end_tupel.z += zDiff * zPoster;
            act_val.start_tupel.z += zDiff * zPoster;

            // Start der Iteration in der Reihenfolge: z,x,y (y entspricht der Tiefe)
            z = act_val.end_tupel.z + zd;

            for (zschl = (int)(_maxzIter); zschl >= (MINZ_ITER); zschl -= 1)
            {

                // Nur wenn der Scheduler die Erlaubnis gibt, zschl zu benutzen,
                // die Berechnung ausführen (sonst nächste Iteration)
                if (IsAvailable(_maxzIter - zschl))
                {

                    System.Windows.Forms.Application.DoEvents();
                    z = act_val.end_tupel.z - (double)zd * (_maxzIter - zschl);

                    bool minYDetected = false;
                    for (xschl = (int)(MINX_ITER); xschl <= _maxxIter; xschl += 1)
                    {
                        if (_abort)
                        {
                            return;
                        }

                        x = act_val.start_tupel.x + (double)xd * xschl;
                        double miny = 0;
                        isYborder = true;

                        xx = xschl;
                        yy = _maxzIter - zschl;
                        if (double.IsNaN(x) )
                            return ;

                        // Used for better start values in update iteration
                        double yAdd = rand.NextDouble() * yd;
                        // In last computation a voxel ist found at (xx,zz)
                        bool centerIsSet = false;
                        // In last computation at least on voxel ist found near (xx,zz)
                        bool areaIsSet = false;
                        double yAddCenter = 0;

                        bool needComputing = true;
                        if (_oldPictureData != null)
                        {
                            needComputing = false;
                            PixelInfo pxInfoTest = _oldPictureData.Points[xx, yy];
                            if (pxInfoTest != null && pxInfoTest.Coord != null)
                            {
                                yAddCenter = pxInfoTest.Coord.Y;
                                yAdd = yAddCenter;
                                centerIsSet = true;
                            }

                            for (int xxi = -1; xxi <= 1; xxi++)
                            {
                                for (int yyi = -1; yyi <= 1; yyi++)
                                {
                                    int xxposi = xx + xxi;
                                    int yyposi = yy + yyi;
                                    if (xxposi >= 0 && xxposi <= _maxxIter && yyposi >= 0 && yyposi <= _maxzIter)
                                    {
                                        PixelInfo pxInfo = _oldPictureData.Points[xxposi, yyposi];
                                        if (pxInfo != null && pxInfo.Coord != null)
                                        {
                                            areaIsSet = true;
                                            double yAddTemp = pxInfo.Coord.Y;
                                            if (yAdd < yAddTemp || !centerIsSet)
                                                yAdd = yAddTemp;
                                        }
                                    }
                                }
                            }
                        }

                        if (yAdd + yd < act_val.end_tupel.y)
                        {
                            if (centerIsSet)
                            {
                                if (yAddCenter + 4.0 * yd < yAdd)
                                {
                                    needComputing = true;
                                    yAdd = yAdd - act_val.end_tupel.y + 2.0 * ((double)_updateCount) * yd + rand.NextDouble() * yd;
                                    _gData.Picture[xx, yy] = _oldData.Picture[xx, yy];
                                }
                            }
                            else
                            {
                                if (areaIsSet)
                                {
                                    needComputing = true;
                                    yAdd = rand.NextDouble() * yd;
                                }
                            }
                        }

                        if (needComputing)
                        {
                            // yadd cannot be easy handled (because of inside rendering).
                            for (yschl = (int)(_maxyIter); yschl >= MINY_ITER - dephAdd; yschl -= 1)
                            {
                                if (_abort)
                                    return;

                                if (xx >= 0 && xx < _width && yy >= 0 && yy < _height)
                                {
                                    if ((_gData.Picture)[xx, yy] == 0 || (_gData.Picture)[xx, yy] == 2)
                                    { // aha, noch zeichnen
                                        // Test, ob Schnitt mit Begrenzung vorliegt
                                        y = act_val.end_tupel.y - (double)yd * (_maxyIter - yschl);
                                        y += yAdd;
                                        if (double.IsNaN(x) || double.IsNaN(y) || double.IsNaN(z))
                                            return;

                                        fa1 = 0;

                                        int usedCycles = 0;
                                        bool inverse = false;
                                        if (_gData == null)
                                        {
                                            System.Diagnostics.Debug.WriteLine("Error: GData == null");
                                            return;
                                        }
                                        if ((_gData.Picture)[xx, yy] == 0)
                                            usedCycles = formulas.Rechne(x, y, z, 0, zyklen,
                                                  wix, wiy, wiz,
                                                  jx, jy, jz, jzz, formula, inverse);

                                        if ((_gData.Picture)[xx, yy] == 2)
                                        {// Inverse computing
                                            inverse = true;
                                            usedCycles = formulas.Rechne(x, y, z, 0, minCycle,
                                                  wix, wiy, wiz,
                                                  jx, jy, jz, jzz, formula, inverse);
                                        }

                                        if (usedCycles == 0)
                                        {
                                            if (!minYDetected)
                                                miny = yschl;
                                            minYDetected = true;
                                            // Iteration ist nicht abgebrochen, also weiterrechnen:
                                            int oldPictureInfo = (_gData.Picture)[xx, yy]; // pictureInfo wird eventuell zurückgesetzt, wenn
                                            // die Farbberechnung wiederholt wird.

                                            _gData.Picture[xx, yy] = 1; // Punkt als gesetzt markieren
                                            VoxelInfo vInfo = new VoxelInfo();
                                            _gData.PointInfo[xx, yy] = vInfo;
                                            vInfo.i = x;
                                            vInfo.j = y;
                                            vInfo.k = z;

                                            cycleAdd = 1024;
                                            if (minCycle >= 0)
                                            {
                                                cycleAdd = minCycle - zyklen;
                                            }
                                            if (isYborder)
                                            { // es liegt Schnitt mit Begrenzung vor

                                                fa1 = formulas.Rechne(x, y, z, 0, zyklen + cycleAdd,
                                                 wix, wiy, wiz,
                                                 jx, jy, jz, jzz, formula, false);

                                                if (fa1 == 0)
                                                {
                                                    fa1 = -1;
                                                    (_gData.Picture)[xx, yy] = 2; // Punkt nicht als gesetzt markieren
                                                }
                                                else
                                                    fa1 = 255 * fa1 / (zyklen + cycleAdd);

                                                // debug only: alle Farbwerte auf 1 setzen
                                                col[0] = col[1] = col[2] = col[3] = 255;
                                            }
                                            else
                                            {// innerer Punkt

                                                if (inverse)
                                                {

                                                        if (IsSmallPreview())
                                                        {
                                                            fa1 = formulas.RayCastAt(minCycle, x, y, z, 0,
                                                           xd, yd, zd, 0,
                                                           wix, wiy, wiz,
                                                           jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                        }
                                                        else
                                                        {
                                                            fa1 = formulas.FixPoint(minCycle, x, y, z, 0,
                                                           xd, yd, zd, 0,
                                                           wix, wiy, wiz,
                                                           jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                        }
                                                }
                                                else
                                                {
                                                        if (IsSmallPreview())
                                                        {
                                                            fa1 = formulas.RayCastAt(zyklen, x, y, z, 0,
                                   xd, yd, zd, 0,
                                   wix, wiy, wiz,
                                   jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                        }
                                                        else
                                                        {
                                                            fa1 = formulas.FixPoint(zyklen, x, y, z, 0,
                                     xd, yd, zd, 0,
                                     wix, wiy, wiz,
                                     jx, jy, jz, jzz, formula, inverse, xx, yy, true);
                                                            fa1 = (col[0] + col[1] + col[2] + col[3]) / 4.0;
                                                        }
                                                }
                                            }
                                        }
                                    }
                                }
                                isYborder = false;
                            }
                            if ((_gData.Picture)[xx, yy] == 0 || (_gData.Picture)[xx, yy] == 2)
                            {
                                if (_oldPictureData != null)
                                {
                                    _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                                }
                            }

                            if (_oldData != null && _updateCount > 2)
                            {
                                if (_oldPictureData.Points[xx, yy] != null)
                                {
                                    if (_pData.Points[xx, yy] == null)
                                    {
                                        _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                                    }
                                    else
                                    {
                                        if (_pData.Points[xx, yy].Coord.Y < _oldPictureData.Points[xx, yy].Coord.Y)
                                        {
                                            _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Get the old values:
                            _pData.Points[xx, yy] = _oldPictureData.Points[xx, yy];
                        }
                    }
                }
            }
        }