Beispiel #1
0
Base::Vector3d TransformStrategy::getRotationCenter() const
{
    // get the global bounding box of all selected objects and use its center as
    // rotation center
    std::set<App::DocumentObject*> objects = transformObjects();
    if (!objects.empty()) {
        Base::BoundBox3d bbox;
        bool first=true;
        for (std::set<App::DocumentObject*>::const_iterator it=objects.begin();it!=objects.end();++it) {
            std::map<std::string,App::Property*> props;
            (*it)->getPropertyMap(props);
            // search for a data property
            std::map<std::string,App::Property*>::iterator jt;
            jt = std::find_if(props.begin(), props.end(), find_geometry_data());
            if (jt != props.end()) {
                if (first)
                    bbox = (static_cast<App::PropertyGeometry*>(jt->second)->getBoundingBox());
                else
                    bbox.Add(static_cast<App::PropertyGeometry*>(jt->second)->getBoundingBox());
                first = false;
            }
        }

        return Base::Vector3d((bbox.MinX+bbox.MaxX)/2,
                              (bbox.MinY+bbox.MaxY)/2,
                              (bbox.MinZ+bbox.MaxZ)/2);
    }

    return Base::Vector3d();
}
Base::BoundBox3d PropertyPointKernel::getBoundingBox() const
{
    Base::BoundBox3d box;
    for (PointKernel::const_iterator it = _cPoints->begin(); it != _cPoints->end(); ++it)
        box.Add(*it);
    return box;
}
Beispiel #3
0
Base::BoundBox3d DrawProjGroup::getBoundingBox() const
{
    Base::BoundBox3d bbox;

    std::vector<App::DocumentObject*> views = Views.getValues();
    TechDraw::DrawProjGroupItem *anchorView = dynamic_cast<TechDraw::DrawProjGroupItem *>(Anchor.getValue());
    for (std::vector<App::DocumentObject*>::const_iterator it = views.begin(); it != views.end(); ++it) {
         if ((*it)->getTypeId().isDerivedFrom(DrawViewPart::getClassTypeId())) {
            DrawViewPart *part = static_cast<DrawViewPart *>(*it);
            Base::BoundBox3d  bb = part->getBoundingBox();

            bb.ScaleX(1. / part->Scale.getValue());
            bb.ScaleY(1. / part->Scale.getValue());

            // X and Y of dependant views are relative to the anchorView
            if (part != anchorView) {
                bb.MoveX(part->X.getValue());
                bb.MoveY(part->Y.getValue());
            }

            bbox.Add(bb);
        }
    }
    // This /should/ leave the centre of the bounding box at (0,0) except when
    // we're in the process of updating the anchor view's position (eg called
    // by moveToCentre())
    if (anchorView) { //TODO: It looks like we might be getting called before an anchor view is set - weird...
        bbox.MoveX(anchorView->X.getValue());
        bbox.MoveY(anchorView->Y.getValue());
    }
    return bbox;
}
Base::BoundBox3d PointKernel::getBoundBox(void)const
{
    Base::BoundBox3d bnd;
    for (const_point_iterator it = begin(); it != end(); ++it)
        bnd.Add(*it);
    return bnd;
}
Beispiel #5
0
    void onSelectionChanged(const Gui::SelectionChanges& msg)
    {
        Base::BoundBox3d bbox;
        unsigned long countPoints=0, countFacets=0;
        std::vector<Mesh::Feature*> mesh = Gui::Selection().getObjectsOfType<Mesh::Feature>();
        for (std::vector<Mesh::Feature*>::iterator it = mesh.begin(); it != mesh.end(); ++it) {
            countPoints += (*it)->Mesh.getValue().countPoints();
            countFacets += (*it)->Mesh.getValue().countFacets();
            bbox.Add((*it)->Mesh.getBoundingBox());
        }

        if (countPoints > 0) {
            numPoints->setText(QString::number(countPoints));
            numFacets->setText(QString::number(countFacets));
            numMin->setText(QString::fromAscii("X: %1\tY: %2\tZ: %3")
                .arg(bbox.MinX).arg(bbox.MinX).arg(bbox.MinX));
            numMax->setText(QString::fromAscii("X: %1\tY: %2\tZ: %3")
                .arg(bbox.MaxX).arg(bbox.MaxX).arg(bbox.MaxX));
        }
        else {
            numPoints->setText(QString::fromAscii(""));
            numFacets->setText(QString::fromAscii(""));
            numMin->setText(QString::fromAscii(""));
            numMax->setText(QString::fromAscii(""));
        }
    }
