Example #1
0
void FW::popLogFile(void)
{
    s_lock.enter();
    if (s_logFiles.getSize())
    {
        s_logStreams.getLast()->flush();
        delete s_logFiles.removeLast();
        delete s_logStreams.removeLast();
        if (!s_logFiles.getSize())
        {
            s_logFiles.reset();
            s_logStreams.reset();
        }
    }
    s_lock.leave();
}
Example #2
0
Vec2i GLContext::getStringSize(const String& str)
{
   // Split the string into lines.

    Array<String> lines;
    str.split('\n', lines, true);
    while (lines.getSize() && !lines.getLast().getLength())
        lines.removeLast();

    // Compute metrics.

    Vec2i strSize = 0;
    for (int i = 0; i < lines.getSize(); i++)
    {
        if (!lines[i].getLength())
            lines[i] = " "; // To avoid lineSize.y being zero.

    SIZE size;
		if (!GetTextExtentPoint32(m_memdc, lines[i].getPtr(), lines[i].getLength(), &size))
        failWin32Error("GetTextExtentPoint32");
        Vec2i lineSize(size.cx + m_vgFontMetrics.tmOverhang, size.cy);
        strSize.x = max(strSize.x, lineSize.x);
        strSize.y += lineSize.y;
}

	return strSize;
}
    static void shortenSubPath (Array<LineSection>& subPath, float amountAtStart, float amountAtEnd)
    {
        while (amountAtEnd > 0 && subPath.size() > 0)
        {
            LineSection& l = subPath.getReference (subPath.size() - 1);
            float dx = l.rx2 - l.rx1;
            float dy = l.ry2 - l.ry1;
            const float len = juce_hypot (dx, dy);

            if (len <= amountAtEnd && subPath.size() > 1)
            {
                LineSection& prev = subPath.getReference (subPath.size() - 2);
                prev.x2 = l.x2;
                prev.y2 = l.y2;
                subPath.removeLast();
                amountAtEnd -= len;
            }
            else
            {
                const float prop = jmin (0.9999f, amountAtEnd / len);
                dx *= prop;
                dy *= prop;
                l.rx1 += dx;
                l.ry1 += dy;
                l.lx2 += dx;
                l.ly2 += dy;
                break;
            }
        }

        while (amountAtStart > 0 && subPath.size() > 0)
        {
            LineSection& l = subPath.getReference (0);
            float dx = l.rx2 - l.rx1;
            float dy = l.ry2 - l.ry1;
            const float len = juce_hypot (dx, dy);

            if (len <= amountAtStart && subPath.size() > 1)
            {
                LineSection& next = subPath.getReference (1);
                next.x1 = l.x1;
                next.y1 = l.y1;
                subPath.remove (0);
                amountAtStart -= len;
            }
            else
            {
                const float prop = jmin (0.9999f, amountAtStart / len);
                dx *= prop;
                dy *= prop;
                l.rx2 -= dx;
                l.ry2 -= dy;
                l.lx1 -= dx;
                l.ly1 -= dy;
                break;
            }
        }
    }
