<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "test_bits.hpp"
#include <proton/uuid.hpp>
#include <proton/io/connection_engine.hpp>
#include <proton/handler.hpp>
#include <proton/types_fwd.hpp>
#include <proton/link.hpp>
#include <deque>
#include <algorithm>

#if __cplusplus < 201103L
#define override
#endif

using namespace proton::io;
using namespace proton;
using namespace test;
using namespace std;

typedef std::deque<char> byte_stream;

/// In memory connection_engine that reads and writes from byte_streams
struct in_memory_engine : public connection_engine {

    byte_stream& reads;
    byte_stream& writes;

    in_memory_engine(byte_stream& rd, byte_stream& wr, handler &h,
                     const connection_options &opts = connection_options()) :
        connection_engine(h, opts), reads(rd), writes(wr) {}

    void do_read() {
        mutable_buffer rbuf = read_buffer();
        size_t size = std::min(reads.size(), rbuf.size);
        if (size) {
            copy(reads.begin(), reads.begin()+size, static_cast<char*>(rbuf.data));
            read_done(size);
            reads.erase(reads.begin(), reads.begin()+size);
        }
    }

    void do_write() {
        const_buffer wbuf = write_buffer();
        if (wbuf.size) {
            writes.insert(writes.begin(),
                          static_cast<const char*>(wbuf.data),
                          static_cast<const char*>(wbuf.data) + wbuf.size);
            write_done(wbuf.size);
        }
    }

    void process() { do_read(); do_write(); dispatch(); }
};

/// A pair of engines that talk to each other in-memory.
struct engine_pair {
    byte_stream ab, ba;
    connection_engine::container cont;

    in_memory_engine a, b;

    engine_pair(handler& ha, handler& hb,
                const connection_options& ca = connection_options(),
                const connection_options& cb = connection_options()) :
        a(ba, ab, ha, ca), b(ab, ba, hb, cb) {}

    void process() { a.process(); b.process(); }
};

template <class S> typename S::value_type quick_pop(S& s) {
    ASSERT(!s.empty());
    typename S::value_type x = s.front();
    s.pop_front();
    return x;
}

/// A handler that records incoming endpoints, errors etc.
struct record_handler : public handler {
    std::deque<proton::internal::link> links;
    std::deque<proton::session> sessions;
    std::deque<std::string> errors, transport_errors, connection_errors;

    void on_receiver_open(receiver &l) override {
        links.push_back(l);
    }

    void on_sender_open(sender &l) override {
        links.push_back(l);
    }

    void on_session_open(session &s) override {
        sessions.push_back(s);
    }

    void on_transport_error(transport& t) override {
        transport_errors.push_back(t.error().what());
    }

    void on_connection_error(connection& c) override {
        connection_errors.push_back(c.error().what());
    }

    void on_unhandled_error(const proton::error_condition& c) override {
        errors.push_back(c.what());
    }
};

void test_engine_prefix() {
    // Set container ID and prefix explicitly
    record_handler ha, hb;
    engine_pair e(ha, hb,
                  connection_options().container_id("a").link_prefix("x/"),
                  connection_options().container_id("b").link_prefix("y/"));
    e.a.connection().open();
    ASSERT_EQUAL("a", e.a.connection().container_id());
    e.b.connection().open();
    ASSERT_EQUAL("b", e.b.connection().container_id());

    e.a.connection().open_sender("x");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("x/1", quick_pop(ha.links).name());
    ASSERT_EQUAL("x/1", quick_pop(hb.links).name());

    e.a.connection().open_receiver("");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("x/2", quick_pop(ha.links).name());
    ASSERT_EQUAL("x/2", quick_pop(hb.links).name());

    e.b.connection().open_receiver("");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("y/1", quick_pop(ha.links).name());
    ASSERT_EQUAL("y/1", quick_pop(hb.links).name());
}

void test_container_prefix() {
    /// Let the container set the options.
    record_handler ha, hb;
    connection_engine::container ca("a"), cb("b");
    engine_pair e(ha, hb, ca.make_options(), cb.make_options());

    ASSERT_EQUAL("a", e.a.connection().container_id());
    ASSERT_EQUAL("b", e.b.connection().container_id());

    e.a.connection().open();
    sender s = e.a.connection().open_sender("x");
    ASSERT_EQUAL("1/1", s.name());

    while (ha.links.empty() || hb.links.empty()) e.process();

    ASSERT_EQUAL("1/1", quick_pop(ha.links).name());
    ASSERT_EQUAL("1/1", quick_pop(hb.links).name());

    e.a.connection().open_receiver("y");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("1/2", quick_pop(ha.links).name());
    ASSERT_EQUAL("1/2", quick_pop(hb.links).name());

    // Open a second connection in each container, make sure links have different IDs.
    record_handler ha2, hb2;
    engine_pair e2(ha2, hb2, ca.make_options(), cb.make_options());

    ASSERT_EQUAL("a", e2.a.connection().container_id());
    ASSERT_EQUAL("b", e2.b.connection().container_id());

    e2.b.connection().open();
    receiver r = e2.b.connection().open_receiver("z");
    ASSERT_EQUAL("2/1", r.name());

    while (ha2.links.empty() || hb2.links.empty()) e2.process();

    ASSERT_EQUAL("2/1", quick_pop(ha2.links).name());
    ASSERT_EQUAL("2/1", quick_pop(hb2.links).name());
};

void test_endpoint_close() {
    // Make sure conditions are sent to the remote end.

    record_handler ha, hb;
    engine_pair e(ha, hb);
    e.a.connection().open();
    e.a.connection().open_sender("x");
    e.a.connection().open_receiver("y");
    while (ha.links.size() < 2 || hb.links.size() < 2) e.process();
    proton::internal::link ax = quick_pop(ha.links), ay = quick_pop(ha.links);
    proton::internal::link bx = quick_pop(hb.links), by = quick_pop(hb.links);

    // Close a link
    ax.close(proton::error_condition("err", "foo bar"));
    while (!bx.closed()) e.process();
    proton::error_condition c = bx.error();
    ASSERT_EQUAL("err", c.name());
    ASSERT_EQUAL("foo bar", c.description());
    ASSERT_EQUAL("err: foo bar", c.what());

    // Close a link with an empty condition
    ay.close(proton::error_condition());
    while (!by.closed()) e.process();
    ASSERT(by.error().empty());

    // Close a connection
    connection ca = e.a.connection(), cb = e.b.connection();
    ca.close(proton::error_condition("conn", "bad connection"));
    while (!cb.closed()) e.process();
    ASSERT_EQUAL("conn: bad connection", cb.error().what());
    ASSERT_EQUAL(1, hb.connection_errors.size());
    ASSERT_EQUAL("conn: bad connection", hb.connection_errors.front());
}

void test_transport_close() {
    // Make sure conditions are sent to the remote end.
    record_handler ha, hb;
    engine_pair e(ha, hb);
    e.a.connection().open();
    while (!e.b.connection().active()) e.process();

    e.a.close(proton::error_condition("oops", "engine failure"));
    // Closed but we still have output data to flush so a.dispatch() is true.
    ASSERT(e.a.dispatch());
    do { e.process(); } while (e.b.dispatch());
    ASSERT_EQUAL(1, hb.errors.size());
    ASSERT_EQUAL("oops: engine failure", hb.errors.front());
    // Connection and transport share the same error.
    ASSERT_EQUAL(proton::error_condition("oops", "engine failure"),e.b.connection().error());
    ASSERT_EQUAL(proton::error_condition("oops", "engine failure"),e.b.transport().error());
    // But connectoin was never protocol closed.
    ASSERT(!e.b.connection().closed());
    ASSERT_EQUAL(0, hb.connection_errors.size());
    ASSERT_EQUAL(1, hb.transport_errors.size());
    ASSERT_EQUAL("oops: engine failure", hb.transport_errors.front());
}

int main(int, char**) {
    int failed = 0;
    RUN_TEST(failed, test_engine_prefix());
    RUN_TEST(failed, test_container_prefix());
    RUN_TEST(failed, test_endpoint_close());
    return failed;
}
<commit_msg>PROTON-1161: Fixed transport_close_test() in engine_test.cpp<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "test_bits.hpp"
#include <proton/uuid.hpp>
#include <proton/io/connection_engine.hpp>
#include <proton/handler.hpp>
#include <proton/types_fwd.hpp>
#include <proton/link.hpp>
#include <deque>
#include <algorithm>

#if __cplusplus < 201103L
#define override
#endif

using namespace proton::io;
using namespace proton;
using namespace test;
using namespace std;

typedef std::deque<char> byte_stream;

/// In memory connection_engine that reads and writes from byte_streams
struct in_memory_engine : public connection_engine {

    byte_stream& reads;
    byte_stream& writes;

    in_memory_engine(byte_stream& rd, byte_stream& wr, handler &h,
                     const connection_options &opts = connection_options()) :
        connection_engine(h, opts), reads(rd), writes(wr) {}

    void do_read() {
        mutable_buffer rbuf = read_buffer();
        size_t size = std::min(reads.size(), rbuf.size);
        if (size) {
            copy(reads.begin(), reads.begin()+size, static_cast<char*>(rbuf.data));
            read_done(size);
            reads.erase(reads.begin(), reads.begin()+size);
        }
    }

    void do_write() {
        const_buffer wbuf = write_buffer();
        if (wbuf.size) {
            writes.insert(writes.begin(),
                          static_cast<const char*>(wbuf.data),
                          static_cast<const char*>(wbuf.data) + wbuf.size);
            write_done(wbuf.size);
        }
    }

    void process() { do_read(); do_write(); dispatch(); }
};

/// A pair of engines that talk to each other in-memory.
struct engine_pair {
    byte_stream ab, ba;
    connection_engine::container cont;

    in_memory_engine a, b;

    engine_pair(handler& ha, handler& hb,
                const connection_options& ca = connection_options(),
                const connection_options& cb = connection_options()) :
        a(ba, ab, ha, ca), b(ab, ba, hb, cb) {}

    void process() { a.process(); b.process(); }
};

template <class S> typename S::value_type quick_pop(S& s) {
    ASSERT(!s.empty());
    typename S::value_type x = s.front();
    s.pop_front();
    return x;
}

/// A handler that records incoming endpoints, errors etc.
struct record_handler : public handler {
    std::deque<proton::internal::link> links;
    std::deque<proton::session> sessions;
    std::deque<std::string> unhandled_errors, transport_errors, connection_errors;

    void on_receiver_open(receiver &l) override {
        links.push_back(l);
    }

    void on_sender_open(sender &l) override {
        links.push_back(l);
    }

    void on_session_open(session &s) override {
        sessions.push_back(s);
    }

    void on_transport_error(transport& t) override {
        transport_errors.push_back(t.error().what());
    }

    void on_connection_error(connection& c) override {
        connection_errors.push_back(c.error().what());
    }

    void on_unhandled_error(const proton::error_condition& c) override {
        unhandled_errors.push_back(c.what());
    }
};