Beispiel #6
0
Base::BoundBox3d GeometryObject::boundingBoxOfAoe(const Ellipse *aoe,
        double start,
        double end, bool cw) const
{
    // Using the ellipse form:
    // (xc, yc) = centre of ellipse
    // phi = angle of ellipse major axis off X axis
    // a, b = half of major, minor axes
    //
    // x(theta) = xc + a*cos(theta)*cos(phi) - b*sin(theta)*sin(phi)
    // y(theta) = yc + a*cos(theta)*sin(phi) + b*sin(theta)*cos(phi)

    double a (aoe->major / 2.0),
           b (aoe->minor / 2.0),
           phi (aoe->angle),
           xc (aoe->center.fX),
           yc (aoe->center.fY);

    if (a == 0 || b == 0) {
        // Degenerate case - TODO: handle as line instead of throwing
        throw Base::Exception("Ellipse with invalid major axis in GeometryObject::boundingBoxOfAoe()");
    }

    // Calculate points of interest for the bounding box.  These are points
    // where d(x)/d(theta) and d(y)/d(theta) = 0 (where the x and y extremes
    // of the ellipse would be if it were complete), and arc endpoints.
    double testAngles[6] = { atan(tan(phi) * (-b / a)),
                             testAngles[0] + M_PI
                           };
    if (tan(phi) == 0) {
        testAngles[2] = M_PI / 2.0;
        testAngles[3] = 3.0 * M_PI / 2.0;
    } else {
        testAngles[2] = atan((1.0 / tan(phi)) * (b / a));
        testAngles[3] = testAngles[2] + M_PI;
    }
    testAngles[4] = start;
    testAngles[5] = end;

    // Add extremes to bounding box, if they are within the arc
    Base::BoundBox3d bb;
    for (int ai(0); ai < 6; ++ai) {
        double theta(testAngles[ai]);
        if (isWithinArc(theta, start, end, cw) ) {
            bb.Add( Base::Vector3d(xc + a*cos(theta)*cos(phi) - b*sin(theta)*sin(phi),
                                   yc + a*cos(theta)*sin(phi) - b*sin(theta)*cos(phi),
                                   0) );
        }
    }

    return bb;
}
Beispiel #7
0
PointsGrid::PointsGrid (const PointKernel &rclM, double fGridLen)
: _pclPoints(&rclM),
  _ulCtElements(0),
  _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0),
  _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
  _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
{
  Base::BoundBox3d clBBPts;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPts.Add(*it);
  Rebuild(std::max<unsigned long>((unsigned long)(clBBPts.LengthX() / fGridLen), 1),
          std::max<unsigned long>((unsigned long)(clBBPts.LengthY() / fGridLen), 1),
          std::max<unsigned long>((unsigned long)(clBBPts.LengthZ() / fGridLen), 1));
}
Beispiel #8
0
void PointsGrid::InitGrid (void)
{
  assert(_pclPoints != NULL);

  unsigned long i, j;

  // Grid Laengen berechnen wenn nicht initialisiert
  //
  if ((_ulCtGridsX == 0) || (_ulCtGridsY == 0) || (_ulCtGridsZ == 0))
    CalculateGridLength(POINTS_CT_GRID, POINTS_MAX_GRIDS);

  // Grid Laengen und Offset bestimmen
  //
  {
  Base::BoundBox3d clBBPts;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPts.Add(*it);

  double fLengthX = clBBPts.LengthX(); 
  double fLengthY = clBBPts.LengthY();
  double fLengthZ = clBBPts.LengthZ();

  {
    // Offset fGridLen/2
    //
    _fGridLenX = (1.0f + fLengthX) / double(_ulCtGridsX);
    _fMinX = clBBPts.MinX - 0.5f;
  }

  {
    _fGridLenY = (1.0f + fLengthY) / double(_ulCtGridsY);
    _fMinY = clBBPts.MinY - 0.5f;
  }

  {
    _fGridLenZ = (1.0f + fLengthZ) / double(_ulCtGridsZ);
    _fMinZ = clBBPts.MinZ - 0.5f;
  }
  }

  // Daten-Struktur anlegen
  _aulGrid.clear();
  _aulGrid.resize(_ulCtGridsX);
  for (i = 0; i < _ulCtGridsX; i++)
  {
    _aulGrid[i].resize(_ulCtGridsY);
    for (j = 0; j < _ulCtGridsY; j++)
      _aulGrid[i][j].resize(_ulCtGridsZ);
  }
}
Beispiel #9
0
Base::BoundBox3d PointKernel::getBoundBox(void)const
{
    Base::BoundBox3d bnd;

    //FIXME: VS 2015 or later causes a linker error
#if defined _WIN32 
    // Thread-local bounding boxes
    Concurrency::combinable<Base::BoundBox3d> bbs;
    // Cannot use a const_point_iterator here as it is *not* a proper iterator (fails the for_each template)
    Concurrency::parallel_for_each(_Points.begin(), _Points.end(), [this, &bbs](const value_type& value) {
        Base::Vector3d vertd(value.x, value.y, value.z);
        bbs.local().Add(this->_Mtrx * vertd);
    });
    // Combine each thread-local bounding box in the final bounding box
    bbs.combine_each([&bnd](const Base::BoundBox3d& lbb) {
        bnd.Add(lbb);
    });
#else
    for (const_point_iterator it = begin(); it != end(); ++it)
        bnd.Add(*it);
#endif
    return bnd;
}
Beispiel #10
0
void CmdPartCrossSections::activated(int iMsg)
{
    Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
    if (!dlg) {
        std::vector<App::DocumentObject*> obj = Gui::Selection().getObjectsOfType
            (Part::Feature::getClassTypeId());
        Base::BoundBox3d bbox;
        for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it) {
            bbox.Add(static_cast<Part::Feature*>(*it)->Shape.getBoundingBox());
        }
        dlg = new PartGui::TaskCrossSections(bbox);
    }
    Gui::Control().showDialog(dlg);
}
Beispiel #11
0
void PointsGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids)
{
  // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen
  // pro Grid sollen ca. 10 (?!?!) Facets liegen
  // bzw. max Grids sollten 10000 nicht ueberschreiten
  Base::BoundBox3d clBBPtsEnlarged;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPtsEnlarged.Add(*it);
  double fVolElem;

  if (_ulCtElements > (ulMaxGrids * ulCtGrid))
    fVolElem = (clBBPtsEnlarged.LengthX() * clBBPtsEnlarged.LengthY() * clBBPtsEnlarged.LengthZ()) / float(ulMaxGrids * ulCtGrid);
  else
    fVolElem = (clBBPtsEnlarged.LengthX() * clBBPtsEnlarged.LengthY() * clBBPtsEnlarged.LengthZ()) / float(_ulCtElements);

  double fVol     = fVolElem * float(ulCtGrid);
  double fGridLen = float(pow((float)fVol,(float) 1.0f / 3.0f));

  _ulCtGridsX = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthX() / fGridLen), 1);
  _ulCtGridsY = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthY() / fGridLen), 1);
  _ulCtGridsZ = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthZ() / fGridLen), 1);
}
Beispiel #12
0
Base::BoundBox3d GeometryObject::calcBoundingBox() const
{
    Base::BoundBox3d bbox;

    // First calculate bounding box based on vertices
    for(std::vector<Vertex *>::const_iterator it( vertexGeom.begin() );
            it != vertexGeom.end(); ++it) {
        bbox.Add( Base::Vector3d((*it)->pnt.fX, (*it)->pnt.fY, 0.) );
    }

    // Now, consider geometry where vertices don't define bounding box eg circles
    for (std::vector<BaseGeom *>::const_iterator it( edgeGeom.begin() );
            it != edgeGeom.end(); ++it) {
        switch ((*it)->geomType) {
        case CIRCLE: {
            Circle *c = static_cast<Circle *>(*it);
            bbox.Add( Base::BoundBox3d(-c->radius + c->center.fX,
                                       -c->radius + c->center.fY,
                                       0,
                                       c->radius + c->center.fX,
                                       c->radius + c->center.fY,
                                       0) );
        }
        break;

        case ARCOFCIRCLE: {
            AOC *arc = static_cast<AOC *>(*it);

            // Endpoints of arc
            bbox.Add( Base::Vector3d(arc->radius * cos(arc->startAngle),
                                     arc->radius * sin(arc->startAngle),
                                     0.0) );
            bbox.Add( Base::Vector3d(arc->radius * cos(arc->endAngle),
                                     arc->radius * sin(arc->endAngle),
                                     0.0) );

            // Extreme X and Y values if they're within the arc
            for (double theta = 0.0; theta < 6.5; theta += M_PI / 2.0) {
                if (isWithinArc(theta, arc->startAngle, arc->endAngle, arc->cw)) {
                    bbox.Add( Base::Vector3d(arc->radius * cos(theta),
                                             arc->radius * sin(theta),
                                             0.0) );
                }
            }
        }
        break;

        case ELLIPSE: {
            bbox.Add( boundingBoxOfAoe(static_cast<Ellipse *>(*it)) );
        }
        break;

        case ARCOFELLIPSE: {
            AOE *aoe = static_cast<AOE *>(*it);
            double start = aoe->startAngle,
                   end = aoe->endAngle;
            bool cw = aoe->cw;
            bbox.Add( boundingBoxOfAoe(static_cast<Ellipse *>(*it), start, end, cw) );
        }
        break;

        case BSPLINE: {
            bbox.Add( boundingBoxOfBspline(static_cast<BSpline *>(*it)) );
        }
        break;

        case GENERIC: {
            // this case ends up just drawing line segments between points
            Generic *gen = static_cast<Generic *>(*it);
            for (std::vector<Base::Vector2D>::const_iterator segIt = gen->points.begin();
                    segIt != gen->points.end(); ++segIt) {
                bbox.Add( Base::Vector3d(segIt->fX, segIt->fY, 0) );
            }
        }
        break;

        default:
            throw Base::Exception("Unknown geomType in GeometryObject::calcBoundingBox()");
        }
    }
    return bbox;
}
Beispiel #13
0
Base::BoundBox3d GeometryObject::boundingBoxOfBspline(const BSpline *spline) const
{
    Base::BoundBox3d bb;
    for (std::vector<BezierSegment>::const_iterator segItr( spline->segments.begin() );
            segItr != spline->segments.end(); ++segItr) {
        switch (segItr->poles) {
        case 0:   // Degenerate, but safe ignore
            break;
        case 2:   // Degenerate - straight line
            bb.Add(Base::Vector3d( segItr->pnts[1].fX,
                                   segItr->pnts[1].fY,
                                   0 ));
        // fall through
        case 1:   // Degenerate - just a point
            bb.Add(Base::Vector3d( segItr->pnts[0].fX,
                                   segItr->pnts[0].fY,
                                   0 ));
            break;
        case 3: {
            double
            px[3] = { segItr->pnts[0].fX,
                      segItr->pnts[1].fX,
                      segItr->pnts[2].fX
                    },
                    py[3] = { segItr->pnts[0].fY,
                              segItr->pnts[1].fY,
                              segItr->pnts[2].fY
                            },
                            slns[4] = { 0, 1 }; // Consider the segment's end points

            // if's are to prevent problems with divide-by-0
            if ((2 * px[1] - px[0] - px[2]) == 0) {
                slns[2] = -1;
            } else {
                slns[2] = (px[1] - px[0]) / (2 * px[1] - px[0] - px[2]);
            }
            if ((2 * py[1] - py[0] - py[2]) == 0) {
                slns[3] = -1;
            } else {
                slns[3] = (py[1] - py[0]) / (2 * py[1] - py[0] - py[2]);
            }

            // evaluate B(t) at the endpoints and zeros
            for (int s(0); s < 4; ++s) {
                double t( slns[s] );
                if (t < 0 || t > 1) {
                    continue;
                }
                double tx( px[0] * (1 - t) * (1 - t) +
                           px[1] * 2 * (1 - t) * t +
                           px[2] * t * t ),
                           ty( py[0] * (1 - t) * (1 - t) +
                               py[1] * 2 * (1 - t) * t +
                               py[2] * t * t );
                bb.Add( Base::Vector3d(tx, ty, 0) );
            }
        }
        break;
        case 4: {
            double
            px[4] = { segItr->pnts[0].fX,
                      segItr->pnts[1].fX,
                      segItr->pnts[2].fX,
                      segItr->pnts[3].fX
                    },
                    py[4] = { segItr->pnts[0].fY,
                              segItr->pnts[1].fY,
                              segItr->pnts[2].fY,
                              segItr->pnts[3].fY
                            },
                            // If B(t) is the cubic Bezier, find t where B'(t) == 0
                            //
                            // For control points P0-P3, B'(t) works out to be:
                            // B'(t) = t^2 * (-3P0 + 9P1 - 9P2 + 3P3) +
                            //          t  * (6P0 - 12P1 + 6P2) +
                            //          3  * (P1 - P0)
                            //
                            // So, we use the quadratic formula!
                            ax = -3 * px[0] + 9 * px[1] - 9 * px[2] + 3 * px[3],
                            ay = -3 * py[0] + 9 * py[1] - 9 * py[2] + 3 * py[3],
                            bx = 6 * px[0] - 12 * px[1] + 6 * px[2],
                            by = 6 * py[0] - 12 * py[1] + 6 * py[2],
                            cx = 3 * px[1] - 3 * px[0],
                            cy = 3 * py[1] - 3 * py[0],

                            slns[6] = { 0, 1 }; // Consider the segment's end points

            // if's are to prevent problems with divide-by-0 and NaN
            if ( (2 * ax) == 0 || (bx * bx - 4 * ax * cx) < 0 ) {
                slns[2] = -1;
                slns[3] = -1;
            } else {
                slns[2] = (-bx + sqrt(bx * bx - 4 * ax * cx)) / (2 * ax);
                slns[3] = (-bx - sqrt(bx * bx - 4 * ax * cx)) / (2 * ax);
            }
            if ((2 * ay) == 0 || (by * by - 4 * ay * cy) < 0 ) {
                slns[4] = -1;
                slns[5] = -1;
            } else {
                slns[4] = (-by + sqrt(by * by - 4 * ay * cy)) / (2 * ay);
                slns[5] = (-by - sqrt(by * by - 4 * ay * cy)) / (2 * ay);
            }

            // evaluate B(t) at the endpoints and zeros
            for (int s(0); s < 6; ++s) {
                double t( slns[s] );
                if (t < 0 || t > 1) {
                    continue;
                }
                double tx( px[0] * (1 - t) * (1 - t) * (1 - t) +
                           px[1] * 3 * (1 - t) * (1 - t) * t +
                           px[2] * 3 * (1 - t) * t * t +
                           px[3] * t * t * t ),
                           ty( py[0] * (1 - t) * (1 - t) * (1 - t) +
                               py[1] * 3 * (1 - t) * (1 - t) * t +
                               py[2] * 3 * (1 - t) * t * t +
                               py[3] * t * t * t );
                bb.Add( Base::Vector3d(tx, ty, 0) );
            }

        }
        break;
        default:
            throw Base::Exception("Invalid degree bezier segment in GeometryObject::calcBoundingBox");
        }
    }
    return bb;
}
Beispiel #14
0
void PointsGrid::CalculateGridLength (int iCtGridPerAxis)
{
  if (iCtGridPerAxis<=0)
  {
    CalculateGridLength(POINTS_CT_GRID, POINTS_MAX_GRIDS);
    return;
  }

  // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen
  // pro Grid sollen ca. 10 (?!?!) Facets liegen
  // bzw. max Grids sollten 10000 nicht ueberschreiten
  Base::BoundBox3d clBBPts;// = _pclPoints->GetBoundBox();
  for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
    clBBPts.Add(*it);

  double fLenghtX = clBBPts.LengthX();
  double fLenghtY = clBBPts.LengthY();
  double fLenghtZ = clBBPts.LengthZ();

  double fLenghtD = clBBPts.CalcDiagonalLength();

  double fLengthTol = 0.05f * fLenghtD;

  bool bLenghtXisZero = (fLenghtX <= fLengthTol);
  bool bLenghtYisZero = (fLenghtY <= fLengthTol);
  bool bLenghtZisZero = (fLenghtZ <= fLengthTol);

  int iFlag  = 0;

  int iMaxGrids = 1;

  if (bLenghtXisZero)  
    iFlag += 1; 
  else
    iMaxGrids *= iCtGridPerAxis;

  if (bLenghtYisZero) 
    iFlag += 2;
  else
    iMaxGrids *= iCtGridPerAxis;

  if (bLenghtZisZero)
    iFlag += 4; 
  else
    iMaxGrids *= iCtGridPerAxis;
  
  unsigned long ulGridsFacets =   10;

  double fFactorVolumen = 40.0;
  double fFactorArea    = 10.0;

  switch (iFlag)
  {
  case 0:
    {
      double fVolumen = fLenghtX * fLenghtY * fLenghtZ;

      double fVolumenGrid = (fVolumen * ulGridsFacets) / (fFactorVolumen * _ulCtElements);

      if ((fVolumenGrid * iMaxGrids) < fVolumen)
        fVolumenGrid = fVolumen / (float)iMaxGrids;

      double fLengthGrid = float(pow((float)fVolumenGrid,(float) 1.0f / 3.0f));

      _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
      _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
      _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
      
    } break;
  case 1:
    {
      _ulCtGridsX = 1; // bLenghtXisZero
      
      double fArea = fLenghtY * fLenghtZ;

      double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);

      if ((fAreaGrid * iMaxGrids) < fArea)
        fAreaGrid = fArea / (double)iMaxGrids;

      double fLengthGrid = double(sqrt(fAreaGrid));

      _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
      _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
    } break;
  case 2:
    {
      _ulCtGridsY = 1; // bLenghtYisZero
  
      double fArea = fLenghtX * fLenghtZ;

      double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);

      if ((fAreaGrid * iMaxGrids) < fArea)
        fAreaGrid = fArea / (double)iMaxGrids;

      double fLengthGrid = double(sqrt(fAreaGrid));

      _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
      _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
    } break;
  case 3:
    {
      _ulCtGridsX = 1; // bLenghtXisZero
      _ulCtGridsY = 1; // bLenghtYisZero
      _ulCtGridsZ = iMaxGrids; // bLenghtYisZero
    } break;
  case 4:
    {
      _ulCtGridsZ = 1; // bLenghtZisZero
      
      double fArea = fLenghtX * fLenghtY;

      double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);

      if ((fAreaGrid * iMaxGrids) < fArea)
        fAreaGrid = fArea / (float)iMaxGrids;

      double fLengthGrid = double(sqrt(fAreaGrid));

      _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
      _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
    } break;
  case 5:
    {
      _ulCtGridsX = 1; // bLenghtXisZero
      _ulCtGridsZ = 1; // bLenghtZisZero
      _ulCtGridsY = iMaxGrids; // bLenghtYisZero
    } break;
  case 6:
    {
      _ulCtGridsY = 1; // bLenghtYisZero
      _ulCtGridsZ = 1; // bLenghtZisZero
      _ulCtGridsX = iMaxGrids; // bLenghtYisZero
    } break;
  case 7:
    {
      _ulCtGridsX = iMaxGrids; // bLenghtXisZero
      _ulCtGridsY = iMaxGrids; // bLenghtYisZero
      _ulCtGridsZ = iMaxGrids; // bLenghtZisZero
    } break;
  }
}