Exemple #1
0
  /// Calculate a bound box where the faces parallel to the x-y-plane are
  /// quadratic
  Vector3R maxQuadraticBoundingBox(Real scale = 1) const
  {
    // the center of the bounding box
    Vector3R center = R(0.5) * (mMinBoundingBox + mMaxBoundingBox);

    // the diagonal of the bounding box
    Vector3R diagonal = mMaxBoundingBox - mMinBoundingBox;

    // the greatest extension of the bounding box in the x-y-plane, this will
    // be the edge length of the square.
    Real maxExtension = std::max(diagonal.x(), diagonal.y());
    return Vector3R(center.x() + maxExtension * R(0.5) * scale,
                    center.y() + maxExtension * R(0.5) * scale,
                    mMaxBoundingBox.z());
  }
void SampleSlice::compute() {
  // Allocate space
  resize((steps[0] + 2) * (steps[1] + 2), -std::numeric_limits<real>::max());

  // Compute offsets
  const Vector2R &rmin = bbox.getMin();
  Vector2R scale = Vector2R(bbox.getWidth() / steps.x(),
                            bbox.getLength() / steps.y());
  Vector3R p = Vector3R(0, 0, z);

  // TODO Culling?

  // Sample
  //real *array = (*this)[0];
  for (unsigned y = 0; y < steps.y() + 2; y++) {
    p.y() = rmin.y() + y * scale.y();

    for (unsigned x = 0; x < steps.x() + 2; x++) {
      p.x() = rmin.x() + x * scale.x();

      // TODO func.getSample() was removed
      //*array++ = func.getSample(p);
    }
  }
}
Exemple #3
0
real ConicSweep::depth(const Vector3R &A, const Vector3R &B,
                       const Vector3R &P) const {
    const double Ax = A.x(), Ay = A.y(), Az = A.z();
    const double Bx = B.x(), By = B.y(), Bz = B.z();
    const double Px = P.x(), Py = P.y(), Pz = P.z();

    // Check z-height
    if (Pz < min(Az, Bz) || max(Az, Bz) + l < Pz) return -1;

    // epsilon * beta^2 + gamma * beta + rho = 0
    double epsilon = sqr(Bx - Ax) + sqr(By - Ay) - sqr(Tm * (Bz - Az));

    // If this is a straight up and down move of a cylindrical tool choose
    // a fake arbitrarily small epsilon.
    if (epsilon == 0 && Bz != Az && Tm == 0) epsilon = 0.000000001;

    const double gamma = (Ax - Px) * (Bx - Ax) + (Ay - Py) * (By - Ay) +
                         (sqr(Tm) * (Az - Pz) - Tm * rb) * (Az - Bz);
    const double rho = sqr(Ax - Px) + sqr(Ay - Py) - sqr(Tm * (Az - Pz) - rb);
    const double sigma = sqr(gamma) - epsilon * rho;

    // Check if solution is valid
    if (epsilon == 0 || sigma < 0) return -1;

    double beta = (-gamma - sqrt(sigma)) / epsilon; // Quadradic equation

    // Check if z-heights make sense
    const double Qz = (Bz - Az) * beta + Az;

    // Check if the point is cut by the flat top or bottom
    if (Pz < Qz || Qz + l < Pz) {
        beta = Pz / (Bz - Az); // E is on AB at z-height

        // Compute squared distance to E on XY plane
        const double Ex = beta * (Bx - Ax) + Ax;
        const double Ey = beta * (By - Ay) + Ay;
        const double d2 = sqr(Ex - Px) + sqr(Ey - Py);

        if (Pz < Qz && rb * rb < d2) return -1;
        if (Qz + l < Pz && rt * rt < d2) return -1;
    }

    // Check that it's on the line segment
    if (beta < 0 || 1 < beta) return -1;

    return 1;
}
Exemple #4
0
void Project::updateAutomaticWorkpiece(ToolPath &path) {
  if (!getAutomaticWorkpiece()) return;
  setAutomaticWorkpiece(true);
  Rectangle3R wpBounds;

  // Guess workpiece bounds from cutting moves
  vector<SmartPointer<Sweep> > sweeps;
  vector<Rectangle3R> bboxes;

  for (unsigned i = 0; i < path.size(); i++) {
    const Move &move = path.at(i);

    if (move.getType() == MoveType::MOVE_RAPID) continue;

    int tool = move.getTool();
    if (tool < 0) continue;

    if (sweeps.size() <= (unsigned)tool) sweeps.resize(tool + 1);
    if (sweeps[tool].isNull()) sweeps[tool] = tools.get(tool).getSweep();

    sweeps[tool]->getBBoxes(move.getStartPt(), move.getEndPt(), bboxes, 0);
  }

  for (unsigned i = 0; i < bboxes.size(); i++) wpBounds.add(bboxes[i]);

  if (wpBounds == Rectangle3R()) return;

  // Start from z = 0
  Vector3R bMin = wpBounds.getMin();
  Vector3R bMax = wpBounds.getMax();
  wpBounds = Rectangle3R(bMin, Vector3R(bMax.x(), bMax.y(), 0));

  // At least 2mm thick
  if (wpBounds.getHeight() < 2)
    wpBounds.add(Vector3R(bMin.x(), bMin.y(), bMin.z() - 2));

  if (wpBounds.isReal()) {
    // Margin
    Vector3R margin =
      wpBounds.getDimensions() * getWorkpieceMargin() / 100.0;
    wpBounds.add(wpBounds.getMin() - margin);
    wpBounds.add(wpBounds.getMax() + Vector3R(margin.x(), margin.y(), 0));

    setWorkpieceBounds(wpBounds);
  }
}
Exemple #5
0
void QtWin::updateToolPathBounds() {
  Rectangle3R bounds = *toolPath;
  Vector3R bMin = bounds.getMin();
  Vector3R bMax = bounds.getMax();
  Vector3R bDim = bounds.getDimensions();

  setUnitLabel(ui->toolPathBoundsXMinLabel, bMin.x());
  setUnitLabel(ui->toolPathBoundsXMaxLabel, bMax.x());
  setUnitLabel(ui->toolPathBoundsXDimLabel, bDim.x());

  setUnitLabel(ui->toolPathBoundsYMinLabel, bMin.y());
  setUnitLabel(ui->toolPathBoundsYMaxLabel, bMax.y());
  setUnitLabel(ui->toolPathBoundsYDimLabel, bDim.y());

  setUnitLabel(ui->toolPathBoundsZMinLabel, bMin.z());
  setUnitLabel(ui->toolPathBoundsZMaxLabel, bMax.z());
  setUnitLabel(ui->toolPathBoundsZDimLabel, bDim.z());
}
Exemple #6
0
RBuffer2D Sample::projectedPotential(int64_t cols, int64_t rows,
                                     Vector3R minCoords, Vector3R maxCoords,
                                     Real cutoff,
                                     const std::string& parametrization) const
{
  RBuffer2D projPotential(cols, rows, R(0.0));

  auto periodicTable = FormFactorParametrization::create(parametrization);

  const Real cutoffSqr = cutoff * cutoff;

  for (auto atom : mAtoms)
  {
    Vector3R atomPosition = atom.position();
    const Element& element = periodicTable->element(atom.atomicNumber(),
                                                    atom.charge());

    #pragma omp parallel for
    for (int64_t j = 0; j < rows; ++j)
    {
      const Real fracY = static_cast<Real>(j) / static_cast<Real>(rows);
      const Real y = lerp(minCoords.y(), maxCoords.y(), fracY);
      const Real deltaYSqr = powerOf<2>(y - atomPosition.y());

      if (deltaYSqr > cutoffSqr)
        continue;

      for (int64_t i = 0; i < cols; ++i)
      {
        const Real fracX = static_cast<Real>(i) / static_cast<Real>(cols);
        const Real x = lerp(minCoords.x(), maxCoords.x(), fracX);
        const Real deltaXSqr = powerOf<2>(x - atomPosition.x());
        const Real rhoSqr = deltaXSqr + deltaYSqr;

        if (rhoSqr > cutoffSqr)
          continue;

        projPotential.pixel(i, j) += element.projectedPotential(rhoSqr);
      }
    }
  }

  return projPotential;
}
Exemple #7
0
void QtWin::updateWorkpieceBounds() {
  if (project.isNull()) return;

  Rectangle3R bounds = project->getWorkpieceBounds();
  Vector3R bMin = bounds.getMin();
  Vector3R bMax = bounds.getMax();
  Vector3R bDim = bounds.getDimensions();

  setUnitLabel(ui->workpieceBoundsXMinLabel, bMin.x());
  setUnitLabel(ui->workpieceBoundsXMaxLabel, bMax.x());
  setUnitLabel(ui->workpieceBoundsXDimLabel, bDim.x());

  setUnitLabel(ui->workpieceBoundsYMinLabel, bMin.y());
  setUnitLabel(ui->workpieceBoundsYMaxLabel, bMax.y());
  setUnitLabel(ui->workpieceBoundsYDimLabel, bDim.y());

  setUnitLabel(ui->workpieceBoundsZMinLabel, bMin.z());
  setUnitLabel(ui->workpieceBoundsZMaxLabel, bMax.z());
  setUnitLabel(ui->workpieceBoundsZDimLabel, bDim.z());
}
void MultisliceParameters::setBox(const Vector3R& minBox,
                                  const Vector3R& maxBox,
                                  Real deltaZ)
{
  mMinBox = minBox;
  mMaxBox = maxBox;

  setSize(maxBox.x() - minBox.x(), maxBox.y() - minBox.y());
  mDepth = maxBox.z() - minBox.z();
  mDeltaZ = deltaZ;

  if (mDeltaZ <= 0)
    AURORA_THROW(EInvalidParameter, "deltaZ must be positive");

  mMinBoxes.clear();
  Real z = minBox.z();
  const Real maxZ = maxBox.z();

  mMinBoxes.push_back(Vector3R(minBox.x(), minBox.y(), z));

  do
  {
    z += mDeltaZ;
    mMinBoxes.push_back(Vector3R(minBox.x(), minBox.y(), z));
  }
  while (z < maxZ);

  if (verbosity >= 2)
  {
    for (size_t i = 0; i < numSlices(); ++i)
    {
      std::cout << " slice " << i << " (z1 = " << zStart(i) << ", z2 = "
                << zEnd(i) << ")\n";
    }
  }

  if (verbosity >= 1)
    std::cout << "Number of Slices: " << numSlices() << std::endl;
}
void Viewer::draw(const View &view) {
  init();

  SmartPointer<Surface> surface = view.surface;

  // Setup view port
  Rectangle3R bounds = view.path->getBounds();
  if (!surface.isNull()) bounds.add(surface->getBounds());
  bounds.add(view.workpiece->getBounds());
  view.glDraw(bounds);

  // Workpiece bounds
  if (!view.isFlagSet(View::SHOW_WORKPIECE_FLAG) &&
      view.isFlagSet(View::SHOW_WORKPIECE_BOUNDS_FLAG)) {
    glEnable(GL_DEPTH_TEST);
    glLineWidth(1);
    glColor4f(1, 1, 1, 0.5); // White

    BoundsView(view.workpiece->getBounds()).draw();
  }

  // Enable Lighting
  view.setLighting(true);

  // Tool path
  if (view.isFlagSet(View::SHOW_PATH_FLAG)) view.path->draw();
  else view.path->update();

  // Model
  if (view.isFlagSet(View::SHOW_WORKPIECE_FLAG | View::SHOW_SURFACE_FLAG)) {
    const float ambient[] = {12.0 / 255, 45.0 / 255,  83.0 / 255, 1.00};
    const float diffuse[] = {16.0 / 255, 59.0 / 255, 108.0 / 255, 1.00};

    glDisable(GL_COLOR_MATERIAL);
    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

    view.setWire(view.isFlagSet(View::WIRE_FLAG));

    if (!surface.isNull() && view.isFlagSet(View::SHOW_SURFACE_FLAG))
      surface->draw();

    if (view.isFlagSet(View::SHOW_WORKPIECE_FLAG)) view.workpiece->draw();

    glEnable(GL_COLOR_MATERIAL);

    view.setWire(false);

    if (view.isFlagSet(View::SHOW_NORMALS_FLAG)) {
      glColor4f(1.0, 1.0, 0, 0.6);
      surface->drawNormals();
    }
  }

  // Bounding box tree
  // TODO revive this
  //if (view.isFlagSet(View::SHOW_BBTREE_FLAG)) cutWP->drawBB();

  // Tool
  if (view.isFlagSet(View::SHOW_TOOL_FLAG) && !view.path->getPath().isNull()) {
    Vector3R currentPosition = view.path->getPosition();
    glTranslatef(currentPosition.x(), currentPosition.y(),
                 currentPosition.z());

    ToolTable &tools = *view.path->getPath()->getTools();
    const Move &move = view.path->getMove();
    const Tool &tool = *tools.get(move.getTool());
    double diameter = tool.getDiameter();
    double radius = tool.getRadius();
    double length = tool.getLength();
    ToolShape shape = tool.getShape();

    if (radius <= 0) {
      // Default tool specs
      radius = 25.4 / 8;
      shape = ToolShape::TS_CONICAL;

      glColor4f(1, 0, 0, 1); // Red

    } else glColor4f(1, 0.5, 0, 1); // Orange

    if (length <= 0) length = 50;

    switch (shape) {
    case ToolShape::TS_SPHEROID: {
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix();
      glTranslatef(0, 0, length / 2);
      glScaled(1, 1, length / diameter);
      gluSphere((GLUquadric *)toolQuad, radius, 100, 100);
      glPopMatrix();
      break;
    }

    case ToolShape::TS_BALLNOSE:
      glPushMatrix();
      glTranslatef(0, 0, radius);
      gluSphere((GLUquadric *)toolQuad, radius, 100, 100);
      drawCylinder((GLUquadric *)toolQuad, radius, radius, length - radius);
      glPopMatrix();
      break;

    case ToolShape::TS_SNUBNOSE:
      drawCylinder((GLUquadric *)toolQuad, tool.getSnubDiameter() / 2, radius,
                   length);
      break;

    case ToolShape::TS_CONICAL:
      drawCylinder((GLUquadric *)toolQuad, 0, radius, length);
      break;

    case ToolShape::TS_CYLINDRICAL:
    default:
      drawCylinder((GLUquadric *)toolQuad, radius, radius, length);
      break;
    }
  }

  // Disable Lighting
  view.setLighting(false);

  CHECK_GL_ERROR("");
}
Exemple #10
0
bool ConicSweep::contains(const Vector3R &start, const Vector3R &end,
                          const Vector3R &p) const {
  real x1 = start.x();
  real y1 = start.y();
  real z1 = start.z();

  real x2 = end.x();
  real y2 = end.y();
  real z2 = end.z();

  real x = p.x();
  real y = p.y();
  real z = p.z();

  // Z height range
  real minZ = z1 < z2 ? z1 : z2;
  real maxZ = z1 < z2 ? z2 : z1;
  if (z < minZ || maxZ + length < z) return false;

  real xLen = x2 - x1;
  real yLen = y2 - y1;
  real zLen = z2 - z1;

  bool horizontal = z1 == z2;
  bool vertical = x1 == x2 && y1 == y2;
  bool conical = radius1 != radius2;

  Vector2R q(x, y);
  Vector2R p1(x1, y1);
  Vector2R p2(x2, y2);

  real conicSlope = conical ? (radius1 - radius2) / length : 0;

  // Simple cases for horizontal and vertical moves
  real r2;
  if (conical) {
    if (z <= minZ) r2 = radius2;
    else if (maxZ + length <= z) r2 = radius1;
    else r2 = (z - minZ) * conicSlope + radius2;
    r2 *= r2;

  } else r2 = radius1 * radius1;

  if (vertical) return p1.distanceSquared(q) < r2;

  Vector2R c = Segment2R(p1, p2).closest(q);
  if (horizontal) return q.distanceSquared(c) < r2;

  // Slanting move
  // Find the ends of the line segment which passes through the move's
  // internal parallelogram at the z-height of p
  int count = 0;
  Vector2R s[2];

  // First check the verticals
  if (z1 <= z && z <= z1 + length) s[count++] = p1;
  if (z2 <= z && z <= z2 + length) s[count++] = p2;

  // Check top & bottom lines of the parallelogram
  if (count < 2) {
    real delta;
    if (minZ + length < z) delta = (z - minZ + length) / std::fabs(z2 - z1);
    else delta = (z - minZ) / std::fabs(z2 - z1);
    if (z1 < z2) s[count++] = p1 + (p2 - p1) * delta;
    else s[count++] = p2 + (p1 - p2) * delta;
  }

  // Find the closest point to p on the z-line segment
  c = Segment2R(s[0], s[1]).closest(q);

  // Check cone tool height for closest point
  if (conical) {
    // NOTE Slanting move so one or both of xLen and yLen is not zero
    real h = 0;
    if (xLen) h = z - (z1 + (c.x() - x1) / xLen * zLen);
    else if (yLen) h = z - (z1 + (c.y() - y1) / yLen * zLen);

    if (h < length) {
      r2 = h * conicSlope + radius2;
      r2 *= r2;
    }
  }

  real cDistSq = q.distanceSquared(c);
  if (cDistSq < r2) return true;
  if (!conical) return false;

  // Look up and down the z-line for a closer point on the cone
  real maxRadius = radius1 < radius2 ? radius2 : radius1;
  real l2 = maxRadius * maxRadius - cDistSq;
  real l = sqrt(l2); // How far to look
  Vector2R n = (s[1] - s[0]).normalize(); // Direction vector

  Vector2R a = c.distanceSquared(s[1]) < l2 ? s[1] : (c + n * l);
  Vector2R b = c.distanceSquared(s[0]) < l2 ? s[0] : (c - n * l);
  real aH = 0;
  real bH = 0;

  if (xLen) {
    aH = z - (z1 + (a.x() - x1) / xLen * zLen);
    bH = z - (z1 + (b.x() - x1) / xLen * zLen);

  } else if (yLen) {
    aH = z - (z1 + (a.y() - y1) / yLen * zLen);
    bH = z - (z1 + (b.y() - y1) / yLen * zLen);
  }

  real h = aH < bH ? bH : aH;
  c = aH < bH ? b : a;
  r2 = h * conicSlope + radius2;
  r2 *= r2;

  return q.distanceSquared(c) < r2;
}
Exemple #11
0
void ViewPort::glDraw(const Rectangle3R &bbox) const {
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  // Background
  glBegin(GL_QUADS);
  glColor3ub(0x25, 0x30, 0x40);
  glVertex2f(-1, -1);
  glVertex2f(1, -1);
  glColor3ub(0x5, 0x5, 0x5);
  glVertex2f(1, 1);
  glVertex2f(-1, 1);
  glEnd();

  // Compute "radius"
  Vector3R dims = bbox.getDimensions();
  real radius = dims.x() < dims.y() ? dims.y() : dims.x();
  radius = dims.z() < radius ? radius : dims.z();

  // Perspective
  gluPerspective(45, (float)width / height, 1, 100000);

  // Translate
  glTranslatef(translation.x() * radius / zoom,
               translation.y() * radius / zoom, 0);

  // Scale
  gluLookAt(0, 0, radius / zoom, 0, 0, 0, 0, 1, 0);

  glMatrixMode(GL_MODELVIEW);

  // Rotate
  glRotated(rotation[0], rotation[1], rotation[2], rotation[3]);

  // Center
  Vector3R center = bbox.getCenter();
  glTranslatef(-center.x(), -center.y(), -center.z());

  // Axes
  if (axes) {
    double length = (bbox.getWidth() + bbox.getLength() + bbox.getHeight()) / 3;
    length *= 0.1;
    double radius = length / 20;

    setLighting(true);

    for (int axis = 0; axis < 3; axis++)
      for (int up = 0; up < 2; up++)
        drawAxis(axis, up, length, radius);

    setLighting(false);
  }
  
  // Bounds
  if (bounds) {
    glEnable(GL_LINE_STIPPLE);
    glLineStipple(1, 0x5555);
    glLineWidth(1);
    glColor4f(1, 1, 1, 0.5); // White

    BoundsView(bbox).draw();

    glDisable(GL_LINE_STIPPLE);
  }
}
Exemple #12
0
void CuboidView::draw() {
  if (bounds == Rectangle3R()) return;

  static float vertices[] = {
    1, 0, 0,  1, 0, 1,  1, 1, 1,  1, 1, 0,
    0, 0, 0,  0, 0, 1,  0, 1, 1,  0, 1, 0,

    0, 1, 0,  1, 1, 0,  1, 1, 1,  0, 1, 1,
    0, 0, 0,  1, 0, 0,  1, 0, 1,  0, 0, 1,

    0, 0, 1,  1, 0, 1,  1, 1, 1,  0, 1, 1,
    0, 0, 0,  1, 0, 0,  1, 1, 0,  0, 1, 0,
  };

  static float normals[] = {
     1,  0,  0,   1,  0,  0,   1,  0,  0,   1,  0,  0,
    -1,  0,  0,  -1,  0,  0,  -1,  0,  0,  -1,  0,  0,

     0,  1,  0,   0,  1,  0,   0,  1,  0,   0,  1,  0,
     0, -1,  0,   0, -1,  0,   0, -1,  0,   0, -1,  0,

     0,  0,  1,   0,  0,  1,   0,  0,  1,   0,  0,  1,
     0,  0, -1,   0,  0, -1,   0,  0, -1,   0,  0, -1,
  };

  if (glGenBuffers) {
    if (!vertexVBuf) {
      glGenBuffers(1, &vertexVBuf);
      glBindBuffer(GL_ARRAY_BUFFER, vertexVBuf);
      glBufferData(GL_ARRAY_BUFFER, 24 * 3 * sizeof(float),
                   vertices, GL_STATIC_DRAW);

      glGenBuffers(1, &normalVBuf);
      glBindBuffer(GL_ARRAY_BUFFER, normalVBuf);
      glBufferData(GL_ARRAY_BUFFER, 24 * 3 * sizeof(float),
                   normals, GL_STATIC_DRAW);
    }

    glBindBuffer(GL_ARRAY_BUFFER, vertexVBuf);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, normalVBuf);
    glNormalPointer(GL_FLOAT, 0, 0);

  } else {
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glNormalPointer(GL_FLOAT, 0, normals);
  }

  glEnable(GL_NORMALIZE);
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_NORMAL_ARRAY);

  glPushMatrix();

  Vector3R bMin = bounds.getMin();
  Vector3R bDim = bounds.getDimensions();
  glTranslated(bMin.x(), bMin.y(), bMin.z());
  glScaled(bDim.x(), bDim.y(), bDim.z());

  glDrawArrays(GL_QUADS, 0, 24);

  glPopMatrix();

  glDisableClientState(GL_NORMAL_ARRAY);
  glDisableClientState(GL_VERTEX_ARRAY);
}