Example #4
0
void FW::profilePop(void)
{
    if (!s_profileStarted || s_profileStack.getSize() == 0)
        return;
    if (!Thread::isMain())
        fail("profilePop() can only be used in the main thread!");

    if (s_profileStack.getSize() > 1)
        s_profileTimers[s_profileStack.getLast()].timer.end();
    s_profileStack.removeLast();
    if (s_profileStack.getSize() == 1)
        s_profileTimers[s_profileStack.getLast()].timer.end();
}
Example #5
0
void FW::popMemOwner(void)
{
#if FW_MEM_DEBUG
    U32 threadID = Thread::getID();
    Array<const char*>* stack = s_memOwnerStacks.search(threadID);
    if (stack)
    {
        stack->removeLast();
        if (!stack->getSize())
        {
            s_memOwnerStacks.remove(threadID);
            if (!s_memOwnerStacks.getSize())
                s_memOwnerStacks.reset();
        }
    }
#endif
}
int main() { 
    Array *array = new Array(20);
    for (int i = 0; i < 10; ++i) {
        array->addLast(i);
    }
    array->print();
    array->add(1,100);
    array->addFirst(-1);
    array->print();
    array->remove(2);
    array->print();
    array->removeElement(4);
    array->print();
    array->removeFirst();
    array->print();
    array->removeLast(); 
    array->print();
    return 0;
}
Example #7
0
Vec2i GLContext::drawLabel(const String& str, const Vec4f& pos, const Vec2f& align, U32 fgABGR, U32 bgABGR)
{
    // Split the string into lines.

    Array<String> lines;
    str.split('\n', lines, true);
    while (lines.getSize() && !lines.getLast().getLength())
        lines.removeLast();

    // Compute metrics.

    Vec2i strSize = 0;
    for (int i = 0; i < lines.getSize(); i++)
    {
        if (!lines[i].getLength())
            lines[i] = " "; // To avoid lineSize.y being zero.

        Vec2i lineSize = getStringSize(lines[i]);
        strSize.x = max(strSize.x, lineSize.x);
        strSize.y += lineSize.y;
    }

    // Empty or fully transparent => skip.

    if (strSize.x <= 0 || strSize.y <= 0 || ((fgABGR | bgABGR) & 0xFF000000) == 0)
        return strSize;

    // Initialize GL state.

    glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
    glEnable(GL_BLEND);
    glBlendEquation(GL_FUNC_ADD);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Draw each line.

    Vec4f fgColor = Vec4f::fromABGR(fgABGR);
    Vec4f bgColor = Vec4f::fromABGR(bgABGR);
    Vec2f linePos(0.0f, (F32)strSize.y);

    for (int i = 0; i < lines.getSize(); i++)
    {
        Vec2i lineSize = (lines.getSize() == 1) ? strSize : getStringSize(lines[i]);
        if (lineSize.x <= 0 || lineSize.y <= 0)
            continue;

        linePos.y -= (F32)lineSize.y;
        const Vec2i& texSize = uploadString(lines[i], lineSize);

        Vec4f tpos = m_vgXform * pos;
        Vec2f pixel = m_viewScale * tpos.w;
        tpos.x += (linePos.x - align.x * (F32)lineSize.x) * pixel.x;
        tpos.y += (linePos.y - align.y * (F32)strSize.y) * pixel.y;
        tpos.x = floor((tpos.x + tpos.w) / pixel.x + 0.5f) * pixel.x - tpos.w;
        tpos.y = floor((tpos.y + tpos.w) / pixel.y + 0.5f) * pixel.y - tpos.w;

        if (bgColor.w > 0.0f)
            for (int j = -1; j <= 1; j++)
                for (int k = -1; k <= 1; k++)
                    drawString(tpos + Vec4f(Vec2f((F32)j, (F32)k) * pixel, 0.0f, 0.0f), lineSize, texSize, bgColor);

        if (fgColor.w > 0.0f)
            drawString(tpos, lineSize, texSize, fgColor);
    }

    // Clean up.

    glPopAttrib();
    checkErrors();
    return strSize;
}
Fracture* VertPositionMutation::mutate(Fracture* fracture) {
  // get all verts that are not corners
  Array<Vertex*>* nonCorner = new Array<Vertex*>();
  for(int i=0;i<fracture->getVerts()->getSize();i++)
    if(!fracture->getVerts()->get(i)->getIsCorner())
      nonCorner->add(fracture->getVerts()->get(i));
  int numVerts = nonCorner->getSize();
  if(!numVerts) // if only corners return the original fracture
    return fracture;
  // get a random non-boundary vert
  int randVert = RNG::RandomInt(numVerts);
  Vertex* ranVert = nonCorner->get(randVert);
  // get the move amount and distance before making a jump
  real moveLimit = EvolutionSettings::getInstance()->getMaxMovePercent();
  real distBeforeJump = EvolutionSettings::getInstance()->getDistBeforeJump();
  if(ranVert->getBoundary()) {
    // move along boundary line
    Array<Edge*>* boundaryEdges = new Array<Edge*>();
    for(int i=0;i<ranVert->getEdges()->getSize();i++)
      if(ranVert->getEdges()->get(i)->getIsBoundary())
        boundaryEdges->add(ranVert->getEdges()->get(i));
    // choose a random edge to move by
    int randDir = RNG::RandomInt(boundaryEdges->getSize());
    Edge* edgeToMoveBy = boundaryEdges->get(randDir);
    // get the edge length
    real length = edgeToMoveBy->length();
    // if the length is too small move the other direction
    // in the future this is going to check if it can jump i.e
    // it will jump around a corner.
    if(length < distBeforeJump) {
      for(int i=0;i<boundaryEdges->getSize();i++) {
        // this should always work since there should be at least
        // two boundary edges attached
        if(boundaryEdges->get(i)!=edgeToMoveBy) {
          edgeToMoveBy = boundaryEdges->get(i);
          i = boundaryEdges->getSize();
        }
      }
      // recheck length and abort if the check fails
      real length = edgeToMoveBy->length();
      if(length < distBeforeJump)
        return fracture;
    }
    // get a random mutation value
    real mutateScale = RNG::RandomFloat(moveLimit);
    // Get the two points on the edge to move on
    Point2 firstPoint = ranVert->getLocation();
    Point2 secondPoint = edgeToMoveBy->getOtherPoint(ranVert->getID());
    // calculate the vert's new location
    Point2 slope = secondPoint.minus(firstPoint);
    slope.scale(mutateScale);
    Point2 newLoc = firstPoint.add(slope);
    // set the new location
    ranVert->setLocation(newLoc);
    // tell the verts edges about its new location
    ranVert->updateEdges();
    // clean up
    while(boundaryEdges->getSize())
      boundaryEdges->removeLast();
    delete boundaryEdges;
  } else {
    // maybe implement move along edges ???
    // move about faces using barycentric coordinates
    // get the faces containing the point
    Array<Face*>* facesWithVert = fracture->getFacesWithVertex(ranVert);
    // create a face containing all points around the vert
    Face* faceToMutateAround = new Face();
    for(int i=0;i<facesWithVert->getSize();i++) {
      Face* tmp = facesWithVert->get(i);
      for(int j=0;j<tmp->getEdges()->getSize();j++)
        if(!tmp->getEdges()->get(j)->eitherMatch(ranVert->getID()))
          faceToMutateAround->getEdges()->add(tmp->getEdges()->get(j)->copy());
      for(int j=0;j<tmp->getVerts()->getSize();j++)
        if(tmp->getVerts()->get(j)->getID() != ranVert->getID())
          faceToMutateAround->getVerts()->add(tmp->getVerts()->get(j)->copy(faceToMutateAround->getEdges()));
    }
    // create the container for the generated Tris
    Array<Tri*>* generatedTris = new Array<Tri*>();
    // detect if the face is convex or not
    faceToMutateAround->detectIfConvex();
    if(faceToMutateAround->getIsConvex()) {
      // TODO :: Do this the more efficient way
      // convex case mutation (easy)
      // generate tris
      for(int i=0;i<faceToMutateAround->getEdges()->getSize();i++)
        generatedTris->add(new Tri(faceToMutateAround->getEdges()->get(i),ranVert->getLocation(),ranVert->getID()));
      // create barycentric coordinates for mutation (2 * #tris)
      // TODO :: Combine this with the case below
      int numBarys = generatedTris->getSize()*2;
      real barys[numBarys];
      for(int i=0;i<numBarys;i++)
        barys[i] = RNG::RandomFloat(moveLimit);
      // apply mutations
      Point2 newPos;
      newPos.xpos = 0.0;
      newPos.ypos = 0.0;
      int pointID = ranVert->getID();
      for(int i=0;i<generatedTris->getSize();i++) {
        // get new position
        real baryOne = barys[i*2];
        real baryTwo = barys[i*2-1];
        real baryThree = 1.0 - baryOne - baryTwo;
        newPos = generatedTris->get(i)->interpolatePosition(baryOne,baryTwo,baryThree);
        // update the position in all the remaining tris
        for(int j=i;j<generatedTris->getSize();j++)
          generatedTris->get(j)->updatePosition(pointID,newPos);
      }
      // set new position of vert
      ranVert->setLocation(newPos);
      // update edges
      ranVert->updateEdges();
      // clean up
    } else {
      // concave case mutation (harder)
      // create collection for trimesh shell
      Array<Vertex*>* vertsInView = new Array<Vertex*>();
      Array<Vertex*>* sortedVertsInView = new Array<Vertex*>();
      Array<Edge*>* trimeshShell = new Array<Edge*>();
      // get all verts in view
      for(int i=0;i<faceToMutateAround->getVerts()->getSize();i++) {
        Vertex* vert = faceToMutateAround->getVerts()->get(i);
        // create a temp edge to check for intersections
        Edge* tmpEdge = new Edge(ranVert->getLocation(),vert->getLocation());
        bool noIntersection = true;
        // check if intersections
        for(int i=0;i<faceToMutateAround->getEdges()->getSize();i++)
          if(faceToMutateAround->getEdges()->get(i)->intersects(tmpEdge))
            noIntersection = false;
        // if no intersections add it to the list of verts in view
        if(noIntersection)
          vertsInView->add(vert);
        // Note :: vert is still a copy
        // clean up
        delete tmpEdge;
      }
      // sort verts
      Array<Integer>* sortedIDs = faceToMutateAround->sortVertIDsByPath();
      for(int i=0;i<sortedIDs->getSize();i++)
        for(int j=0;j<vertsInView->getSize();i++)
          if(vertsInView->get(j)->getID() == sortedIDs->get(i).val) {
            sortedVertsInView->add(vertsInView->get(j));
            j = vertsInView->getSize();
          }
      // create shell from verts
      for(int i=0;i<sortedVertsInView->getSize();i++) {
        Vertex* one = sortedVertsInView->get(i);
        Vertex* two = i==sortedVertsInView->getSize()-1
          ? sortedVertsInView->get(0) : sortedVertsInView->get(i+1);
        Edge* newEdge = new Edge(one->getLocation(),two->getLocation(),one->getID(),two->getID());
        trimeshShell->add(newEdge);
      }
      // generate tris
      for(int i=0;i<trimeshShell->getSize();i++)
        generatedTris->add(new Tri(trimeshShell->get(i),ranVert->getLocation(),ranVert->getID()));
      // create barycentric coordinates for mutation (Only 2 for this case)
      // TODO :: Combine this with the case above
      //int numBarys = generatedTris->getSize()*2;
      int numBarys = 2;
      real barys[numBarys];
      for(int i=0;i<numBarys;i++)
        barys[i] = RNG::RandomFloat(moveLimit);
      // apply mutations
      Point2 newPos;
      newPos.xpos = 0.0;
      newPos.ypos = 0.0;

      int pointID = ranVert->getID();
      int ranTri = RNG::RandomInt(generatedTris->getSize());

      //for(int i=0;i<generatedTris->getSize();i++) {

      // get new position
      //real baryOne = barys[i*2];
      //real baryTwo = barys[i*2-1];
      real baryOne = barys[0];
      real baryTwo = barys[1];
      real baryThree = 1.0 - baryOne - baryTwo;
      newPos = generatedTris->get(ranTri)->interpolatePosition(baryOne,baryTwo,baryThree);

      // update the position in all the remaining tris (skip for this step)
      //  for(int j=i;j<generatedTris->getSize();j++)
      //    generatedTris->get(j)->updatePosition(pointID,newPos);

      //}

      // set new position of vert
      ranVert->setLocation(newPos);
      // update edges
      ranVert->updateEdges();
      // clean up
      while(vertsInView->getSize())
        vertsInView->removeLast();
      while(sortedIDs->getSize())
        sortedIDs->removeLast();
      while(sortedVertsInView->getSize())
        sortedVertsInView->removeLast();
      while(trimeshShell->getSize())
        delete trimeshShell->removeLast();
      delete vertsInView;
      delete trimeshShell;
      delete sortedVertsInView;
      delete sortedIDs;
    }
    // clean up
    while(nonCorner->getSize())
      nonCorner->removeLast();
    while(facesWithVert->getSize())
      facesWithVert->removeLast();
    while(generatedTris->getSize())
      delete generatedTris->removeLast();
    while(faceToMutateAround->getVerts()->getSize())
      delete faceToMutateAround->getVerts()->removeLast();
    while(faceToMutateAround->getEdges()->getSize())
      delete faceToMutateAround->getEdges()->removeLast();
    delete faceToMutateAround;
    delete generatedTris;
    delete facesWithVert;
    delete nonCorner;
  }
  return fracture;
}