void test_engine_prefix() {
    // Set container ID and prefix explicitly
    record_handler ha, hb;
    engine_pair e(ha, hb,
                  connection_options().container_id("a").link_prefix("x/"),
                  connection_options().container_id("b").link_prefix("y/"));
    e.a.connection().open();
    ASSERT_EQUAL("a", e.a.connection().container_id());
    e.b.connection().open();
    ASSERT_EQUAL("b", e.b.connection().container_id());

    e.a.connection().open_sender("x");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("x/1", quick_pop(ha.links).name());
    ASSERT_EQUAL("x/1", quick_pop(hb.links).name());

    e.a.connection().open_receiver("");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("x/2", quick_pop(ha.links).name());
    ASSERT_EQUAL("x/2", quick_pop(hb.links).name());

    e.b.connection().open_receiver("");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("y/1", quick_pop(ha.links).name());
    ASSERT_EQUAL("y/1", quick_pop(hb.links).name());
}

void test_container_prefix() {
    /// Let the container set the options.
    record_handler ha, hb;
    connection_engine::container ca("a"), cb("b");
    engine_pair e(ha, hb, ca.make_options(), cb.make_options());

    ASSERT_EQUAL("a", e.a.connection().container_id());
    ASSERT_EQUAL("b", e.b.connection().container_id());

    e.a.connection().open();
    sender s = e.a.connection().open_sender("x");
    ASSERT_EQUAL("1/1", s.name());

    while (ha.links.empty() || hb.links.empty()) e.process();

    ASSERT_EQUAL("1/1", quick_pop(ha.links).name());
    ASSERT_EQUAL("1/1", quick_pop(hb.links).name());

    e.a.connection().open_receiver("y");
    while (ha.links.empty() || hb.links.empty()) e.process();
    ASSERT_EQUAL("1/2", quick_pop(ha.links).name());
    ASSERT_EQUAL("1/2", quick_pop(hb.links).name());

    // Open a second connection in each container, make sure links have different IDs.
    record_handler ha2, hb2;
    engine_pair e2(ha2, hb2, ca.make_options(), cb.make_options());

    ASSERT_EQUAL("a", e2.a.connection().container_id());
    ASSERT_EQUAL("b", e2.b.connection().container_id());

    e2.b.connection().open();
    receiver r = e2.b.connection().open_receiver("z");
    ASSERT_EQUAL("2/1", r.name());

    while (ha2.links.empty() || hb2.links.empty()) e2.process();

    ASSERT_EQUAL("2/1", quick_pop(ha2.links).name());
    ASSERT_EQUAL("2/1", quick_pop(hb2.links).name());
};

void test_endpoint_close() {
    // Make sure conditions are sent to the remote end.

    record_handler ha, hb;
    engine_pair e(ha, hb);
    e.a.connection().open();
    e.a.connection().open_sender("x");
    e.a.connection().open_receiver("y");
    while (ha.links.size() < 2 || hb.links.size() < 2) e.process();
    proton::internal::link ax = quick_pop(ha.links), ay = quick_pop(ha.links);
    proton::internal::link bx = quick_pop(hb.links), by = quick_pop(hb.links);

    // Close a link
    ax.close(proton::error_condition("err", "foo bar"));
    while (!bx.closed()) e.process();
    proton::error_condition c = bx.error();
    ASSERT_EQUAL("err", c.name());
    ASSERT_EQUAL("foo bar", c.description());
    ASSERT_EQUAL("err: foo bar", c.what());

    // Close a link with an empty condition
    ay.close(proton::error_condition());
    while (!by.closed()) e.process();
    ASSERT(by.error().empty());

    // Close a connection
    connection ca = e.a.connection(), cb = e.b.connection();
    ca.close(proton::error_condition("conn", "bad connection"));
    while (!cb.closed()) e.process();
    ASSERT_EQUAL("conn: bad connection", cb.error().what());
    ASSERT_EQUAL(1, hb.connection_errors.size());
    ASSERT_EQUAL("conn: bad connection", hb.connection_errors.front());
}

void test_transport_close() {
    // Make sure an engine close calls the local on_transport_error() and aborts the remote.
    record_handler ha, hb;
    engine_pair e(ha, hb);
    e.a.connection().open();
    while (!e.b.connection().active()) e.process();
    e.a.close(proton::error_condition("oops", "engine failure"));
    ASSERT(!e.a.dispatch());    // Final dispatch on a.
    ASSERT_EQUAL(1, ha.transport_errors.size());
    ASSERT_EQUAL("oops: engine failure", ha.transport_errors.front());
    ASSERT_EQUAL(proton::error_condition("oops", "engine failure"),e.a.transport().error());
    // But connectoin was never protocol closed.
    ASSERT(!e.a.connection().closed());
    ASSERT_EQUAL(0, ha.connection_errors.size());
}

int main(int, char**) {
    int failed = 0;
    RUN_TEST(failed, test_engine_prefix());
    RUN_TEST(failed, test_container_prefix());
    RUN_TEST(failed, test_endpoint_close());
    RUN_TEST(failed, test_transport_close());
    return failed;
}
<|endoftext|>


<commit_before>// Copyright 2016 Annotator Team
#define Annotator_AnnotatorLib_Algo_SmoothAnnotation_BODY

/************************************************************
 InterpolateAnnotation class body
 ************************************************************/

// include associated header file
#include "AnnotatorLib/Algo/AdjustAnnotation.h"
#include "AnnotatorLib/Algo/InterpolateAnnotation.h"
#include "AnnotatorLib/Annotation.h"
#include "AnnotatorLib/Frame.h"
#include "AnnotatorLib/Session.h"

#include <algorithm>
#include <assert.h>

namespace AnnotatorLib {
namespace Algo {

shared_ptr<Annotation> AdjustAnnotation::getInterpolation(
    const std::shared_ptr<Session> session, shared_ptr<Frame> frame,
    shared_ptr<Object> object, unsigned int depth) {
  assert(frame);
  assert(object.get());

  shared_ptr<Annotation> annotation =
      InterpolateAnnotation::getInterpolation(session, frame, object);

  if (!annotation || annotation->getConfidenceScore() == 1.0f)
    return annotation;

  float confidence = 0.5f; // interpolation cannot be 1.0 but if I use 0.0 then
                           // min() will always be 0.0

  unsigned int counter = 0;
  float posX = 0;
  float posY = 0;
  float posW = 0;
  float posH = 0;

  // interpolate with previous annotations
  for (int i = -1; i >= -(int)depth; --i) {
    shared_ptr<Frame> nframe = session->getFrame(frame->getFrameNumber() + i);
    if (!nframe)
      nframe = std::make_shared<Frame>(frame->getFrameNumber() + i);
    shared_ptr<Annotation> nAnnotation =
        InterpolateAnnotation::getInterpolation(session, nframe, object);
    if (nAnnotation && !nAnnotation->isTemporary()) {
      confidence = std::min(confidence, nAnnotation->getConfidenceScore());
      posX += interpolate(annotation->getX(), nAnnotation->getX(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posY += interpolate(annotation->getY(), nAnnotation->getY(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posW += interpolate(annotation->getWidth(), nAnnotation->getWidth(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posH += interpolate(annotation->getHeight(), nAnnotation->getHeight(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      ++counter;

      // annotations with confidence equal to 1 should be handeld as borders for
      // the calculation
      if (nAnnotation->getConfidenceScore() >= 1.0f) {
        break;
      }
    }
  }

  // interpolate with next annotations
  for (int i = 0; i <= (int)depth; ++i) {
    shared_ptr<Frame> nframe = session->getFrame(frame->getFrameNumber() + i);
    if (!nframe)
      nframe = std::make_shared<Frame>(frame->getFrameNumber() + i);
    shared_ptr<Annotation> nAnnotation =
        InterpolateAnnotation::getInterpolation(session, nframe, object);
    if (nAnnotation && !nAnnotation->isTemporary()) {
      confidence = std::min(confidence, nAnnotation->getConfidenceScore());
      posX += interpolate(annotation->getX(), nAnnotation->getX(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posY += interpolate(annotation->getY(), nAnnotation->getY(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posW += interpolate(annotation->getWidth(), nAnnotation->getWidth(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posH += interpolate(annotation->getHeight(), nAnnotation->getHeight(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      ++counter;

      // annotations with confidence equal to 1 should be handeld as borders for
      // the calculation
      if (i > 0 && nAnnotation->getConfidenceScore() >= 1.0f) {
        break;
      }
    }
  }

  if (counter == 0)
    return nullptr;

  annotation->setX(posX / counter);
  annotation->setY(posY / counter);
  annotation->setWidth(posW / counter);
  annotation->setHeight(posH / counter);
  annotation->setConfidenceScore(confidence);
  return annotation;
}

float AdjustAnnotation::interpolate(float p1, float p2, float c2,
                                    unsigned int p2depth) {
  if (p2depth == 0)
    return p1 * (c2 > 0.1f ? c2 : 0.5f);
  return p1 + (p2 - p1) * c2 / std::pow(p2depth, 2);
}

} // of namespace Algo
} // of namespace AnnotatorLib
<commit_msg>Adjust annootation updates 3<commit_after>// Copyright 2016 Annotator Team
#define Annotator_AnnotatorLib_Algo_SmoothAnnotation_BODY

/************************************************************
 InterpolateAnnotation class body
 ************************************************************/

// include associated header file
#include "AnnotatorLib/Algo/AdjustAnnotation.h"
#include "AnnotatorLib/Algo/InterpolateAnnotation.h"
#include "AnnotatorLib/Annotation.h"
#include "AnnotatorLib/Frame.h"
#include "AnnotatorLib/Session.h"

#include <algorithm>
#include <assert.h>

namespace AnnotatorLib {
namespace Algo {

shared_ptr<Annotation> AdjustAnnotation::getInterpolation(
    const std::shared_ptr<Session> session, shared_ptr<Frame> frame,
    shared_ptr<Object> object, unsigned int depth) {
  assert(frame);
  assert(object.get());

  shared_ptr<Annotation> annotation =
      InterpolateAnnotation::getInterpolation(session, frame, object);

  if (!annotation || annotation->getConfidenceScore() == 1.0f)
    return annotation;

  float confidence = 0.5f; // interpolation cannot be 1.0 but if I use 0.0 then
                           // min() will always be 0.0

  unsigned int counter = 0;
  float posX = 0;
  float posY = 0;
  float posW = 0;
  float posH = 0;

  // interpolate with previous annotations
  for (int i = -1; i >= -(int)depth; --i) {
    shared_ptr<Frame> nframe = session->getFrame(frame->getFrameNumber() + i);
    if (!nframe)
      nframe = std::make_shared<Frame>(frame->getFrameNumber() + i);
    shared_ptr<Annotation> nAnnotation =
        InterpolateAnnotation::getInterpolation(session, nframe, object);
    if (nAnnotation && !nAnnotation->isTemporary()) {
      confidence = std::min(confidence, nAnnotation->getConfidenceScore());
      posX += interpolate(annotation->getX(), nAnnotation->getX(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posY += interpolate(annotation->getY(), nAnnotation->getY(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posW += interpolate(annotation->getWidth(), nAnnotation->getWidth(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posH += interpolate(annotation->getHeight(), nAnnotation->getHeight(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      ++counter;

      // annotations with confidence equal to 1 should be handeld as borders for
      // the calculation
      if (nAnnotation->getConfidenceScore() >= 1.0f) {
        break;
      }
    }
  }

  // interpolate with next annotations
  for (int i = 0; i <= (int)depth; ++i) {
    shared_ptr<Frame> nframe = session->getFrame(frame->getFrameNumber() + i);
    if (!nframe)
      nframe = std::make_shared<Frame>(frame->getFrameNumber() + i);
    shared_ptr<Annotation> nAnnotation =
        InterpolateAnnotation::getInterpolation(session, nframe, object);
    if (nAnnotation && !nAnnotation->isTemporary()) {
      confidence = std::min(confidence, nAnnotation->getConfidenceScore());
      posX += interpolate(annotation->getX(), nAnnotation->getX(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posY += interpolate(annotation->getY(), nAnnotation->getY(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posW += interpolate(annotation->getWidth(), nAnnotation->getWidth(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      posH += interpolate(annotation->getHeight(), nAnnotation->getHeight(),
                          nAnnotation->getConfidenceScore(), std::abs(i));
      ++counter;

      // annotations with confidence equal to 1 should be handeld as borders for
      // the calculation
      if (i > 0 && nAnnotation->getConfidenceScore() >= 1.0f) {
        break;
      }
    }
  }

  if (counter == 0)
    return nullptr;

  annotation->setX(posX / counter);
  annotation->setY(posY / counter);
  annotation->setWidth(std::max(1.0f,posW / counter));
  annotation->setHeight(std::max(1.0f,posH / counter));
  annotation->setConfidenceScore(confidence);
  return annotation;
}

float AdjustAnnotation::interpolate(float p1, float p2, float c2,
                                    unsigned int p2depth) {
  if (p2depth == 0)
    return p1 * c2;
  return p1 + (p2 - p1) * c2 * 1 / (2 * p2depth);
}

} // of namespace Algo
} // of namespace AnnotatorLib
<|endoftext|>


<commit_before>#include "ColorGradientStopWidget.h"

#include <QColorDialog>
#include <QMouseEvent>
#include <QPainter>
#include <QPainterPath>

#include "ColorGradientStopModel.h"
#include "ColorGradientStopBar.h"
#include "util.hpp"

namespace widgetzeug
{

ColorGradientStopWidget::ColorGradientStopWidget(
    ColorGradientStopModel * model,
    ColorGradientStopBar * bar)
:   QWidget{bar}
,   m_model{model}
,   m_pressed{false}
,   m_remove{false}
{
    setFixedSize(13, 15);
    setCursor(Qt::ArrowCursor);

    updatePosition();

    connect(bar, &ColorGradientStopBar::resized,
            this, &ColorGradientStopWidget::updatePosition);
}

ColorGradientStopModel * ColorGradientStopWidget::model() const
{
    return m_model;
}

void ColorGradientStopWidget::mousePressEvent(QMouseEvent * event)
{
    if (event->buttons() != Qt::LeftButton)
        return;

    m_initialPos = m_mousePos = event->globalPos();
    m_pressed = true;
    m_remove = false;
    update();
}

void ColorGradientStopWidget::mouseMoveEvent(QMouseEvent * event)
{
    if (event->buttons() != Qt::LeftButton)
        return;

    if (qAbs(m_initialPos.y() - event->globalPos().y()) > 50)
    {
        m_remove = true;
        update();
        return;
    }

    m_remove = false;

    auto parentWidth = parentWidget()->width();

    auto newMousePos = event->globalPos();
    auto diff = newMousePos - m_mousePos;
    m_mousePos = newMousePos;
    auto newX = clamp(pos().x() + diff.x(), 0, parentWidth - width());

    m_model->setPosition(static_cast<qreal>(newX) / (parentWidth - width()));
    updatePosition();
    emit positionChanged(this);
}

void ColorGradientStopWidget::mouseReleaseEvent(QMouseEvent * event)
{
    m_pressed = false;
    m_remove = false;
    update();

    if (m_initialPos == event->globalPos())
    {
        m_model->setColor(QColorDialog::getColor(
            m_model->color(),
            this,
            QString{},
            QColorDialog::ShowAlphaChannel));

        update();
        return;
    }

    if (qAbs(m_initialPos.y() - event->globalPos().y()) > 50)
    {
        emit remove(this);
    }
}

void ColorGradientStopWidget::paintEvent(QPaintEvent * event)
{
    QWidget::paintEvent(event);

    QPainter painter{this};
    painter.setRenderHint(QPainter::Antialiasing);

    auto palette = this->palette();

    auto role = m_pressed ? QPalette::Dark : QPalette::Light;
    painter.setBrush(palette.brush(QPalette::Active, role));

    auto pen = QPen{palette.color(QPalette::Mid)};
    pen.setWidthF(1.0);
    painter.setPen(pen);

    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    path.addRoundedRect(0.5, 4.5, 12, 9.0, 2.0, 2.0);
    QVector<QPointF> top = { {6.5, 0.0}, {12.0, 5.5}, {1.0, 5.5} };
    path.addPolygon(top);

    painter.drawPath(path.simplified());

    if (!m_remove)
    {
        painter.setBrush(m_model->color());
        painter.setPen(Qt::NoPen);
        painter.drawRect(QRectF{3.0, 7.0, 7.0, 4.0});
    }
    else
    {
        pen.setWidthF(2);
        pen.setColor(palette.color(QPalette::Text));
        painter.setPen(pen);
        painter.drawLines(QVector<QLineF>{{4.5, 6.5, 8.5, 10.5}, {8.5, 6.5, 4.5, 10.5}});
    }
}

void ColorGradientStopWidget::updatePosition()
{
    move((parentWidget()->width() - width()) * m_model->position(), 0);
}

} // namespace widgetzeug<commit_msg>Fix cancel color dialog<commit_after>#include "ColorGradientStopWidget.h"

#include <QColorDialog>
#include <QMouseEvent>
#include <QPainter>
#include <QPainterPath>

#include "ColorGradientStopModel.h"
#include "ColorGradientStopBar.h"
#include "util.hpp"

namespace widgetzeug
{

ColorGradientStopWidget::ColorGradientStopWidget(
    ColorGradientStopModel * model,
    ColorGradientStopBar * bar)
:   QWidget{bar}
,   m_model{model}
,   m_pressed{false}
,   m_remove{false}
{
    setFixedSize(13, 15);
    setCursor(Qt::ArrowCursor);

    updatePosition();

    connect(bar, &ColorGradientStopBar::resized,
            this, &ColorGradientStopWidget::updatePosition);
}

ColorGradientStopModel * ColorGradientStopWidget::model() const
{
    return m_model;
}

void ColorGradientStopWidget::mousePressEvent(QMouseEvent * event)
{
    if (event->buttons() != Qt::LeftButton)
        return;

    m_initialPos = m_mousePos = event->globalPos();
    m_pressed = true;
    m_remove = false;
    update();
}

void ColorGradientStopWidget::mouseMoveEvent(QMouseEvent * event)
{
    if (event->buttons() != Qt::LeftButton)
        return;

    if (qAbs(m_initialPos.y() - event->globalPos().y()) > 50)
    {
        m_remove = true;
        update();
        return;
    }

    m_remove = false;

    auto parentWidth = parentWidget()->width();

    auto newMousePos = event->globalPos();
    auto diff = newMousePos - m_mousePos;
    m_mousePos = newMousePos;
    auto newX = clamp(pos().x() + diff.x(), 0, parentWidth - width());

    m_model->setPosition(static_cast<qreal>(newX) / (parentWidth - width()));
    updatePosition();
    emit positionChanged(this);
}

void ColorGradientStopWidget::mouseReleaseEvent(QMouseEvent * event)
{
    m_pressed = false;
    m_remove = false;
    update();

    if (m_initialPos == event->globalPos())
    {
        auto newColor = QColorDialog::getColor(
            m_model->color(),
            this,
            QString{},
            QColorDialog::ShowAlphaChannel);

        if (!newColor.isValid())
            return;

        m_model->setColor(newColor);
        update();
        return;
    }

    if (qAbs(m_initialPos.y() - event->globalPos().y()) > 50)
    {
        emit remove(this);
    }
}

void ColorGradientStopWidget::paintEvent(QPaintEvent * event)
{
    QWidget::paintEvent(event);

    QPainter painter{this};
    painter.setRenderHint(QPainter::Antialiasing);

    auto palette = this->palette();

    auto role = m_pressed ? QPalette::Dark : QPalette::Light;
    painter.setBrush(palette.brush(QPalette::Active, role));

    auto pen = QPen{palette.color(QPalette::Mid)};
    pen.setWidthF(1.0);
    painter.setPen(pen);

    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    path.addRoundedRect(0.5, 4.5, 12, 9.0, 2.0, 2.0);
    QVector<QPointF> top = { {6.5, 0.0}, {12.0, 5.5}, {1.0, 5.5} };
    path.addPolygon(top);

    painter.drawPath(path.simplified());

    if (!m_remove)
    {
        painter.setBrush(m_model->color());
        painter.setPen(Qt::NoPen);
        painter.drawRect(QRectF{3.0, 7.0, 7.0, 4.0});
    }
    else
    {
        pen.setWidthF(2);
        pen.setColor(palette.color(QPalette::Text));
        painter.setPen(pen);
        painter.drawLines(QVector<QLineF>{{4.5, 6.5, 8.5, 10.5}, {8.5, 6.5, 4.5, 10.5}});
    }
}

void ColorGradientStopWidget::updatePosition()
{
    move((parentWidget()->width() - width()) * m_model->position(), 0);
}

} // namespace widgetzeug<|endoftext|>


<commit_before>#include "ofxLSTurtle.h"

void ofxLSTurtle::setup( float _moveLength, float _width, float _turnAngle, ofxLSGeometryAvailable _geometry, bool _randomYRotation, bool _scaleWidth, int _resolution, int _textureRepeat) {
    defaultLength = _moveLength;
    width = _width;
    theta = _turnAngle;
    resolution = _resolution;
    textureRepeat = _textureRepeat;
    geometry = _geometry;
    randomYRotation = _randomYRotation;
    scaleWidth = _scaleWidth;
    bookmarks.clear();
    branchContainer.clear();
    historySizes.clear();
    shared_ptr<ofNode> root(new ofNode);
    root->setPosition(origin);
    branchContainer.push_back(root);
}

void ofxLSTurtle::generate(ofVboMesh& mesh, const string _instruction, const int _depth) {
    resetBoundingBox();
    bool branching = false;
    auto instructions = getInstructionsFromString(_instruction);

    for (auto stringInstruction : instructions) {
        auto inst = ofxLSInstruction(stringInstruction);
        auto head = inst.getHead();
        if (head == "F") {
            branching =  true;
        }else if( head == "G") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->boom(inst.getLength(defaultLength));
            branchContainer.push_back(newJoin);
        }else if (head == "+") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->roll(+inst.getAngle(theta));
            if(randomYRotation){
                newJoin->pan(ofRandom(30.00, 330.00));
            }
            branchContainer.push_back(newJoin);
        }else if (head == "-") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->roll(-inst.getAngle(theta));
            if(randomYRotation){
                newJoin->pan(ofRandom(30.00, 330.00));
            }
            branchContainer.push_back(newJoin);
        }else if (head == "|") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->pan(+inst.getAngle(180.00));
            branchContainer.push_back(newJoin);
        }else if (head == "&") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->tilt(+inst.getAngle(theta));
            branchContainer.push_back(newJoin);
        }
        else if (head == "^") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->tilt(-inst.getAngle(theta));
            branchContainer.push_back(newJoin);
        }
        else if (head == "\\") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->pan(+inst.getAngle(theta));
            branchContainer.push_back(newJoin);
        }
        else if (head == "/") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->pan(-inst.getAngle(180.00));
            branchContainer.push_back(newJoin);
        }
        else if (head == "[") {
            bookmarks.push_back(branchContainer.back());
        }
        else if (head == "]") {
            branchContainer.push_back(bookmarks.back());
            bookmarks.pop_back();
        }

        if (branching) {
            float length = inst.getLength(defaultLength);
            auto beginBranch = branchContainer.back();
            shared_ptr<ofNode> endBranch(new ofNode);
            endBranch->setParent(*branchContainer.back());
            endBranch->move(ofVec3f(0, length, 0));

            maybeVectorExpandsBoundingBox(endBranch->getGlobalPosition());

            auto widths = getPrevAndCurrentWidth(length);
            auto newBranch = ofxLSBranch(*beginBranch, *endBranch, widths);
            geometryBuilder.putIntoMesh(newBranch, mesh, geometry, resolution, length, textureRepeat);
            branchContainer.push_back(endBranch);
            branching = false;
        }
    }

    //TODO, separate the generation of the node skeleton to mesh construction
//    float distance;
//    for(auto b : branchContainer){
//        if(b->getParent() != nullptr){
//            cout << "Start"<< endl;
//            cout << b->getParent()->getGlobalPosition().x;
//            cout << b->getParent()->getGlobalPosition().y;
//            cout << b->getParent()->getGlobalPosition().x;
//            cout << "End" << endl;
//            cout << b->getGlobalPosition().x;
//            cout << b->getGlobalPosition().y;
//            cout << b->getGlobalPosition().x;
//        }else{
//            //root point
//        }
//
//    }
    branchContainer.clear();
    bookmarks.clear();
    historySizes.clear();
}

// In case there is the need to keep track of the differents branches width and lenght,
// as in the case when scaleWidth is set to true, this method does 2 things:
// 1) it stores all the sizes in the container historySizes, for each pair, the first calue is the lenght
// the second the width.
// 2) It returns the current width and the previous one, as the method name says.
// If there is no need to keep track of the branch  width, just returns a pair containing
// the default width, both for the prev and current width.
pair<float, float> ofxLSTurtle::getPrevAndCurrentWidth(float currentLength){
    if(!scaleWidth){
        return make_pair(width, width);
    }

    float currentWidth = (scaleWidth) ? getScaledWidth(currentLength) : width;
    if (historySizes.empty()) {
        historySizes.insert(make_pair(currentLength, currentWidth));
        return (make_pair(currentWidth, currentWidth));
    } else {
        map<float, float>::iterator current;
        if (historySizes.find(currentLength) == historySizes.end()) {
            historySizes.insert(make_pair(currentLength, currentWidth));
            current = historySizes.begin();
        } else {
            current = historySizes.find(currentLength);
        }
        auto prev = current;
        ++prev;
        return make_pair(prev->second, current->second);
    }
}

//it scales the with proportionally to the scaled length
//
float ofxLSTurtle::getScaledWidth(float currentLength){
    auto ratio = (defaultLength / currentLength );
    float currentWidth = width / ratio;
    return currentWidth;
    if (currentWidth < 0.2) {
        return 0.2;
    } else {
        return currentWidth;
    }
}

vector<string> ofxLSTurtle::getInstructionsFromString(string _str){
    // This regex deserves an explanation. Taking a string like:
    // "F[+F-F(1.0,3.2)^F&F\\F/F?|]YU(2.0)A(2.232)?\\/"
    // it returns a vector containing
    //    F
    //    +
    //    F
    //    -
    //    F(1.0,3.2)
    //    ^
    //    F
    //    &
    //    F
    //    \
    //    F
    //    /
    //    F
    //    ?
    //    |
    //    Y
    //    U(2.0)
    //    A(2.232)
    //    ?
    //    \
    //    /

    // Explanation:
    // "([A-Z\\^&\\+-\\?\\|/\\]\\[\\\\](\\([0-9\\.,]+\\))*)" this means take any string that start with a capital letter,
    // a ^, a & a +, -, a | a '/', a'\' a'[', a ']'and, if there are, take any number or point '.' enclosed between ()
    return ofxLSUtils::matchesInRegex(_str,"([A-Z\\^&\\+\\-\\?\\|/\\]\\[\\\\](\\([0-9\\.,]+\\))*)");
}

// keep in mind that this method does not consider the thikness of a branch, but just the position of the vertices
// that will be used later to generate the cylinder. Therefore, it is not accurate, but is is usefull to get the UV
// if you want higher precision, call ofxLSystem.computeBoundingBox(), that iterates on all the vertices composing the
// mesh
void ofxLSTurtle::maybeVectorExpandsBoundingBox(ofVec3f v){
    if (v.x < buildedBoundingBox.min.x) buildedBoundingBox.min.x = v.x;
    if (v.y < buildedBoundingBox.min.y) buildedBoundingBox.min.y = v.y;
    if (v.z < buildedBoundingBox.min.z) buildedBoundingBox.min.z = v.z;

    if (v.x > buildedBoundingBox.max.x) buildedBoundingBox.max.x = v.x;
    if (v.y > buildedBoundingBox.max.y) buildedBoundingBox.max.y = v.y;
    if (v.z > buildedBoundingBox.max.z) buildedBoundingBox.max.z = v.z;
};

void ofxLSTurtle::resetBoundingBox(){
    buildedBoundingBox.min = ofVec3f(0,0,0);
    buildedBoundingBox.max = ofVec3f(0,0,0);
}<commit_msg>fix pan to panDeg<commit_after>#include "ofxLSTurtle.h"

void ofxLSTurtle::setup( float _moveLength, float _width, float _turnAngle, ofxLSGeometryAvailable _geometry, bool _randomYRotation, bool _scaleWidth, int _resolution, int _textureRepeat) {
    defaultLength = _moveLength;
    width = _width;
    theta = _turnAngle;
    resolution = _resolution;
    textureRepeat = _textureRepeat;
    geometry = _geometry;
    randomYRotation = _randomYRotation;
    scaleWidth = _scaleWidth;
    bookmarks.clear();
    branchContainer.clear();
    historySizes.clear();
    shared_ptr<ofNode> root(new ofNode);
    root->setPosition(origin);
    branchContainer.push_back(root);
}

void ofxLSTurtle::generate(ofVboMesh& mesh, const string _instruction, const int _depth) {
    resetBoundingBox();
    bool branching = false;
    auto instructions = getInstructionsFromString(_instruction);

    for (auto stringInstruction : instructions) {
        auto inst = ofxLSInstruction(stringInstruction);
        auto head = inst.getHead();
        if (head == "F") {
            branching =  true;
        }else if( head == "G") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->boom(inst.getLength(defaultLength));
            branchContainer.push_back(newJoin);
        }else if (head == "+") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->rollDeg(+inst.getAngle(theta));
            if(randomYRotation){
                newJoin->panDeg(ofRandom(30.00, 330.00));
            }
            branchContainer.push_back(newJoin);
        }else if (head == "-") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->rollDeg(-inst.getAngle(theta));
            if(randomYRotation){
                newJoin->panDeg(ofRandom(30.00, 330.00));
            }
            branchContainer.push_back(newJoin);
        }else if (head == "|") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->panDeg(+inst.getAngle(180.00));
            branchContainer.push_back(newJoin);
        }else if (head == "&") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->tiltDeg(+inst.getAngle(theta));
            branchContainer.push_back(newJoin);
        }
        else if (head == "^") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->tiltDeg(-inst.getAngle(theta));
            branchContainer.push_back(newJoin);
        }
        else if (head == "\\") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->panDeg(+inst.getAngle(theta));
            branchContainer.push_back(newJoin);
        }
        else if (head == "/") {
            shared_ptr<ofNode> newJoin(new ofNode);
            newJoin->setParent(*branchContainer.back());
            newJoin->panDeg(-inst.getAngle(180.00));
            branchContainer.push_back(newJoin);
        }
        else if (head == "[") {
            bookmarks.push_back(branchContainer.back());
        }
        else if (head == "]") {
            branchContainer.push_back(bookmarks.back());
            bookmarks.pop_back();
        }

        if (branching) {
            float length = inst.getLength(defaultLength);
            auto beginBranch = branchContainer.back();
            shared_ptr<ofNode> endBranch(new ofNode);
            endBranch->setParent(*branchContainer.back());
            endBranch->move(ofVec3f(0, length, 0));

            maybeVectorExpandsBoundingBox(endBranch->getGlobalPosition());

            auto widths = getPrevAndCurrentWidth(length);
            auto newBranch = ofxLSBranch(*beginBranch, *endBranch, widths);
            geometryBuilder.putIntoMesh(newBranch, mesh, geometry, resolution, length, textureRepeat);
            branchContainer.push_back(endBranch);
            branching = false;
        }
    }

    //TODO, separate the generation of the node skeleton to mesh construction
//    float distance;
//    for(auto b : branchContainer){
//        if(b->getParent() != nullptr){
//            cout << "Start"<< endl;
//            cout << b->getParent()->getGlobalPosition().x;
//            cout << b->getParent()->getGlobalPosition().y;
//            cout << b->getParent()->getGlobalPosition().x;
//            cout << "End" << endl;
//            cout << b->getGlobalPosition().x;
//            cout << b->getGlobalPosition().y;
//            cout << b->getGlobalPosition().x;
//        }else{
//            //root point
//        }
//
//    }
    branchContainer.clear();
    bookmarks.clear();
    historySizes.clear();
}

// In case there is the need to keep track of the differents branches width and lenght,
// as in the case when scaleWidth is set to true, this method does 2 things:
// 1) it stores all the sizes in the container historySizes, for each pair, the first calue is the lenght
// the second the width.
// 2) It returns the current width and the previous one, as the method name says.
// If there is no need to keep track of the branch  width, just returns a pair containing
// the default width, both for the prev and current width.
pair<float, float> ofxLSTurtle::getPrevAndCurrentWidth(float currentLength){
    if(!scaleWidth){
        return make_pair(width, width);
    }

    float currentWidth = (scaleWidth) ? getScaledWidth(currentLength) : width;
    if (historySizes.empty()) {
        historySizes.insert(make_pair(currentLength, currentWidth));
        return (make_pair(currentWidth, currentWidth));
    } else {
        map<float, float>::iterator current;
        if (historySizes.find(currentLength) == historySizes.end()) {
            historySizes.insert(make_pair(currentLength, currentWidth));
            current = historySizes.begin();
        } else {
            current = historySizes.find(currentLength);
        }
        auto prev = current;
        ++prev;
        return make_pair(prev->second, current->second);
    }
}

//it scales the with proportionally to the scaled length
//
float ofxLSTurtle::getScaledWidth(float currentLength){
    auto ratio = (defaultLength / currentLength );
    float currentWidth = width / ratio;
    return currentWidth;
    if (currentWidth < 0.2) {
        return 0.2;
    } else {
        return currentWidth;
    }
}

vector<string> ofxLSTurtle::getInstructionsFromString(string _str){
    // This regex deserves an explanation. Taking a string like:
    // "F[+F-F(1.0,3.2)^F&F\\F/F?|]YU(2.0)A(2.232)?\\/"
    // it returns a vector containing
    //    F
    //    +
    //    F
    //    -
    //    F(1.0,3.2)
    //    ^
    //    F
    //    &
    //    F
    //    \
    //    F
    //    /
    //    F
    //    ?
    //    |
    //    Y
    //    U(2.0)
    //    A(2.232)
    //    ?
    //    \
    //    /

    // Explanation:
    // "([A-Z\\^&\\+-\\?\\|/\\]\\[\\\\](\\([0-9\\.,]+\\))*)" this means take any string that start with a capital letter,
    // a ^, a & a +, -, a | a '/', a'\' a'[', a ']'and, if there are, take any number or point '.' enclosed between ()
    return ofxLSUtils::matchesInRegex(_str,"([A-Z\\^&\\+\\-\\?\\|/\\]\\[\\\\](\\([0-9\\.,]+\\))*)");
}

// keep in mind that this method does not consider the thikness of a branch, but just the position of the vertices
// that will be used later to generate the cylinder. Therefore, it is not accurate, but is is usefull to get the UV
// if you want higher precision, call ofxLSystem.computeBoundingBox(), that iterates on all the vertices composing the
// mesh
void ofxLSTurtle::maybeVectorExpandsBoundingBox(ofVec3f v){
    if (v.x < buildedBoundingBox.min.x) buildedBoundingBox.min.x = v.x;
    if (v.y < buildedBoundingBox.min.y) buildedBoundingBox.min.y = v.y;
    if (v.z < buildedBoundingBox.min.z) buildedBoundingBox.min.z = v.z;

    if (v.x > buildedBoundingBox.max.x) buildedBoundingBox.max.x = v.x;
    if (v.y > buildedBoundingBox.max.y) buildedBoundingBox.max.y = v.y;
    if (v.z > buildedBoundingBox.max.z) buildedBoundingBox.max.z = v.z;
};

void ofxLSTurtle::resetBoundingBox(){
    buildedBoundingBox.min = ofVec3f(0,0,0);
    buildedBoundingBox.max = ofVec3f(0,0,0);
}
<|endoftext|>


<commit_before>#include <random>
#include <chrono>
#include <algorithm>
#include <cmath>
#include <string>
#include <sstream>
#include <fstream>
#include <chrono>
#include <cstdlib>

#include "util.h"
#include "eval.h"

int main(int argc, const char *const argv[]) {
  constexpr size_t max_iterations = 50;
  constexpr unsigned base_trials = 10000;

  auto num_samples = [=](const double eb_no) {
    return std::min(base_trials * pow(10, eb_no / 2), 10e6);
  };

  const float alpha_start = (argc > 0) ? strtof(argv[1], nullptr) : 0.1f;
  const float alpha_max = (argc > 1) ? strtof(argv[2], nullptr) : 1.0f;
  const float alpha_step = (argc > 2) ? strtof(argv[3], nullptr) : 0.01f;

  const float beta_start = (argc > 3) ? strtof(argv[4], nullptr) : 0.1f;
  const float beta_max = (argc > 4) ? strtof(argv[5], nullptr) : 1.0f;
  const float beta_step = (argc > 5) ? strtof(argv[6], nullptr) : 0.01f;

  const float eb_no = (argc > 6) ? strtof(argv[7], nullptr) : 0.0f;

  std::cout << "Calculating for eb_no: " << eb_no << std::endl;
  std::cout << "alpha: " << alpha_start << " to " << alpha_max << " in "
            << alpha_step << " steps" << std::endl;
  std::cout << "beta:  " << beta_start << " to " << beta_max << " in "
            << beta_step << " steps" << std::endl;

  std::mt19937_64 generator;
  const auto seed =
      std::chrono::high_resolution_clock::now().time_since_epoch().count();

  bch code(5, 0x25, 7);
  // bch code(6, 0x45, 7);

  auto parameters = code.parameters();
  auto simulator = std::bind(evaluate, generator, std::placeholders::_1,
                             std::placeholders::_2, std::placeholders::_3,
                             std::get<0>(parameters), std::get<1>(parameters),
                             std::get<2>(parameters));

  std::ostringstream os;
  os << "logs/ebno_" << eb_no;
  std::string fname = os.str();
  if (file_exists(fname)) {
    std::cout << "File " << fname << " exists. Aborting.";
    return -1;
  }

  std::ofstream file(fname, std::ofstream::out);
  std::cout << "Writing to file " << fname << std::endl;
  file << "#eb_no " << eb_no << std::endl;
  file << "#alpha: " << alpha_start << " " << alpha_max << " " << alpha_step
       << std::endl;
  file << "#beta : " << beta_start << " " << beta_max << " " << beta_step
       << std::endl;

  file << std::scientific;

  for (float alpha = alpha_start; alpha < alpha_max; alpha += alpha_step) {
    for (float beta = beta_start; beta < beta_max; beta += beta_step) {
      generator.seed(seed);

      const size_t N = num_samples(eb_no);

      std::cout << "alpha = " << alpha << " beta = " << beta << " N = " << N;
      std::cout.flush();

      auto start = std::chrono::high_resolution_clock::now();
      auto f =
          std::bind(nms_2d<max_iterations, float, float>, std::ref(code.H()),
                    std::placeholders::_1, alpha, beta);
      file << simulator(f, N, eb_no).ber() << " ";

      auto end = std::chrono::high_resolution_clock::now();
      auto seconds =
          std::chrono::duration_cast<std::chrono::seconds>(end - start).count();

      std::cout << seconds << " s" << std::endl;
    }

    file << std::endl;
  }
}
<commit_msg>More verbose file header in optimized2d<commit_after>#include <random>
#include <chrono>
#include <algorithm>
#include <cmath>
#include <string>
#include <sstream>
#include <fstream>
#include <chrono>
#include <cstdlib>

#include "util.h"
#include "eval.h"

int main(int argc, const char *const argv[]) {
  constexpr size_t max_iterations = 50;
  constexpr unsigned base_trials = 10000;

  auto num_samples = [=](const double eb_no) {
    return std::min(base_trials * pow(10, eb_no / 2), 10e6);
  };

  const float alpha_start = (argc > 0) ? strtof(argv[1], nullptr) : 0.1f;
  const float alpha_max = (argc > 1) ? strtof(argv[2], nullptr) : 1.0f;
  const float alpha_step = (argc > 2) ? strtof(argv[3], nullptr) : 0.01f;

  const float beta_start = (argc > 3) ? strtof(argv[4], nullptr) : 0.1f;
  const float beta_max = (argc > 4) ? strtof(argv[5], nullptr) : 1.0f;
  const float beta_step = (argc > 5) ? strtof(argv[6], nullptr) : 0.01f;

  const float eb_no = (argc > 6) ? strtof(argv[7], nullptr) : 0.0f;

  std::cout << "Calculating for eb_no: " << eb_no << std::endl;
  std::cout << "alpha: " << alpha_start << " to " << alpha_max << " in "
            << alpha_step << " steps" << std::endl;
  std::cout << "beta:  " << beta_start << " to " << beta_max << " in "
            << beta_step << " steps" << std::endl;

  std::mt19937_64 generator;
  const auto seed =
      std::chrono::high_resolution_clock::now().time_since_epoch().count();

  bch code(5, 0x25, 7);
  // bch code(6, 0x45, 7);

  auto parameters = code.parameters();
  auto simulator = std::bind(evaluate, generator, std::placeholders::_1,
                             std::placeholders::_2, std::placeholders::_3,
                             std::get<0>(parameters), std::get<1>(parameters),
                             std::get<2>(parameters));

  std::ostringstream os;
  os << "logs/ebno_" << eb_no;
  std::string fname = os.str();
  if (file_exists(fname)) {
    std::cout << "File " << fname << " exists. Aborting.";
    return -1;
  }

  std::ofstream file(fname, std::ofstream::out);
  std::cout << "Writing to file " << fname << std::endl;
  file << "#eb_no " << eb_no << std::endl;
  file << "#alpha: " << alpha_start << " " << alpha_max << " " << alpha_step
       << " in rows" << std::endl;
  file << "#beta : " << beta_start << " " << beta_max << " " << beta_step
       << " in columns" << std::endl;

  file << std::scientific;

  for (float alpha = alpha_start; alpha < alpha_max; alpha += alpha_step) {
    for (float beta = beta_start; beta < beta_max; beta += beta_step) {
      generator.seed(seed);

      const size_t N = num_samples(eb_no);

      std::cout << "alpha = " << alpha << " beta = " << beta << " N = " << N;
      std::cout.flush();

      auto start = std::chrono::high_resolution_clock::now();
      auto f =
          std::bind(nms_2d<max_iterations, float, float>, std::ref(code.H()),
                    std::placeholders::_1, alpha, beta);
      file << simulator(f, N, eb_no).ber() << " ";

      auto end = std::chrono::high_resolution_clock::now();
      auto seconds =
          std::chrono::duration_cast<std::chrono::seconds>(end - start).count();

      std::cout << seconds << " s" << std::endl;
    }

    file << std::endl;
  }
}
<|endoftext|>


<commit_before>#ifndef OSC_POLYGON_HPP_INCLUDED
#define OSC_POLYGON_HPP_INCLUDED

#include "osc_common_draw.hpp"
#include "Polygon.h"
#include "FigureGraphic.hpp"
#include "InputGestureDirectObjects.hpp"
#include "InputGestureDirectFingers.hpp"

class OSCPolygonObject :public FigureGraphic, public OSCCommonDrawObject
{
    public:
    Figures::Polygon polygon;
    int cursor;
    int object;
    int id;
    bool drawstroke;
    bool drawpolygon;
    ofColor poly_color;
    ofColor stroke_color;
    void AddPoint(ofPoint point)
    {
        polygon.AddVertex(point);
        cursor = -1;
        object = -1;
    }
    void Clear()
    {
        polygon = Figures::Polygon();
    }
    bool collide(ofPoint point)
    {
        return polygon.Collide(point);
    }
    void SetTexture(std::string texture)
    {
        if(texture.compare("none")== 0)
        {
            polygon.SetTexture("");
        }
        else
            polygon.SetTexture(texture);
    }
    OSCPolygonObject():FigureGraphic(&polygon),drawpolygon(true),drawstroke(false)
    {
        this->registerMyEvent(InputGestureDirectObjects::I().newObject,&OSCPolygonObject::newObject);
        this->registerMyEvent(InputGestureDirectObjects::I().enterObject,&OSCPolygonObject::newObject);
        this->registerMyEvent(InputGestureDirectObjects::I().removeObject,&OSCPolygonObject::removeObject);
        this->registerMyEvent(InputGestureDirectObjects::I().exitObject,&OSCPolygonObject::removeObject);
        this->registerMyEvent(InputGestureDirectObjects::I().updateObject,&OSCPolygonObject::updateObject);
        this->registerMyEvent(InputGestureDirectFingers::I().newCursor, &OSCPolygonObject::newCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().enterCursor, &OSCPolygonObject::newCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().removeCursor, &OSCPolygonObject::removeCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().exitCursor, &OSCPolygonObject::removeCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().updateCursor, &OSCPolygonObject::updateCursor);
    }
    void newCursor(InputGestureDirectFingers::newCursorArgs & a)
    {
        DirectFinger *df = a.finger;
        if (cursor == -1)
        {
            cursor= df->s_id;
            ofxOscMessage msg1;
            msg1.setAddress("/figure/addfinger");
            OscPacker(msg1) << (int)id << (int)df->s_id;
            OSCDispatcher::Instance().sender.sendMessage(msg1);

            ofxOscMessage msg;
            msg.setAddress("/figure/finger");
            OscPacker(msg) << (int)id <<(int)df->s_id << (float) df->getX() << (float) df->getY();
            OSCDispatcher::Instance().sender.sendMessage(msg);
        }
    }
    void removeCursor(InputGestureDirectFingers::removeCursorArgs & a)
    {
        DirectFinger *df = a.finger;

            if(cursor == df->s_id)
            {
                //std::cout << "remove" << std::endl;
                cursor = -1;
                ofxOscMessage msg1;
                msg1.setAddress("/figure/rmfinger");
                OscPacker(msg1) << (int)id << (int)df->s_id;
                OSCDispatcher::Instance().sender.sendMessage(msg1);
            }
    }
    void updateCursor(InputGestureDirectFingers::updateCursorArgs & a)
    {
        DirectFinger *df = a.finger;
       // updatelist.insert(f);

            if(cursor == df->s_id)
            {
                ofxOscMessage msg;
                msg.setAddress("/figure/finger");
                OscPacker(msg) << (int)id <<(int)df->s_id << (float) df->getX() << (float) df->getY();
                OSCDispatcher::Instance().sender.sendMessage(msg);
            }
    }
    void newObject(InputGestureDirectObjects::newObjectArgs & a)
    {
        DirectObject *df = a.object;

           if(object == -1)
           {

                   object= df->f_id;
                   ofxOscMessage msg1;
                   msg1.setAddress("/figure/addobject");
                   OscPacker(msg1) << (int)id << (int)df->f_id;
                   OSCDispatcher::Instance().sender.sendMessage(msg1);

                   ofxOscMessage msg;
                   msg.setAddress("/figure/object");
                   OscPacker(msg) << (int)id <<(int)df->f_id << (float) df->getX() << (float) df->getY();
                   OSCDispatcher::Instance().sender.sendMessage(msg);

           }
    }
    void removeObject(InputGestureDirectObjects::removeObjectArgs & a)
    {
        DirectObject *df = a.object;

            if(object == df->f_id)
            {
                //std::cout << "remove" << std::endl;
                object = -1;
                ofxOscMessage msg1;
                msg1.setAddress("/figure/rmobject");
                OscPacker(msg1) << (int)id << (int)df->f_id;
                OSCDispatcher::Instance().sender.sendMessage(msg1);
            }
    }
    void updateObject(InputGestureDirectObjects::updateObjectArgs & a)
    {
        DirectObject *df = a.object;
       // updatelist.insert(f);

            if(object == df->f_id)
            {
                ofxOscMessage msg;
                msg.setAddress("/figure/object");
                OscPacker(msg) << (int)id <<(int)df->f_id << (float) df->getX() << (float) df->getY();
                OSCDispatcher::Instance().sender.sendMessage(msg);
            }
    }

    void draw()
    {
        ofPushMatrix();
        ofMultMatrix(total_matrix);
        if(drawpolygon){
            setFill(true);
            color = poly_color;
            FigureGraphic::draw();
        }
        if(drawstroke)
        {
            color = stroke_color;
            setFill(false);
            FigureGraphic::draw();
        }
        ofPopMatrix();
    }
    void cmd_report_matrix()
    {
        ofxOscMessage msg;
        msg.setAddress("/figure/matrix");
        OscPacker(msg) << (int)id <<
            (float)total_matrix(0,0)<<(float)total_matrix(0,1)<<(float)total_matrix(0,2)<<(float)total_matrix(0,3)<<
            (float)total_matrix(1,0)<<(float)total_matrix(1,1)<<(float)total_matrix(1,2)<<(float)total_matrix(1,3)<<
            (float)total_matrix(2,0)<<(float)total_matrix(2,1)<<(float)total_matrix(2,2)<<(float)total_matrix(2,3)<<
            (float)total_matrix(3,0)<<(float)total_matrix(3,1)<<(float)total_matrix(3,2)<<(float)total_matrix(3,3);
        OSCDispatcher::Instance().sender.sendMessage(msg);
    }
    void cmd_color(int r,int g,int b)
    {
        poly_color.set(r,g,b);
    }
    void cmd_hidden(bool ishidden)
    {
         isHidden(ishidden);
    }
    void cmd_bring_top()
    {
        BringTop();
    }
    void cmd_set_layer(int _layer)
    {
        SetLayer(_layer);
    }
    void run_extra(const std::string & cmd, OscOptionalUnpacker & msg)
    {
        if(cmd == "addrectangle")
        {
            std::cout << "TODO: addrectangle not implemented" << std::endl;
        }
        else if(cmd == "addcircle")
        {
            std::cout << "TODO: addcircle not implemented" << std::endl;
        }
        else if(cmd == "addvertex")
        {
            float fx, fy;
            while (!msg.Eos())
            {
                msg >> fx >> fy;
                AddPoint(ofPoint(fx,fy));
            }
        }
        else if(cmd == "clearvertex")
        {
            Clear();
        }
        else if(cmd == "texture")
        {
            std::string tex_name;
            msg >> tex_name;
            SetTexture(tex_name);
        }
        else if(cmd == "drawpolygon")
        {
            int yesno;
            msg >> yesno;
            drawpolygon = (yesno==1);

        }
        else if(cmd == "drawstroke")
        {
            int yesno;
            msg >> yesno;
            drawstroke = (yesno==1);
        }
        else if(cmd == "strokecolor")
        {
            int r,g,b;
            msg >> r >> g >> b;
            stroke_color.set(r,g,b);
        }
        else if(cmd == "strokewidth")
        {
            std::cout << "TODO: strokewidth not implemented" << std::endl;
        }
        else if(cmd == "touchable")
        {
            std::cout << "TODO: touchable not implemented" << std::endl;
        }
        else
        {
            std::cout << "Polygon: command " << cmd << " not found" << std::endl;
        }

    }
};

class OSCFigureDraw: public Singleton<OSCFigureDraw>
{
public:
    OSCCommonDraw<OSCPolygonObject> o;
    OSCFigureDraw():o("/figure"){}
};

#endif // OSC_POLYGON_HPP_INCLUDED
<commit_msg>implement addrectangle<commit_after>#ifndef OSC_POLYGON_HPP_INCLUDED
#define OSC_POLYGON_HPP_INCLUDED

#include "osc_common_draw.hpp"
#include "Polygon.h"
#include "FigureGraphic.hpp"
#include "InputGestureDirectObjects.hpp"
#include "InputGestureDirectFingers.hpp"

class OSCPolygonObject :public FigureGraphic, public OSCCommonDrawObject
{
    public:
    Figures::Polygon polygon;
    int cursor;
    int object;
    int id;
    bool drawstroke;
    bool drawpolygon;
    ofColor poly_color;
    ofColor stroke_color;
    void AddPoint(ofPoint point)
    {
        polygon.AddVertex(point);
        cursor = -1;
        object = -1;
    }
    void Clear()
    {
        polygon = Figures::Polygon();
    }
    bool collide(ofPoint point)
    {
        return polygon.Collide(point);
    }
    void SetTexture(std::string texture)
    {
        if(texture.compare("none")== 0)
        {
            polygon.SetTexture("");
        }
        else
            polygon.SetTexture(texture);
    }
    OSCPolygonObject():FigureGraphic(&polygon),drawpolygon(true),drawstroke(false)
    {
        this->registerMyEvent(InputGestureDirectObjects::I().newObject,&OSCPolygonObject::newObject);
        this->registerMyEvent(InputGestureDirectObjects::I().enterObject,&OSCPolygonObject::newObject);
        this->registerMyEvent(InputGestureDirectObjects::I().removeObject,&OSCPolygonObject::removeObject);
        this->registerMyEvent(InputGestureDirectObjects::I().exitObject,&OSCPolygonObject::removeObject);
        this->registerMyEvent(InputGestureDirectObjects::I().updateObject,&OSCPolygonObject::updateObject);
        this->registerMyEvent(InputGestureDirectFingers::I().newCursor, &OSCPolygonObject::newCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().enterCursor, &OSCPolygonObject::newCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().removeCursor, &OSCPolygonObject::removeCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().exitCursor, &OSCPolygonObject::removeCursor);
        this->registerMyEvent(InputGestureDirectFingers::I().updateCursor, &OSCPolygonObject::updateCursor);
    }
    void newCursor(InputGestureDirectFingers::newCursorArgs & a)
    {
        DirectFinger *df = a.finger;
        if (cursor == -1)
        {
            cursor= df->s_id;
            ofxOscMessage msg1;
            msg1.setAddress("/figure/addfinger");
            OscPacker(msg1) << (int)id << (int)df->s_id;
            OSCDispatcher::Instance().sender.sendMessage(msg1);

            ofxOscMessage msg;
            msg.setAddress("/figure/finger");
            OscPacker(msg) << (int)id <<(int)df->s_id << (float) df->getX() << (float) df->getY();
            OSCDispatcher::Instance().sender.sendMessage(msg);
        }
    }
    void removeCursor(InputGestureDirectFingers::removeCursorArgs & a)
    {
        DirectFinger *df = a.finger;

            if(cursor == df->s_id)
            {
                //std::cout << "remove" << std::endl;
                cursor = -1;
                ofxOscMessage msg1;
                msg1.setAddress("/figure/rmfinger");
                OscPacker(msg1) << (int)id << (int)df->s_id;
                OSCDispatcher::Instance().sender.sendMessage(msg1);
            }
    }
    void updateCursor(InputGestureDirectFingers::updateCursorArgs & a)
    {
        DirectFinger *df = a.finger;
       // updatelist.insert(f);

            if(cursor == df->s_id)
            {
                ofxOscMessage msg;
                msg.setAddress("/figure/finger");
                OscPacker(msg) << (int)id <<(int)df->s_id << (float) df->getX() << (float) df->getY();
                OSCDispatcher::Instance().sender.sendMessage(msg);
            }
    }
    void newObject(InputGestureDirectObjects::newObjectArgs & a)
    {
        DirectObject *df = a.object;

           if(object == -1)
           {

                   object= df->f_id;
                   ofxOscMessage msg1;
                   msg1.setAddress("/figure/addobject");
                   OscPacker(msg1) << (int)id << (int)df->f_id;
                   OSCDispatcher::Instance().sender.sendMessage(msg1);

                   ofxOscMessage msg;
                   msg.setAddress("/figure/object");
                   OscPacker(msg) << (int)id <<(int)df->f_id << (float) df->getX() << (float) df->getY();
                   OSCDispatcher::Instance().sender.sendMessage(msg);

           }
    }
    void removeObject(InputGestureDirectObjects::removeObjectArgs & a)
    {
        DirectObject *df = a.object;

            if(object == df->f_id)
            {
                //std::cout << "remove" << std::endl;
                object = -1;
                ofxOscMessage msg1;
                msg1.setAddress("/figure/rmobject");
                OscPacker(msg1) << (int)id << (int)df->f_id;
                OSCDispatcher::Instance().sender.sendMessage(msg1);
            }
    }
    void updateObject(InputGestureDirectObjects::updateObjectArgs & a)
    {
        DirectObject *df = a.object;
       // updatelist.insert(f);

            if(object == df->f_id)
            {
                ofxOscMessage msg;
                msg.setAddress("/figure/object");
                OscPacker(msg) << (int)id <<(int)df->f_id << (float) df->getX() << (float) df->getY();
                OSCDispatcher::Instance().sender.sendMessage(msg);
            }
    }

    void draw()
    {
        ofPushMatrix();
        ofMultMatrix(total_matrix);
        if(drawpolygon){
            setFill(true);
            color = poly_color;
            FigureGraphic::draw();
        }
        if(drawstroke)
        {
            color = stroke_color;
            setFill(false);
            FigureGraphic::draw();
        }
        ofPopMatrix();
    }
    void cmd_report_matrix()
    {
        ofxOscMessage msg;
        msg.setAddress("/figure/matrix");
        OscPacker(msg) << (int)id <<
            (float)total_matrix(0,0)<<(float)total_matrix(0,1)<<(float)total_matrix(0,2)<<(float)total_matrix(0,3)<<
            (float)total_matrix(1,0)<<(float)total_matrix(1,1)<<(float)total_matrix(1,2)<<(float)total_matrix(1,3)<<
            (float)total_matrix(2,0)<<(float)total_matrix(2,1)<<(float)total_matrix(2,2)<<(float)total_matrix(2,3)<<
            (float)total_matrix(3,0)<<(float)total_matrix(3,1)<<(float)total_matrix(3,2)<<(float)total_matrix(3,3);
        OSCDispatcher::Instance().sender.sendMessage(msg);
    }
    void cmd_color(int r,int g,int b)
    {
        poly_color.set(r,g,b);
    }
    void cmd_hidden(bool ishidden)
    {
         isHidden(ishidden);
    }
    void cmd_bring_top()
    {
        BringTop();
    }
    void cmd_set_layer(int _layer)
    {
        SetLayer(_layer);
    }
    void run_extra(const std::string & cmd, OscOptionalUnpacker & msg)
    {
        if(cmd == "addrectangle")
        {
            float x,y,h,w;
            x=y=h=w=0;
            int round_edge = 0;
            msg >> x >> y >> h >> w >> round_edge;
            if (round_edge)
            {
                std::cout << "TODO: addrectangle: round_edge not implemented" << std::endl;
            }
            AddPoint(ofPoint(x,y));
            AddPoint(ofPoint(x+w,y));
            AddPoint(ofPoint(x+w,y+h));
            AddPoint(ofPoint(x,y+h));
        }
        else if(cmd == "addcircle")
        {
            std::cout << "TODO: addcircle not implemented" << std::endl;
        }
        else if(cmd == "addvertex")
        {
            float fx, fy;
            while (!msg.Eos())
            {
                msg >> fx >> fy;
                AddPoint(ofPoint(fx,fy));
            }
        }
        else if(cmd == "clearvertex")
        {
            Clear();
        }
        else if(cmd == "texture")
        {
            std::string tex_name;
            msg >> tex_name;
            SetTexture(tex_name);
        }
        else if(cmd == "drawpolygon")
        {
            int yesno;
            msg >> yesno;
            drawpolygon = (yesno==1);

        }
        else if(cmd == "drawstroke")
        {
            int yesno;
            msg >> yesno;
            drawstroke = (yesno==1);
        }
        else if(cmd == "strokecolor")
        {
            int r,g,b;
            msg >> r >> g >> b;
            stroke_color.set(r,g,b);
        }
        else if(cmd == "strokewidth")
        {
            std::cout << "TODO: strokewidth not implemented" << std::endl;
        }
        else if(cmd == "touchable")
        {
            std::cout << "TODO: touchable not implemented" << std::endl;
        }
        else
        {
            std::cout << "Polygon: command " << cmd << " not found" << std::endl;
        }

    }
};

class OSCFigureDraw: public Singleton<OSCFigureDraw>
{
public:
    OSCCommonDraw<OSCPolygonObject> o;
    OSCFigureDraw():o("/figure"){}
};

#endif // OSC_POLYGON_HPP_INCLUDED
<|endoftext|>


<commit_before>#include <algorithm>
#include <iostream>
#include <sstream>

#include "parsers/parse_error.hh"
#include "parsers/tina.hh"

namespace pnmc { namespace parsers {

/*------------------------------------------------------------------------------------------------*/

unsigned int
value(std::string::const_iterator cit, std::string::const_iterator cend)
{
  std::string s(cit, cend);
  try
  {
    std::size_t pos;
    auto value = std::stoi(s, &pos);
    std::advance(cit, pos);
    if (std::distance(cit, cend) == 1)
    {
      switch (*cit)
      {
        case 'K': value *= 1000; break;
        case 'M': value *= 1000000; break;
        case 'G': value *= 1000000000; break;
        default: throw parse_error("Invalid suffix, got " + std::string(*cit, 1));
      }
    }
    else if (std::distance(cit, cend) > 1)
    {
      throw parse_error("Invalid suffix, got " + std::string(cit, cend));
    }
    return value;
  }
  catch (const std::invalid_argument&)
  {
    throw parse_error("Expected a value, got " + s);
  }
}

/*------------------------------------------------------------------------------------------------*/

std::pair<std::string, unsigned int>
place_valuation(const std::string& s)
{
  const auto star_cit = std::find(s.cbegin(), s.cend(), '*');
  if (star_cit == s.cend())
  {
    return std::make_pair(s, 1);
  }
  const auto valuation = value(star_cit + 1, s.cend());
  return std::make_pair(std::string(s.cbegin(), star_cit), valuation);
}

/*------------------------------------------------------------------------------------------------*/

unsigned int
marking(const std::string& s)
{
  if (*s.cbegin() == '(' and *std::prev(s.cend()) == ')')
  {
    return value(std::next(s.cbegin()), std::prev(s.cend()));
  }
  else
  {
    throw parse_error("Invalid marking format: " + s);
  }
}

/*------------------------------------------------------------------------------------------------*/

std::shared_ptr<pn::net>
tina(std::istream& in)
{
  std::shared_ptr<pn::net> net_ptr = std::make_shared<pn::net>();
  auto& net = *net_ptr;

  std::string line, s0, s1, s2;
  line.reserve(1024);

  while (std::getline(in, line))
  {
    std::istringstream ss(line);

    // Empty line or comment.
    if (((ss >> std::ws).peek() == std::char_traits<char>::to_int_type('#')) or not (ss >> s0))
    {
      continue;
    }

    // Net
    if (s0 == "net")
    {
      continue;
    }

    // Transitions
    else if (s0 == "tr")
    {
      std::string place_id;
      unsigned int valuation;

      if (ss >> s0)
      {
        net.add_transition(s0);
      }
      else
      {
        throw parse_error("Invalid transition: " + line);
      }

      // Skip time interval, if any.
      const auto c = (ss >> std::ws).peek();
      if (  c == std::char_traits<char>::to_int_type('[')
          or c == std::char_traits<char>::to_int_type(']'))
      {
        ss >> s1;
      }

      bool found_arrow = false;
      while (ss >> s1)
      {
        if (s1 == "->")
        {
          found_arrow = true;
          break;
        }
        std::tie(place_id, valuation) = place_valuation(s1);
        net.add_pre_place(s0, place_id, valuation);
      }

      if (not found_arrow)
      {
        throw parse_error("Invalid transition (missing '->'): " + line);
      }

      while (ss >> s1)
      {
        std::tie(place_id, valuation) = place_valuation(s1);
        net.add_post_place(s0, place_id, valuation);
      }
    }

    // Places
    else if (s0 == "pl")
    {
      if (ss >> s1 >> s2)
      {
        net.add_place(s1, marking(s2));
      }
      else
      {
        throw parse_error("Invalid place: " + line);
      }
    }

    // Error.
    else
    {
      throw parse_error("Invalid line: " + line);
    }
  }

  return net_ptr;
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::parsers
<commit_msg>Handle places with no marking in TINA specifications.<commit_after>#include <algorithm>
#include <iostream>
#include <sstream>

#include "parsers/parse_error.hh"
#include "parsers/tina.hh"

namespace pnmc { namespace parsers {

/*------------------------------------------------------------------------------------------------*/

unsigned int
value(std::string::const_iterator cit, std::string::const_iterator cend)
{
  std::string s(cit, cend);
  try
  {
    std::size_t pos;
    auto value = std::stoi(s, &pos);
    std::advance(cit, pos);
    if (std::distance(cit, cend) == 1)
    {
      switch (*cit)
      {
        case 'K': value *= 1000; break;
        case 'M': value *= 1000000; break;
        case 'G': value *= 1000000000; break;
        default: throw parse_error("Invalid suffix, got " + std::string(*cit, 1));
      }
    }
    else if (std::distance(cit, cend) > 1)
    {
      throw parse_error("Invalid suffix, got " + std::string(cit, cend));
    }
    return value;
  }
  catch (const std::invalid_argument&)
  {
    throw parse_error("Expected a value, got " + s);
  }
}

/*------------------------------------------------------------------------------------------------*/

std::pair<std::string, unsigned int>
place_valuation(const std::string& s)
{
  const auto star_cit = std::find(s.cbegin(), s.cend(), '*');
  if (star_cit == s.cend())
  {
    return std::make_pair(s, 1);
  }
  const auto valuation = value(star_cit + 1, s.cend());
  return std::make_pair(std::string(s.cbegin(), star_cit), valuation);
}

/*------------------------------------------------------------------------------------------------*/

unsigned int
marking(const std::string& s)
{
  if (*s.cbegin() == '(' and *std::prev(s.cend()) == ')')
  {
    return value(std::next(s.cbegin()), std::prev(s.cend()));
  }
  else
  {
    throw parse_error("Invalid marking format: " + s);
  }
}

/*------------------------------------------------------------------------------------------------*/

std::shared_ptr<pn::net>
tina(std::istream& in)
{
  std::shared_ptr<pn::net> net_ptr = std::make_shared<pn::net>();
  auto& net = *net_ptr;

  std::string line, s0, s1, s2;
  line.reserve(1024);

  while (std::getline(in, line))
  {
    std::istringstream ss(line);

    // Empty line or comment.
    if (((ss >> std::ws).peek() == std::char_traits<char>::to_int_type('#')) or not (ss >> s0))
    {
      continue;
    }

    // Net
    if (s0 == "net")
    {
      continue;
    }

    // Transitions
    else if (s0 == "tr")
    {
      std::string place_id;
      unsigned int valuation;

      if (ss >> s0)
      {
        net.add_transition(s0);
      }
      else
      {
        throw parse_error("Invalid transition: " + line);
      }

      // Skip time interval, if any.
      const auto c = (ss >> std::ws).peek();
      if (  c == std::char_traits<char>::to_int_type('[')
          or c == std::char_traits<char>::to_int_type(']'))
      {
        ss >> s1;
      }

      bool found_arrow = false;
      while (ss >> s1)
      {
        if (s1 == "->")
        {
          found_arrow = true;
          break;
        }
        std::tie(place_id, valuation) = place_valuation(s1);
        net.add_pre_place(s0, place_id, valuation);
      }

      if (not found_arrow)
      {
        throw parse_error("Invalid transition (missing '->'): " + line);
      }

      while (ss >> s1)
      {
        std::tie(place_id, valuation) = place_valuation(s1);
        net.add_post_place(s0, place_id, valuation);
      }
    }

    // Places
    else if (s0 == "pl")
    {
      if (ss >> s1)
      {
        if (ss >> s2)
        {
          net.add_place(s1, marking(s2));
        }
        else
        {
          net.add_place(s1, 0);
        }
      }
      else
      {
        throw parse_error("Invalid place: " + line);
      }
    }

    // Error.
    else
    {
      throw parse_error("Invalid line: " + line);
    }
  }

  return net_ptr;
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::parsers
<|endoftext|>


<commit_before>#ifndef GENERICS_H
#define GENERICS_H

#include"objects.hpp"

class Semispace;

/*-----------------------------------------------------------------------------
GenericTraverser
-----------------------------------------------------------------------------*/
/*An abstract base class which provides a
"traverse" method.  This method is invoked
on each reference of an object.
*/

class GenericTraverser {
public:
	virtual void traverse(Object::ref&) =0;
	virtual ~GenericTraverser();
};

/*-----------------------------------------------------------------------------
Generic
-----------------------------------------------------------------------------*/

class Generic {
public:

	virtual void traverse_references(GenericTraverser* gt) {
		/*default to having no references to traverse*/
		/*example for Cons:
		gt->traverse(a);
		gt->traverse(d);
		*/
	}

	/*some objects have extra allocated space at their ends
	(e.g. Closure).
 	This virtual function returns the total size of the class
	plus extra allocated space.
	*/
	virtual size_t real_size(void) const =0;

	/*Copies an object, used for message passing and
	copying garbage collection
	*/
	virtual Generic* clone(Semispace*) const =0;

	/*hash functions for table-ident and table-is*/
	virtual size_t hash_ident(void) const {
		return reinterpret_cast<size_t>(this);
	}
	virtual size_t hash_is(void) const {
		return reinterpret_cast<size_t>(this);
	}

	/*broken hearts for GC*/
	virtual void break_heart(Generic*) =0;

	/*dtor*/
	virtual ~Generic() { }
};

/*-----------------------------------------------------------------------------
Broken Heart tags
-----------------------------------------------------------------------------*/

void throw_OverBrokenHeart(Generic*);

class BrokenHeart : public Generic {
private:
	// disallowed
	BrokenHeart();
	BrokenHeart(BrokenHeart const&);
public:
	Generic* to;
	virtual void break_heart(Generic* to) {
		/*already broken - don't break too much!*/
		throw_OverBrokenHeart(to);
	}
	virtual Generic* clone(Semispace*) const {
		/*broken - why are we cloning this?*/
		throw_OverBrokenHeart(to);
	}
	BrokenHeart(Generic* nto) : to(nto) { }
};

class BrokenHeartVariadic : public BrokenHeart {
private:
	// disallowed
	BrokenHeartVariadic();
	BrokenHeartVariadic(BrokenHeart const&);
protected:
	size_t sz;
public:
	BrokenHeartVariadic(Generic* x, size_t nsz)
		: BrokenHeart(x), sz(nsz) { }
};

/*-----------------------------------------------------------------------------
Size computations
-----------------------------------------------------------------------------*/

template<class T>
static inline size_t compute_size(void) {
	size_t sizeofBrokenHeart = Object::round_up_to_alignment(
			sizeof(BrokenHeart)
	);
	size_t sizeofT = Object::round_up_to_alignment(sizeof(T));
	return
	(sizeofT < sizeofBrokenHeart) ?		sizeofBrokenHeart :
	/*otherwise*/				sizeofT ;
}

template<class T>
static inline size_t compute_size_variadic(size_t sz) {
	/*remember that this is variadic*/
	size_t sizeofBrokenHeart = Object::round_up_to_alignment(
			sizeof(BrokenHeartVariadic)
	);
	size_t sizeofT = Object::round_up_to_alignment(sizeof(T))
			 + Object::round_up_to_alignment(
				sz * sizeof(Object::ref)
		);
	return
	(sizeofT < sizeofBrokenHeart) ?		sizeofBrokenHeart :
	/*otherwise*/				sizeofT ;
}

#endif // GENERICS_H

<commit_msg>inc/generics.hpp: defined destructor for GenericTraverser<commit_after>#ifndef GENERICS_H
#define GENERICS_H

#include"objects.hpp"

class Semispace;

/*-----------------------------------------------------------------------------
GenericTraverser
-----------------------------------------------------------------------------*/
/*An abstract base class which provides a
"traverse" method.  This method is invoked
on each reference of an object.
*/

class GenericTraverser {
public:
	virtual void traverse(Object::ref&) =0;
	virtual ~GenericTraverser() {}
};

/*-----------------------------------------------------------------------------
Generic
-----------------------------------------------------------------------------*/

class Generic {
public:

	virtual void traverse_references(GenericTraverser* gt) {
		/*default to having no references to traverse*/
		/*example for Cons:
		gt->traverse(a);
		gt->traverse(d);
		*/
	}

	/*some objects have extra allocated space at their ends
	(e.g. Closure).
 	This virtual function returns the total size of the class
	plus extra allocated space.
	*/
	virtual size_t real_size(void) const =0;

	/*Copies an object, used for message passing and
	copying garbage collection
	*/
	virtual Generic* clone(Semispace*) const =0;

	/*hash functions for table-ident and table-is*/
	virtual size_t hash_ident(void) const {
		return reinterpret_cast<size_t>(this);
	}
	virtual size_t hash_is(void) const {
		return reinterpret_cast<size_t>(this);
	}

	/*broken hearts for GC*/
	virtual void break_heart(Generic*) =0;

	/*dtor*/
	virtual ~Generic() { }
};

/*-----------------------------------------------------------------------------
Broken Heart tags
-----------------------------------------------------------------------------*/

void throw_OverBrokenHeart(Generic*);

class BrokenHeart : public Generic {
private:
	// disallowed
	BrokenHeart();
	BrokenHeart(BrokenHeart const&);
public:
	Generic* to;
	virtual void break_heart(Generic* to) {
		/*already broken - don't break too much!*/
		throw_OverBrokenHeart(to);
	}
	virtual Generic* clone(Semispace*) const {
		/*broken - why are we cloning this?*/
		throw_OverBrokenHeart(to);
	}
	BrokenHeart(Generic* nto) : to(nto) { }
};

class BrokenHeartVariadic : public BrokenHeart {
private:
	// disallowed
	BrokenHeartVariadic();
	BrokenHeartVariadic(BrokenHeart const&);
protected:
	size_t sz;
public:
	BrokenHeartVariadic(Generic* x, size_t nsz)
		: BrokenHeart(x), sz(nsz) { }
};

/*-----------------------------------------------------------------------------
Size computations
-----------------------------------------------------------------------------*/

template<class T>
static inline size_t compute_size(void) {
	size_t sizeofBrokenHeart = Object::round_up_to_alignment(
			sizeof(BrokenHeart)
	);
	size_t sizeofT = Object::round_up_to_alignment(sizeof(T));
	return
	(sizeofT < sizeofBrokenHeart) ?		sizeofBrokenHeart :
	/*otherwise*/				sizeofT ;
}

template<class T>
static inline size_t compute_size_variadic(size_t sz) {
	/*remember that this is variadic*/
	size_t sizeofBrokenHeart = Object::round_up_to_alignment(
			sizeof(BrokenHeartVariadic)
	);
	size_t sizeofT = Object::round_up_to_alignment(sizeof(T))
			 + Object::round_up_to_alignment(
				sz * sizeof(Object::ref)
		);
	return
	(sizeofT < sizeofBrokenHeart) ?		sizeofBrokenHeart :
	/*otherwise*/				sizeofT ;
}

#endif // GENERICS_H

<|endoftext|>


<commit_before>///
/// @file  pi_legendre.cpp
/// @brief Count the number of primes <= x using Legendre's formula.
///        Legendre's prime counting algorithm is the simplest
///        combinatorial algorithm for counting the number of primes.
///        All other formulas (e.g. Meissel's formula, Lehmer's
///        formula, ...) are extensions of Legendre's formula that
///        run faster but are also more complex.
///
///        Legendre's formula:
///        pi(x) = pi(y) + phi(x, pi(y)) - 1
///        with y = x^(1/2)
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <print.hpp>
#include <isqrt.hpp>

#include <stdint.h>

namespace primecount {

/// Count the number of primes <= x using Legendre's formula.
/// Run time: O(x)
/// Memory usage: O(x^(1/2))
///
int64_t pi_legendre(int64_t x, int threads)
{
  if (x < 2)
    return 0;

  int64_t y = isqrt(x);
  int64_t a = pi_simple(y, threads);

  print("");
  print("=== pi_legendre(x) ===");
  print("pi(x) = phi(x, a) + a - 1");
  print("x", x);
  print("a", a);
  print("threads", threads);

  int64_t sum = phi_print(x, a, threads) + a - 1;

  return sum;
}

/// This is an internal pi(x) implementation based on Legendre's
/// formula which is used for small values of x and which does
/// not print anything to the screen.
///
int64_t pi_simple(int64_t x, int threads)
{
  if (x < 2)
    return 0;

  int64_t y = isqrt(x);
  int64_t a = pi_simple(y, threads);
  int64_t sum = phi(x, a, threads) + a - 1;

  return sum;
}

} // namespace
<commit_msg>Refactor<commit_after>///
/// @file  pi_legendre.cpp
/// @brief Count the number of primes <= x using Legendre's formula.
///        Legendre's prime counting algorithm is the simplest
///        combinatorial algorithm for counting the number of primes.
///        All other formulas (e.g. Meissel's formula, Lehmer's
///        formula, ...) are extensions of Legendre's formula that
///        run faster but are also more complex.
///
///        Legendre's formula:
///        pi(x) = pi(y) + phi(x, pi(y)) - 1
///        with y = x^(1/2)
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <print.hpp>
#include <isqrt.hpp>

#include <stdint.h>

namespace primecount {

/// Count the number of primes <= x using Legendre's formula.
/// Run time: O(x)
/// Memory usage: O(x^(1/2))
///
int64_t pi_legendre(int64_t x, int threads)
{
  if (x < 2)
    return 0;

  int64_t y = isqrt(x);
  int64_t a = pi_simple(y, threads);

  print("");
  print("=== pi_legendre(x) ===");
  print("pi(x) = phi(x, a) + a - 1");
  print("x", x);
  print("a", a);
  print("threads", threads);

  int64_t phi_xa = phi_print(x, a, threads);
  int64_t sum = phi_xa + a - 1;

  return sum;
}

/// This is an internal pi(x) implementation based on Legendre's
/// formula which is used for small values of x and which does
/// not print anything to the screen.
///
int64_t pi_simple(int64_t x, int threads)
{
  if (x < 2)
    return 0;

  int64_t y = isqrt(x);
  int64_t a = pi_simple(y, threads);
  int64_t sum = phi(x, a, threads) + a - 1;

  return sum;
}

} // namespace
<|endoftext|>