<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "Color.h"
#include "Quaternion.h"
#include "Transform.h"
#include "Vector3D.h"
#include "Matrix4.h"
#include "IAttribute.h"
#include "AssetReference.h"

#include <QScriptEngine>
#include <QColor>
#include <QVector3D>
#include <QQuaternion>

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("JavaScriptEngine")

Q_DECLARE_METATYPE(IAttribute*);

QScriptValue toScriptValueColor(QScriptEngine *engine, const Color &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("r", QScriptValue(engine, s.r));
    obj.setProperty("g", QScriptValue(engine, s.g));
    obj.setProperty("b", QScriptValue(engine, s.b));
    obj.setProperty("a", QScriptValue(engine, s.a));
    return obj;
}

void fromScriptValueColor(const QScriptValue &obj, Color &s)
{
    s.r = (float)obj.property("r").toNumber();
    s.g = (float)obj.property("g").toNumber();
    s.b = (float)obj.property("b").toNumber();
    s.a = (float)obj.property("a").toNumber();
}

QScriptValue toScriptValueQColor(QScriptEngine *engine, const QColor &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("r", QScriptValue(engine, s.red()));
    obj.setProperty("g", QScriptValue(engine, s.green()));
    obj.setProperty("b", QScriptValue(engine, s.blue()));
    obj.setProperty("a", QScriptValue(engine, s.alpha()));
    return obj;
}

void fromScriptValueQColor(const QScriptValue &obj, QColor &s)
{
    s.setRed((float)obj.property("r").toNumber());
    s.setGreen((float)obj.property("g").toNumber());
    s.setBlue((float)obj.property("b").toNumber());
    s.setAlpha((float)obj.property("a").toNumber());
}

QScriptValue toScriptValueVector3(QScriptEngine *engine, const Vector3df &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x));
    obj.setProperty("y", QScriptValue(engine, s.y));
    obj.setProperty("z", QScriptValue(engine, s.z));
    return obj;
}

void fromScriptValueVector3(const QScriptValue &obj, Vector3df &s)
{
    s.x = (float)obj.property("x").toNumber();
    s.y = (float)obj.property("y").toNumber();
    s.z = (float)obj.property("z").toNumber();
}

QScriptValue toScriptValueQVector3D(QScriptEngine *engine, const QVector3D &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x()));
    obj.setProperty("y", QScriptValue(engine, s.y()));
    obj.setProperty("z", QScriptValue(engine, s.z()));
    return obj;
}

void fromScriptValueQVector3D(const QScriptValue &obj, QVector3D &s)
{
    s.setX((float)obj.property("x").toNumber());
    s.setY((float)obj.property("y").toNumber());
    s.setZ((float)obj.property("z").toNumber());
}

QScriptValue toScriptValueQuaternion(QScriptEngine *engine, const Quaternion &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x));
    obj.setProperty("y", QScriptValue(engine, s.y));
    obj.setProperty("z", QScriptValue(engine, s.z));
    obj.setProperty("w", QScriptValue(engine, s.w));
    return obj;
}

void fromScriptValueQuaternion(const QScriptValue &obj, Quaternion &s)
{
    s.x = (float)obj.property("x").toNumber();
    s.y = (float)obj.property("y").toNumber();
    s.z = (float)obj.property("z").toNumber();
    s.w = (float)obj.property("w").toNumber();
}

QScriptValue toScriptValueQQuaternion(QScriptEngine *engine, const QQuaternion &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x()));
    obj.setProperty("y", QScriptValue(engine, s.y()));
    obj.setProperty("z", QScriptValue(engine, s.z()));
    obj.setProperty("w", QScriptValue(engine, s.scalar()));
    return obj;
}

void fromScriptValueQQuaternion(const QScriptValue &obj, QQuaternion &s)
{
    s.setX((float)obj.property("x").toNumber());
    s.setY((float)obj.property("y").toNumber());
    s.setZ((float)obj.property("z").toNumber());
    s.setScalar((float)obj.property("w").toNumber());
}

QScriptValue toScriptValueTransform(QScriptEngine *engine, const Transform &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("pos", toScriptValueVector3(engine, s.position));
    obj.setProperty("rot", toScriptValueVector3(engine, s.rotation));
    obj.setProperty("scale", toScriptValueVector3(engine, s.scale));
    return obj;
}

void fromScriptValueTransform(const QScriptValue &obj, Transform &s)
{
    fromScriptValueVector3(obj.property("pos"), s.position);
    fromScriptValueVector3(obj.property("rot"), s.rotation);
    fromScriptValueVector3(obj.property("scale"), s.scale);
}

QScriptValue toScriptValueIAttribute(QScriptEngine *engine, const IAttribute *&s)
{
    QScriptValue obj = engine->newObject();
    if(s)
    {
        obj.setProperty("name", QScriptValue(engine, QString::fromStdString(s->GetNameString())));
        obj.setProperty("typename", QScriptValue(engine, QString::fromStdString(s->TypeName())));
        obj.setProperty("value", QScriptValue(engine, QString::fromStdString(s->ToString())));
    }
    else
    {
        LogError("Fail to get attribute values from IAttribute pointer, cause pointer was a null. returning empty object.");
    }
    return obj;
}

void fromScriptValueAssetReference(const QScriptValue &obj, AssetReference &s)
{
    s.ref = obj.property("ref").toString();
}

QScriptValue toScriptValueAssetReference(QScriptEngine *engine, const AssetReference &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("ref", QScriptValue(engine, s.ref));
    return obj;
}

void fromScriptValueAssetReferenceList(const QScriptValue &obj, AssetReferenceList &s)
{
    ///\todo Implement
//    s.ref = obj.property("ref").toString();
}

QScriptValue toScriptValueAssetReferenceList(QScriptEngine *engine, const AssetReferenceList &s)
{
    QScriptValue obj = engine->newObject();
    ///\todo Implement
//    obj.setProperty("ref", QScriptValue(engine, s.ref));
    return obj;
}

void fromScriptValueIAttribute(const QScriptValue &obj, IAttribute *&s)
{
}

QScriptValue createColor(QScriptContext *ctx, QScriptEngine *engine)
{
    Color newColor;
    return engine->toScriptValue(newColor);
}

QScriptValue createVector3df(QScriptContext *ctx, QScriptEngine *engine)
{
    Vector3df newVec;
    newVec.x = 0;
    newVec.y = 0;
    newVec.z = 0;
    return engine->toScriptValue(newVec);
}

QScriptValue createQuaternion(QScriptContext *ctx, QScriptEngine *engine)
{
    Quaternion newQuat;
    return engine->toScriptValue(newQuat);
}

QScriptValue createTransform(QScriptContext *ctx, QScriptEngine *engine)
{
    Transform newTransform;
    return engine->toScriptValue(newTransform);
}

QScriptValue createAssetReference(QScriptContext *ctx, QScriptEngine *engine)
{
    AssetReference newAssetRef;
    return engine->toScriptValue(newAssetRef);
}

QScriptValue createAssetReferenceList(QScriptContext *ctx, QScriptEngine *engine)
{
    AssetReferenceList newAssetRefList;
    return engine->toScriptValue(newAssetRefList);
}

void RegisterNaaliCoreMetaTypes()
{
    qRegisterMetaType<Color>("Color");
    qRegisterMetaType<Vector3df>("Vector3df");
    qRegisterMetaType<Quaternion>("Quaternion");
    qRegisterMetaType<Transform>("Transform");
    qRegisterMetaType<AssetReference>("AssetReference");
    qRegisterMetaType<AssetReferenceList>("AssetReferenceList");
}

void ExposeNaaliCoreTypes(QScriptEngine *engine)
{
    qScriptRegisterMetaType(engine, toScriptValueColor, fromScriptValueColor);
    qScriptRegisterMetaType(engine, toScriptValueQColor, fromScriptValueQColor);
    qScriptRegisterMetaType(engine, toScriptValueVector3, fromScriptValueVector3);
    qScriptRegisterMetaType(engine, toScriptValueQVector3D, fromScriptValueQVector3D);
    qScriptRegisterMetaType(engine, toScriptValueQuaternion, fromScriptValueQuaternion);
    qScriptRegisterMetaType(engine, toScriptValueQQuaternion, fromScriptValueQQuaternion);
    qScriptRegisterMetaType(engine, toScriptValueTransform, fromScriptValueTransform);
    qScriptRegisterMetaType(engine, toScriptValueAssetReference, fromScriptValueAssetReference);
    qScriptRegisterMetaType(engine, toScriptValueAssetReferenceList, fromScriptValueAssetReferenceList);

    //qScriptRegisterMetaType<IAttribute*>(engine, toScriptValueIAttribute, fromScriptValueIAttribute);
    int id = qRegisterMetaType<IAttribute*>("IAttribute*");
    qScriptRegisterMetaType_helper(
        engine, id, reinterpret_cast<QScriptEngine::MarshalFunction>(toScriptValueIAttribute),
        reinterpret_cast<QScriptEngine::DemarshalFunction>(fromScriptValueIAttribute),
        QScriptValue());

    // Register constructors
    QScriptValue ctorColor = engine->newFunction(createColor);
    engine->globalObject().setProperty("Color", ctorColor);
    QScriptValue ctorVector3df = engine->newFunction(createVector3df);
    engine->globalObject().setProperty("Vector3df", ctorVector3df);
    QScriptValue ctorQuaternion = engine->newFunction(createQuaternion);
    engine->globalObject().setProperty("Quaternion", ctorQuaternion);
    QScriptValue ctorTransform = engine->newFunction(createTransform);
    engine->globalObject().setProperty("Transform", ctorTransform);
    QScriptValue ctorAssetReference = engine->newFunction(createAssetReference);
    engine->globalObject().setProperty("AssetReference", ctorAssetReference);
    QScriptValue ctorAssetReferenceList = engine->newFunction(createAssetReferenceList);
    engine->globalObject().setProperty("AssetReferenceList", ctorAssetReferenceList);

}
<commit_msg>Implement AssetReferenceList script interface.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "Color.h"
#include "Quaternion.h"
#include "Transform.h"
#include "Vector3D.h"
#include "Matrix4.h"
#include "IAttribute.h"
#include "AssetReference.h"

#include <QScriptEngine>
#include <QColor>
#include <QVector3D>
#include <QQuaternion>
#include <QScriptValueIterator>

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("JavaScriptEngine")

Q_DECLARE_METATYPE(IAttribute*);

QScriptValue toScriptValueColor(QScriptEngine *engine, const Color &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("r", QScriptValue(engine, s.r));
    obj.setProperty("g", QScriptValue(engine, s.g));
    obj.setProperty("b", QScriptValue(engine, s.b));
    obj.setProperty("a", QScriptValue(engine, s.a));
    return obj;
}

void fromScriptValueColor(const QScriptValue &obj, Color &s)
{
    s.r = (float)obj.property("r").toNumber();
    s.g = (float)obj.property("g").toNumber();
    s.b = (float)obj.property("b").toNumber();
    s.a = (float)obj.property("a").toNumber();
}

QScriptValue toScriptValueQColor(QScriptEngine *engine, const QColor &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("r", QScriptValue(engine, s.red()));
    obj.setProperty("g", QScriptValue(engine, s.green()));
    obj.setProperty("b", QScriptValue(engine, s.blue()));
    obj.setProperty("a", QScriptValue(engine, s.alpha()));
    return obj;
}

void fromScriptValueQColor(const QScriptValue &obj, QColor &s)
{
    s.setRed((float)obj.property("r").toNumber());
    s.setGreen((float)obj.property("g").toNumber());
    s.setBlue((float)obj.property("b").toNumber());
    s.setAlpha((float)obj.property("a").toNumber());
}

QScriptValue toScriptValueVector3(QScriptEngine *engine, const Vector3df &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x));
    obj.setProperty("y", QScriptValue(engine, s.y));
    obj.setProperty("z", QScriptValue(engine, s.z));
    return obj;
}

void fromScriptValueVector3(const QScriptValue &obj, Vector3df &s)
{
    s.x = (float)obj.property("x").toNumber();
    s.y = (float)obj.property("y").toNumber();
    s.z = (float)obj.property("z").toNumber();
}

QScriptValue toScriptValueQVector3D(QScriptEngine *engine, const QVector3D &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x()));
    obj.setProperty("y", QScriptValue(engine, s.y()));
    obj.setProperty("z", QScriptValue(engine, s.z()));
    return obj;
}

void fromScriptValueQVector3D(const QScriptValue &obj, QVector3D &s)
{
    s.setX((float)obj.property("x").toNumber());
    s.setY((float)obj.property("y").toNumber());
    s.setZ((float)obj.property("z").toNumber());
}

QScriptValue toScriptValueQuaternion(QScriptEngine *engine, const Quaternion &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x));
    obj.setProperty("y", QScriptValue(engine, s.y));
    obj.setProperty("z", QScriptValue(engine, s.z));
    obj.setProperty("w", QScriptValue(engine, s.w));
    return obj;
}

void fromScriptValueQuaternion(const QScriptValue &obj, Quaternion &s)
{
    s.x = (float)obj.property("x").toNumber();
    s.y = (float)obj.property("y").toNumber();
    s.z = (float)obj.property("z").toNumber();
    s.w = (float)obj.property("w").toNumber();
}

QScriptValue toScriptValueQQuaternion(QScriptEngine *engine, const QQuaternion &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("x", QScriptValue(engine, s.x()));
    obj.setProperty("y", QScriptValue(engine, s.y()));
    obj.setProperty("z", QScriptValue(engine, s.z()));
    obj.setProperty("w", QScriptValue(engine, s.scalar()));
    return obj;
}

void fromScriptValueQQuaternion(const QScriptValue &obj, QQuaternion &s)
{
    s.setX((float)obj.property("x").toNumber());
    s.setY((float)obj.property("y").toNumber());
    s.setZ((float)obj.property("z").toNumber());
    s.setScalar((float)obj.property("w").toNumber());
}

QScriptValue toScriptValueTransform(QScriptEngine *engine, const Transform &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("pos", toScriptValueVector3(engine, s.position));
    obj.setProperty("rot", toScriptValueVector3(engine, s.rotation));
    obj.setProperty("scale", toScriptValueVector3(engine, s.scale));
    return obj;
}

void fromScriptValueTransform(const QScriptValue &obj, Transform &s)
{
    fromScriptValueVector3(obj.property("pos"), s.position);
    fromScriptValueVector3(obj.property("rot"), s.rotation);
    fromScriptValueVector3(obj.property("scale"), s.scale);
}

QScriptValue toScriptValueIAttribute(QScriptEngine *engine, const IAttribute *&s)
{
    QScriptValue obj = engine->newObject();
    if(s)
    {
        obj.setProperty("name", QScriptValue(engine, QString::fromStdString(s->GetNameString())));
        obj.setProperty("typename", QScriptValue(engine, QString::fromStdString(s->TypeName())));
        obj.setProperty("value", QScriptValue(engine, QString::fromStdString(s->ToString())));
    }
    else
    {
        LogError("Fail to get attribute values from IAttribute pointer, cause pointer was a null. returning empty object.");
    }
    return obj;
}

void fromScriptValueAssetReference(const QScriptValue &obj, AssetReference &s)
{
    s.ref = obj.property("ref").toString();
}

QScriptValue toScriptValueAssetReference(QScriptEngine *engine, const AssetReference &s)
{
    QScriptValue obj = engine->newObject();
    obj.setProperty("ref", QScriptValue(engine, s.ref));
    return obj;
}

void fromScriptValueAssetReferenceList(const QScriptValue &obj, AssetReferenceList &s)
{
    QScriptValueIterator it(obj);

    while (it.hasNext()) {
        it.next();
        AssetReference reference(it.value().toString());
        s.Append(reference);
    }

}

QScriptValue toScriptValueAssetReferenceList(QScriptEngine *engine, const AssetReferenceList &s)
{
    QScriptValue obj = engine->newObject();

    for( int i = 0; i < s.refs.size(); ++i)
    {
        obj.setProperty(i, QScriptValue(engine, s.refs[i].toString()));
    }

    return obj;
}

void fromScriptValueIAttribute(const QScriptValue &obj, IAttribute *&s)
{
}

QScriptValue createColor(QScriptContext *ctx, QScriptEngine *engine)
{
    Color newColor;
    return engine->toScriptValue(newColor);
}

QScriptValue createVector3df(QScriptContext *ctx, QScriptEngine *engine)
{
    Vector3df newVec;
    newVec.x = 0;
    newVec.y = 0;
    newVec.z = 0;
    return engine->toScriptValue(newVec);
}

QScriptValue createQuaternion(QScriptContext *ctx, QScriptEngine *engine)
{
    Quaternion newQuat;
    return engine->toScriptValue(newQuat);
}

QScriptValue createTransform(QScriptContext *ctx, QScriptEngine *engine)
{
    Transform newTransform;
    return engine->toScriptValue(newTransform);
}

QScriptValue createAssetReference(QScriptContext *ctx, QScriptEngine *engine)
{
    AssetReference newAssetRef;
    return engine->toScriptValue(newAssetRef);
}

QScriptValue createAssetReferenceList(QScriptContext *ctx, QScriptEngine *engine)
{
    AssetReferenceList newAssetRefList;
    return engine->toScriptValue(newAssetRefList);
}

void RegisterNaaliCoreMetaTypes()
{
    qRegisterMetaType<Color>("Color");
    qRegisterMetaType<Vector3df>("Vector3df");
    qRegisterMetaType<Quaternion>("Quaternion");
    qRegisterMetaType<Transform>("Transform");
    qRegisterMetaType<AssetReference>("AssetReference");
    qRegisterMetaType<AssetReferenceList>("AssetReferenceList");
}

void ExposeNaaliCoreTypes(QScriptEngine *engine)
{
    qScriptRegisterMetaType(engine, toScriptValueColor, fromScriptValueColor);
    qScriptRegisterMetaType(engine, toScriptValueQColor, fromScriptValueQColor);
    qScriptRegisterMetaType(engine, toScriptValueVector3, fromScriptValueVector3);
    qScriptRegisterMetaType(engine, toScriptValueQVector3D, fromScriptValueQVector3D);
    qScriptRegisterMetaType(engine, toScriptValueQuaternion, fromScriptValueQuaternion);
    qScriptRegisterMetaType(engine, toScriptValueQQuaternion, fromScriptValueQQuaternion);
    qScriptRegisterMetaType(engine, toScriptValueTransform, fromScriptValueTransform);
    qScriptRegisterMetaType(engine, toScriptValueAssetReference, fromScriptValueAssetReference);
    qScriptRegisterMetaType(engine, toScriptValueAssetReferenceList, fromScriptValueAssetReferenceList);

    //qScriptRegisterMetaType<IAttribute*>(engine, toScriptValueIAttribute, fromScriptValueIAttribute);
    int id = qRegisterMetaType<IAttribute*>("IAttribute*");
    qScriptRegisterMetaType_helper(
        engine, id, reinterpret_cast<QScriptEngine::MarshalFunction>(toScriptValueIAttribute),
        reinterpret_cast<QScriptEngine::DemarshalFunction>(fromScriptValueIAttribute),
        QScriptValue());

    // Register constructors
    QScriptValue ctorColor = engine->newFunction(createColor);
    engine->globalObject().setProperty("Color", ctorColor);
    QScriptValue ctorVector3df = engine->newFunction(createVector3df);
    engine->globalObject().setProperty("Vector3df", ctorVector3df);
    QScriptValue ctorQuaternion = engine->newFunction(createQuaternion);
    engine->globalObject().setProperty("Quaternion", ctorQuaternion);
    QScriptValue ctorTransform = engine->newFunction(createTransform);
    engine->globalObject().setProperty("Transform", ctorTransform);
    QScriptValue ctorAssetReference = engine->newFunction(createAssetReference);
    engine->globalObject().setProperty("AssetReference", ctorAssetReference);
    QScriptValue ctorAssetReferenceList = engine->newFunction(createAssetReferenceList);
    engine->globalObject().setProperty("AssetReferenceList", ctorAssetReferenceList);

}
<|endoftext|>


<commit_before>#include "fast_obj_loader.h"
#include <stdio.h>
#include <stdlib.h>
#include "fastdynamic.h"
#ifdef _OPENMP
#include <omp.h>
#endif
#include <time.h>
#include <string.h>
//bool getcstr(char *out,unsigned short bufflen,char *input,size_t &len) // bufflen = output buffer size // input has to be a copy of the original pointer
//{
//    if(len<=0)
//        return false;

//    unsigned short i=0;
//    while
//}

unsigned int getNextFaceNumber(char *line,size_t &offset,unsigned char &type,unsigned char &nexttype,bool &more,bool &valid)
{
#define buflen 256
    unsigned int output=-1;
    char tmp[buflen+1];
    type=nexttype;
    more = 1;
    unsigned int j=0;
    for(unsigned int i=0;i<buflen;i++)
    {
        switch(line[i+offset])
        {
            case 0:
                more = 0;
                i=buflen;
                nexttype=0;
                break;

            case '/':
                offset+=i+1;
                i=buflen;
                nexttype++;
                break;
            case ' ':
                offset+=i+1;
                i=buflen;
                nexttype=0;
                break;
            default:
                tmp[j]=line[i+offset];
                j++;
                break;

        }
    }
    if(j!=0)
    {
        tmp[j]=0;
        valid=1;
        output=atoi(tmp);
        //sscanf(tmp,"%99u",&output);  0.6seconds vs atoi 0.36seconds from 0.2seconds without face loading
    }
    else
    {
        valid=0;
    }
    return output;
}

obj *loadObj(const char *filename)
{
    obj *output=new obj;

    FILE *f=fopen(filename,"rb");
    if(!f)
    {
        printf("file not found %s\n",filename);
        return 0;
    }
    fseek(f,0,SEEK_END);
    size_t filelength=ftell(f);
    fseek(f,0,SEEK_SET);
    //printf("filesize=%zu bytes\n",filelength);
    char *memoryfile=new char[filelength];

    fread(memoryfile,filelength,1,f);
    timespec start,stop;
    clock_gettime(CLOCK_REALTIME, &start );
    double calltime;

    size_t linecount=0;
    int numthreads=0;
    int numEnds=0;
    size_t numverts=0;
    size_t *lineends;
    FastDynamic<size_t> *tmpends;
    size_t *numtmpends;
    #pragma omp parallel // first get line ends so they can be parsed in parallel
    {
        numthreads=omp_get_num_threads();
        int threadid=omp_get_thread_num();

        #pragma omp single
        {
            tmpends=new FastDynamic<unsigned int>[numthreads];
            numtmpends=new size_t[numthreads];
            for(int i=0;i<numthreads;i++)
            {
                tmpends[i].SetContainer_size(8192);
                numtmpends[i]=0;
            }
        }

        #pragma omp for reduction(+:linecount,numEnds)
        for(size_t i=0;i<filelength;i++)
        {
            //printf("%i\n",i);
            if(memoryfile[i]=='\n')
            {
                tmpends[threadid][numEnds]=i;
                numtmpends[threadid]++;
                numEnds++;
                linecount++;
            }
        }
        #pragma omp single
        {
            lineends=new size_t[numEnds+1];
            lineends[numEnds+1]=filelength;
        }
        #pragma omp for
        for(int i=0;i<numthreads;i++)
        {
            int offset=0;
            for(int j=0;j<i;j++)
            {
                offset+=numtmpends[j];
            }
            tmpends[i].CopyToStatic(&lineends[offset],numtmpends[i]);
        }
        #pragma omp single
        {
            delete [] numtmpends;
            delete [] tmpends;
        }
    }
    FastDynamic<vec3> *tmpverts;
    size_t *numtmpverts;
    #pragma omp parallel
    {
        // read verts for now
        numthreads=omp_get_num_threads();
        int threadid=omp_get_thread_num();

        #pragma omp single
        {
            tmpverts=new FastDynamic<vec3>[numthreads];
            numtmpverts=new size_t[numthreads];
            for(int i=0;i<numthreads;i++)
            {
                tmpverts[i].SetContainer_size(8192);
                numtmpverts[i]=0;
            }
        }

        #pragma omp single
        {
            // read first line here
        }
        #pragma omp single// for reduction(+:numverts)
        for (int i = 1; i < numEnds; i++)
        {
            char line[1024]={0};
            memcpy(&line,&memoryfile[lineends[i-1]+1],lineends[i]-lineends[i-1]-1);
            if(line[0]=='v' && line[1]==' ')
            {
                vec3 vert;
                sscanf(line,"v %99f %99f %99f",&vert.x,&vert.y,&vert.z);
                tmpverts[threadid][numtmpverts[threadid]]=vert;
                numtmpverts[threadid]++;
                numverts++;
            }
            if(line[0]=='f' && line[1]==' ')
            {
                char *data=line+2;
                size_t offset=0;
                bool more=1;
                unsigned char type=0;
                unsigned char nexttype=0;
                while(more)
                {
                    bool valid;
                    unsigned int faceidnum=getNextFaceNumber(data,offset,type,nexttype,more,valid);
                    if(valid)
                    {
                    switch(type)
                    {
                        case 0:
                  //          printf("p:%u ",faceidnum);
                            break;
                        case 1:
                //            printf("u:%u ",faceidnum);
                            break;
                        case 2:
              //              printf("n:%u ",faceidnum);
                            break;
                    }
                    }
                }
            //    printf("\n");
            }
        }
        #pragma omp single
        {
            output->verts=new vec3[numverts];
        }
        #pragma omp for
        for(int i=0;i<numthreads;i++)
        {
            int offset=0;
            for(int j=0;j<i;j++)
            {
                offset+=numtmpverts[j];
            }
            tmpverts[i].CopyToStatic(&(output->verts[offset]),numtmpverts[i]);
        }

        #pragma omp single
        {
            delete [] tmpverts;
            delete [] numtmpverts;
        }
    }

    delete [] lineends;
    //printf("lines:%zu\n",linecount);
    //printf("numthreads:%i\n",numthreads);
    //printf("numverts:%zu\n",numverts);

    clock_gettime(CLOCK_REALTIME, &stop );
    calltime=(stop.tv_sec-start.tv_sec)+(stop.tv_nsec-start.tv_nsec)/1000000000.0;
//    printf("done parsing file %lfseconds\n",calltime);

    delete [] memoryfile;

    fclose(f);
    return output;
}
<commit_msg>added back threading to vert face parsing<commit_after>#include "fast_obj_loader.h"
#include <stdio.h>
#include <stdlib.h>
#include "fastdynamic.h"
#ifdef _OPENMP
#include <omp.h>
#endif
#include <time.h>
#include <string.h>
//bool getcstr(char *out,unsigned short bufflen,char *input,size_t &len) // bufflen = output buffer size // input has to be a copy of the original pointer
//{
//    if(len<=0)
//        return false;

//    unsigned short i=0;
//    while
//}

unsigned int getNextFaceNumber(char *line,size_t &offset,unsigned char &type,unsigned char &nexttype,bool &more,bool &valid)
{
#define buflen 256
    unsigned int output=-1;
    char tmp[buflen+1];
    type=nexttype;
    more = 1;
    unsigned int j=0;
    for(unsigned int i=0;i<buflen;i++)
    {
        switch(line[i+offset])
        {
            case 0:
                more = 0;
                i=buflen;
                nexttype=0;
                break;

            case '/':
                offset+=i+1;
                i=buflen;
                nexttype++;
                break;
            case ' ':
                offset+=i+1;
                i=buflen;
                nexttype=0;
                break;
            default:
                tmp[j]=line[i+offset];
                j++;
                break;

        }
    }
    if(j!=0)
    {
        tmp[j]=0;
        valid=1;
        output=atoi(tmp);
        //sscanf(tmp,"%99u",&output);  0.6seconds vs atoi 0.36seconds from 0.2seconds without face loading
    }
    else
    {
        valid=0;
    }
    return output;
}

obj *loadObj(const char *filename)
{
    obj *output=new obj;

    FILE *f=fopen(filename,"rb");
    if(!f)
    {
        printf("file not found %s\n",filename);
        return 0;
    }
    fseek(f,0,SEEK_END);
    size_t filelength=ftell(f);
    fseek(f,0,SEEK_SET);
    //printf("filesize=%zu bytes\n",filelength);
    char *memoryfile=new char[filelength];

    fread(memoryfile,filelength,1,f);
    timespec start,stop;
    clock_gettime(CLOCK_REALTIME, &start );
    double calltime;

    size_t linecount=0;
    int numthreads=0;
    int numEnds=0;
    size_t numverts=0;
    size_t *lineends;
    FastDynamic<size_t> *tmpends;
    size_t *numtmpends;
    #pragma omp parallel // first get line ends so they can be parsed in parallel
    {
        numthreads=omp_get_num_threads();
        int threadid=omp_get_thread_num();

        #pragma omp single
        {
            tmpends=new FastDynamic<unsigned int>[numthreads];
            numtmpends=new size_t[numthreads];
            for(int i=0;i<numthreads;i++)
            {
                tmpends[i].SetContainer_size(8192);
                numtmpends[i]=0;
            }
        }

        #pragma omp for reduction(+:linecount,numEnds)
        for(size_t i=0;i<filelength;i++)
        {
            //printf("%i\n",i);
            if(memoryfile[i]=='\n')
            {
                tmpends[threadid][numEnds]=i;
                numtmpends[threadid]++;
                numEnds++;
                linecount++;
            }
        }
        #pragma omp single
        {
            lineends=new size_t[numEnds+1];
            lineends[numEnds+1]=filelength;
        }
        #pragma omp for
        for(int i=0;i<numthreads;i++)
        {
            int offset=0;
            for(int j=0;j<i;j++)
            {
                offset+=numtmpends[j];
            }
            tmpends[i].CopyToStatic(&lineends[offset],numtmpends[i]);
        }
        #pragma omp single
        {
            delete [] numtmpends;
            delete [] tmpends;
        }
    }
    FastDynamic<vec3> *tmpverts;
    size_t *numtmpverts;
    #pragma omp parallel
    {
        // read verts for now
        numthreads=omp_get_num_threads();
        int threadid=omp_get_thread_num();

        #pragma omp single
        {
            tmpverts=new FastDynamic<vec3>[numthreads];
            numtmpverts=new size_t[numthreads];
            for(int i=0;i<numthreads;i++)
            {
                tmpverts[i].SetContainer_size(8192);
                numtmpverts[i]=0;
            }
        }

        #pragma omp single
        {
            // read first line here
        }
        #pragma omp for reduction(+:numverts)
        for (int i = 1; i < numEnds; i++)
        {
            char line[1024]={0};
            memcpy(&line,&memoryfile[lineends[i-1]+1],lineends[i]-lineends[i-1]-1);
            if(line[0]=='v' && line[1]==' ')
            {
                vec3 vert;
                sscanf(line,"v %99f %99f %99f",&vert.x,&vert.y,&vert.z);
                tmpverts[threadid][numtmpverts[threadid]]=vert;
                numtmpverts[threadid]++;
                numverts++;
            }
            if(line[0]=='f' && line[1]==' ')
            {
                char *data=line+2;
                size_t offset=0;
                bool more=1;
                unsigned char type=0;
                unsigned char nexttype=0;
                while(more)
                {
                    bool valid;
                    unsigned int faceidnum=getNextFaceNumber(data,offset,type,nexttype,more,valid);
                    if(valid)
                    {
                    switch(type)
                    {
                        case 0:
                  //          printf("p:%u ",faceidnum);
                            break;
                        case 1:
                //            printf("u:%u ",faceidnum);
                            break;
                        case 2:
              //              printf("n:%u ",faceidnum);
                            break;
                    }
                    }
                }
            //    printf("\n");
            }
        }
        #pragma omp single
        {
            output->verts=new vec3[numverts];
        }
        #pragma omp for
        for(int i=0;i<numthreads;i++)
        {
            int offset=0;
            for(int j=0;j<i;j++)
            {
                offset+=numtmpverts[j];
            }
            tmpverts[i].CopyToStatic(&(output->verts[offset]),numtmpverts[i]);
        }

        #pragma omp single
        {
            delete [] tmpverts;
            delete [] numtmpverts;
        }
    }

    delete [] lineends;
    //printf("lines:%zu\n",linecount);
    //printf("numthreads:%i\n",numthreads);
    //printf("numverts:%zu\n",numverts);

    clock_gettime(CLOCK_REALTIME, &stop );
    calltime=(stop.tv_sec-start.tv_sec)+(stop.tv_nsec-start.tv_nsec)/1000000000.0;
//    printf("done parsing file %lfseconds\n",calltime);

    delete [] memoryfile;

    fclose(f);
    return output;
}
<|endoftext|>


<commit_before><commit_msg>some fixes<commit_after><|endoftext|>


<commit_before>#pragma once
#include "base.hpp"
#include <iostream>
#include <iomanip>
#include "leveldb/db.h"
#include "leveldb/filter_policy.h"
#include "leveldb/write_batch.h"

namespace {
	void put (leveldb::WriteBatch& batch, const Slice& key, const Slice& value) {
		batch.Put(
			leveldb::Slice(reinterpret_cast<const char*>(key.begin()), key.length()),
			leveldb::Slice(reinterpret_cast<const char*>(value.begin()), value.length())
		);
	}

	// 0x00 \ SHA256(block)
	void putTip (leveldb::WriteBatch& batch, const hash256_t& id) {
		StackSlice<1 + 32> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x00);
			_data.writeN(id.begin(), 32);
			assert(_data.length() == 0);
		}

		put(batch, data.take(1), data.drop(1));
	}

	// 0x01 | SHA256(SCRIPT) | HEIGHT<BE> | TX_HASH | VOUT
	void putScript (leveldb::WriteBatch& batch, const hash256_t& scHash, uint32_t height, const hash256_t& txHash, uint32_t vout) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x01);
			_data.writeN(scHash.begin(), 32);
			_data.write<uint32_t, true>(height); // big-endian for indexing
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			assert(_data.length() == 0);
		}

		put(batch, data.drop(0), data.take(0));
	}

	// 0x02 | PREV_TX_HASH | PREV_TX_VOUT \ TX_HASH | TX_VIN
	void putSpent (leveldb::WriteBatch& batch, const Slice& prevTxHash, uint32_t vout, const hash256_t& txHash, uint32_t vin) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x02);
			_data.writeN(prevTxHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vin);
			assert(_data.length() == 0);
		}

		put(batch, data.take(37), data.drop(37));
	}

	// 0x03 | TX_HASH \ HEIGHT
	void putTx (leveldb::WriteBatch& batch, const hash256_t& txHash, uint32_t height) {
		StackSlice<1 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x03);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(height);
			assert(_data.length() == 0);
		}

		put(batch, data.take(33), data.drop(33));
	}

	// 0x04 | TX_HASH | VOUT \ VALUE
	void putTxOut (leveldb::WriteBatch& batch, const hash256_t& txHash, uint32_t vout, uint64_t value) {
		StackSlice<1 + 32 + 4 + 8> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x04);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.write<uint64_t>(value);
			assert(_data.length() == 0);
		}

		put(batch, data.take(37), data.drop(37));
	}
}

struct dumpIndexdLevel : public transform_t {
	leveldb::DB* ldb;
	std::atomic_ulong maxHeight;

	dumpIndexdLevel () {
		this->maxHeight = 0;
	}

	~dumpIndexdLevel () {
		if (this->ldb != nullptr) delete this->ldb;
	}

	bool initialize (const char* arg) {
		if (transform_t::initialize(arg)) return true;
		if (strncmp(arg, "-l", 2) == 0) {
			const auto folderName = std::string(arg + 2);

			leveldb::Options options;
			options.create_if_missing = true;
			options.write_buffer_size = 512 * 1024 * 1024; // 512 MiB
		// 	options.filter_policy = leveldb::NewBloomFilterPolicy(10); // TODO

			const auto status = leveldb::DB::Open(options, folderName, &this->ldb);
			assert(status.ok());

			std::cerr << "Opened leveldb at " << folderName << std::endl;
			return true;
		}

		return false;
	}

	void write (leveldb::WriteBatch& batch) {
		this->ldb->Write(leveldb::WriteOptions(), &batch);
	}

	void operator() (const Block& block) {
		assert(this->ldb);
		assert(not this->whitelist.empty());

		hash256_t blockHash;
		uint32_t height = -1;
		if (this->shouldSkip(block, &blockHash, &height)) return;

		leveldb::WriteBatch batch;
		if (height >= this->maxHeight) {
			this->maxHeight = height;
			putTip(batch, blockHash);
		}

		auto transactions = block.transactions();
		while (not transactions.empty()) {
			const auto& transaction = transactions.front();

			hash256_t txHash;
			hash256(txHash.begin(), transaction.data);

			putTx(batch, txHash, height);

			uint32_t vin = 0;
			for (const auto& input : transaction.inputs) {
				putSpent(batch, input.hash, input.vout, txHash, vin);
				++vin;
			}

			uint32_t vout = 0;
			for (const auto& output : transaction.outputs) {
				hash256_t scHash;
				hash256(scHash.begin(), output.script);

				putScript(batch, scHash, height, txHash, vout);
				putTxOut(batch, txHash, vout, output.value);
				++vout;
			}

			transactions.popFront();
		}

		this->write(batch);
	}
};
<commit_msg>leveldb: avoid larger buffer size, write sync instead<commit_after>#pragma once
#include "base.hpp"
#include <iostream>
#include <iomanip>
#include "leveldb/db.h"
#include "leveldb/filter_policy.h"
#include "leveldb/write_batch.h"

namespace {
	void put (leveldb::WriteBatch& batch, const Slice& key, const Slice& value) {
		batch.Put(
			leveldb::Slice(reinterpret_cast<const char*>(key.begin()), key.length()),
			leveldb::Slice(reinterpret_cast<const char*>(value.begin()), value.length())
		);
	}

	// 0x00 \ SHA256(block)
	void putTip (leveldb::WriteBatch& batch, const hash256_t& id) {
		StackSlice<1 + 32> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x00);
			_data.writeN(id.begin(), 32);
			assert(_data.length() == 0);
		}

		put(batch, data.take(1), data.drop(1));
	}

	// 0x01 | SHA256(SCRIPT) | HEIGHT<BE> | TX_HASH | VOUT
	void putScript (leveldb::WriteBatch& batch, const hash256_t& scHash, uint32_t height, const hash256_t& txHash, uint32_t vout) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x01);
			_data.writeN(scHash.begin(), 32);
			_data.write<uint32_t, true>(height); // big-endian for indexing
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			assert(_data.length() == 0);
		}

		put(batch, data.drop(0), data.take(0));
	}

	// 0x02 | PREV_TX_HASH | PREV_TX_VOUT \ TX_HASH | TX_VIN
	void putSpent (leveldb::WriteBatch& batch, const Slice& prevTxHash, uint32_t vout, const hash256_t& txHash, uint32_t vin) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x02);
			_data.writeN(prevTxHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vin);
			assert(_data.length() == 0);
		}

		put(batch, data.take(37), data.drop(37));
	}

	// 0x03 | TX_HASH \ HEIGHT
	void putTx (leveldb::WriteBatch& batch, const hash256_t& txHash, uint32_t height) {
		StackSlice<1 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x03);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(height);
			assert(_data.length() == 0);
		}

		put(batch, data.take(33), data.drop(33));
	}

	// 0x04 | TX_HASH | VOUT \ VALUE
	void putTxOut (leveldb::WriteBatch& batch, const hash256_t& txHash, uint32_t vout, uint64_t value) {
		StackSlice<1 + 32 + 4 + 8> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x04);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.write<uint64_t>(value);
			assert(_data.length() == 0);
		}

		put(batch, data.take(37), data.drop(37));
	}
}

struct dumpIndexdLevel : public transform_t {
	leveldb::DB* ldb;
	std::atomic_ulong maxHeight;

	dumpIndexdLevel () {
		this->maxHeight = 0;
	}

	~dumpIndexdLevel () {
		if (this->ldb != nullptr) delete this->ldb;
	}

	bool initialize (const char* arg) {
		if (transform_t::initialize(arg)) return true;
		if (strncmp(arg, "-l", 2) == 0) {
			const auto folderName = std::string(arg + 2);

			leveldb::Options options;
			options.create_if_missing = true;
		// 	options.filter_policy = leveldb::NewBloomFilterPolicy(10); // TODO

			const auto status = leveldb::DB::Open(options, folderName, &this->ldb);
			assert(status.ok());

			std::cerr << "Opened leveldb at " << folderName << std::endl;
			return true;
		}

		return false;
	}

	void write (leveldb::WriteBatch& batch) {
		leveldb::WriteOptions options;
		write_options.sync = true;
		this->ldb->Write(options, &batch);
	}

	void operator() (const Block& block) {
		assert(this->ldb);
		assert(not this->whitelist.empty());

		hash256_t blockHash;
		uint32_t height = -1;
		if (this->shouldSkip(block, &blockHash, &height)) return;

		leveldb::WriteBatch batch;
		if (height >= this->maxHeight) {
			this->maxHeight = height;
			putTip(batch, blockHash);
		}

		auto transactions = block.transactions();
		while (not transactions.empty()) {
			const auto& transaction = transactions.front();

			hash256_t txHash;
			hash256(txHash.begin(), transaction.data);

			putTx(batch, txHash, height);

			uint32_t vin = 0;
			for (const auto& input : transaction.inputs) {
				putSpent(batch, input.hash, input.vout, txHash, vin);
				++vin;
			}

			uint32_t vout = 0;
			for (const auto& output : transaction.outputs) {
				hash256_t scHash;
				hash256(scHash.begin(), output.script);

				putScript(batch, scHash, height, txHash, vout);
				putTxOut(batch, txHash, vout, output.value);
				++vout;
			}

			transactions.popFront();
		}

		this->write(batch);
	}
};
<|endoftext|>


<commit_before>#pragma once
#include "base.hpp"
#include <iostream>
#include <iomanip>
#include "leveldb/db.h"
#include "leveldb/filter_policy.h"

struct dumpIndexdLevel : public transform_t {
	leveldb::DB* ldb;
	std::atomic_ulong maxHeight;

	dumpIndexdLevel () {
		this->maxHeight = 0;
	}

	~dumpIndexdLevel () {
		if (this->ldb != nullptr) delete this->ldb;
	}

	bool initialize (const char* arg) {
		if (transform_t::initialize(arg)) return true;
		if (strncmp(arg, "-l", 2) == 0) {
			const auto folderName = std::string(arg + 2);

			leveldb::Options options;
			options.create_if_missing = true;
		// 	options.filter_policy = leveldb::NewBloomFilterPolicy(10); // TODO

			const auto status = leveldb::DB::Open(options, folderName, &this->ldb);
			assert(status.ok());

			std::cerr << "Opened leveldb at " << folderName << std::endl;
			return true;
		}

		return false;
	}

	// 0x00 \ SHA256(block)
	void putTip (const hash256_t& id) {
		StackSlice<1 + 32> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x00);
			_data.writeN(id.begin(), 32);
			assert(_data.length() == 0);
		}

		this->put(data.take(1), data.drop(1));
	}

	// 0x01 | SHA256(SCRIPT) | HEIGHT<BE> | TX_HASH | VOUT
	void putScript (const hash256_t& scHash, uint32_t height, const hash256_t& txHash, uint32_t vout) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x01);
			_data.writeN(scHash.begin(), 32);
			_data.write<uint32_t, true>(height);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			assert(_data.length() == 0);
		}

		this->put(data.drop(0), data.take(0));
	}

	// 0x02 | PREV_TX_HASH | PREV_TX_VOUT \ TX_HASH | TX_VIN
	void putSpent (const Slice& prevTxHash, uint32_t vout, const hash256_t& txHash, uint32_t vin) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x02);
			_data.writeN(prevTxHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vin);
			assert(_data.length() == 0);
		}

		this->put(data.take(37), data.drop(37));
	}

	// 0x03 | TX_HASH \ HEIGHT
	void putTx (const hash256_t& txHash, uint32_t height) {
		StackSlice<1 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x03);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(height);
			assert(_data.length() == 0);
		}

		this->put(data.take(33), data.drop(33));
	}

	// 0x04 | TX_HASH | VOUT \ VALUE
	void putTxOut (const hash256_t& txHash, uint32_t vout, uint64_t value) {
		StackSlice<1 + 32 + 4 + 8> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x04);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.write<uint64_t>(value);
			assert(_data.length() == 0);
		}

		this->put(data.take(37), data.drop(37));
	}

	void put (const Slice& key, const Slice& value) {
		std::cerr << "PUT" << std::hex;
		for (size_t i = 0; i < key.length(); ++i) {
			std::cerr << std::setw(2) << std::setfill('0') << (uint32_t) key[i];
		}
		std::cerr << '\\';
		for (size_t i = 0; i < key.length(); ++i) {
			std::cerr << std::setw(2) << std::setfill('0') << (uint32_t) key[i];
		}
		std::cerr << std::dec << std::endl;

// 		this->ldb->Put(
// 			leveldb::WriteOptions(),
// 			leveldb::Slice(key.begin(), key.length()),
// 			leveldb::Slice(value.begin(), value.length())
// 		);
	}

	void operator() (const Block& block) {
		assert(this->ldb);
		assert(not this->whitelist.empty());

		hash256_t blockHash;
		uint32_t height = -1;
		if (this->shouldSkip(block, &blockHash, &height)) return;
		if (height >= this->maxHeight) {
			this->maxHeight = height;
			this->putTip(blockHash);
		}

		auto transactions = block.transactions();
		while (not transactions.empty()) {
			const auto& transaction = transactions.front();

			hash256_t txHash;
			hash256(txHash.begin(), transaction.data);

			this->putTx(txHash, height);

			uint32_t vin = 0;
			for (const auto& input : transaction.inputs) {
				this->putSpent(input.hash, input.vout, txHash, vin);
				++vin;
			}

			uint32_t vout = 0;
			for (const auto& output : transaction.outputs) {
				hash256_t scHash;
				hash256(scHash.begin(), output.script);

				this->putScript(scHash, height, txHash, vout);
				this->putTxOut(txHash, vout, output.value);
				++vout;
			}

			transactions.popFront();
		}
	}
};
<commit_msg>leveldb: debug show value, not key<commit_after>#pragma once
#include "base.hpp"
#include <iostream>
#include <iomanip>
#include "leveldb/db.h"
#include "leveldb/filter_policy.h"

struct dumpIndexdLevel : public transform_t {
	leveldb::DB* ldb;
	std::atomic_ulong maxHeight;

	dumpIndexdLevel () {
		this->maxHeight = 0;
	}

	~dumpIndexdLevel () {
		if (this->ldb != nullptr) delete this->ldb;
	}

	bool initialize (const char* arg) {
		if (transform_t::initialize(arg)) return true;
		if (strncmp(arg, "-l", 2) == 0) {
			const auto folderName = std::string(arg + 2);

			leveldb::Options options;
			options.create_if_missing = true;
		// 	options.filter_policy = leveldb::NewBloomFilterPolicy(10); // TODO

			const auto status = leveldb::DB::Open(options, folderName, &this->ldb);
			assert(status.ok());

			std::cerr << "Opened leveldb at " << folderName << std::endl;
			return true;
		}

		return false;
	}

	// 0x00 \ SHA256(block)
	void putTip (const hash256_t& id) {
		StackSlice<1 + 32> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x00);
			_data.writeN(id.begin(), 32);
			assert(_data.length() == 0);
		}

		this->put(data.take(1), data.drop(1));
	}

	// 0x01 | SHA256(SCRIPT) | HEIGHT<BE> | TX_HASH | VOUT
	void putScript (const hash256_t& scHash, uint32_t height, const hash256_t& txHash, uint32_t vout) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x01);
			_data.writeN(scHash.begin(), 32);
			_data.write<uint32_t, true>(height);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			assert(_data.length() == 0);
		}

		this->put(data.drop(0), data.take(0));
	}

	// 0x02 | PREV_TX_HASH | PREV_TX_VOUT \ TX_HASH | TX_VIN
	void putSpent (const Slice& prevTxHash, uint32_t vout, const hash256_t& txHash, uint32_t vin) {
		StackSlice<1 + 32 + 4 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x02);
			_data.writeN(prevTxHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vin);
			assert(_data.length() == 0);
		}

		this->put(data.take(37), data.drop(37));
	}

	// 0x03 | TX_HASH \ HEIGHT
	void putTx (const hash256_t& txHash, uint32_t height) {
		StackSlice<1 + 32 + 4> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x03);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(height);
			assert(_data.length() == 0);
		}

		this->put(data.take(33), data.drop(33));
	}

	// 0x04 | TX_HASH | VOUT \ VALUE
	void putTxOut (const hash256_t& txHash, uint32_t vout, uint64_t value) {
		StackSlice<1 + 32 + 4 + 8> data;
		{
			auto _data = data.drop(0);
			_data.write<uint8_t>(0x04);
			_data.writeN(txHash.begin(), 32);
			_data.write<uint32_t>(vout);
			_data.write<uint64_t>(value);
			assert(_data.length() == 0);
		}

		this->put(data.take(37), data.drop(37));
	}

	void put (const Slice& key, const Slice& value) {
		std::cerr << "PUT" << std::hex;
		for (size_t i = 0; i < key.length(); ++i) {
			std::cerr << std::setw(2) << std::setfill('0') << (uint32_t) key[i];
		}
		std::cerr << '\\';
		for (size_t i = 0; i < value.length(); ++i) {
			std::cerr << std::setw(2) << std::setfill('0') << (uint32_t) value[i];
		}
		std::cerr << std::dec << std::endl;

// 		this->ldb->Put(
// 			leveldb::WriteOptions(),
// 			leveldb::Slice(key.begin(), key.length()),
// 			leveldb::Slice(value.begin(), value.length())
// 		);
	}

	void operator() (const Block& block) {
		assert(this->ldb);
		assert(not this->whitelist.empty());

		hash256_t blockHash;
		uint32_t height = -1;
		if (this->shouldSkip(block, &blockHash, &height)) return;
		if (height >= this->maxHeight) {
			this->maxHeight = height;
			this->putTip(blockHash);
		}

		auto transactions = block.transactions();
		while (not transactions.empty()) {
			const auto& transaction = transactions.front();

			hash256_t txHash;
			hash256(txHash.begin(), transaction.data);

			this->putTx(txHash, height);

			uint32_t vin = 0;
			for (const auto& input : transaction.inputs) {
				this->putSpent(input.hash, input.vout, txHash, vin);
				++vin;
			}

			uint32_t vout = 0;
			for (const auto& output : transaction.outputs) {
				hash256_t scHash;
				hash256(scHash.begin(), output.script);

				this->putScript(scHash, height, txHash, vout);
				this->putTxOut(txHash, vout, output.value);
				++vout;
			}

			transactions.popFront();
		}
	}
};
<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_roostats
/// \notebook -js
/// Standard demo of the numerical Bayesian calculator
///
/// This is a standard demo that can be used with any ROOT file
/// prepared in the standard way.  You specify:
///  - name for input ROOT file
///  - name of workspace inside ROOT file that holds model and data
///  - name of ModelConfig that specifies details for calculator tools
///  - name of dataset
///
/// With default parameters the macro will attempt to run the
/// standard hist2workspace example and read the ROOT file
/// that it produces.
///
/// The actual heart of the demo is only about 10 lines long.
///
/// The BayesianCalculator is based on Bayes's theorem
/// and performs the integration using ROOT's numeric integration utilities
///
/// \macro_image
/// \macro_output
/// \macro_code
///
/// \author Kyle Cranmer

#include "TFile.h"
#include "TROOT.h"
#include "RooWorkspace.h"
#include "RooAbsData.h"
#include "RooRealVar.h"

#include "RooUniform.h"
#include "RooStats/ModelConfig.h"
#include "RooStats/BayesianCalculator.h"
#include "RooStats/SimpleInterval.h"
#include "RooStats/RooStatsUtils.h"
#include "RooPlot.h"
#include "TSystem.h"

#include <cassert>

using namespace RooFit;
using namespace RooStats;

struct BayesianNumericalOptions {

   double confLevel = 0.95 ;  // interval CL
   TString integrationType = "";  // integration Type (default is adaptive (numerical integration)
                                     // possible values are "TOYMC" (toy MC integration, work when nuisances have a constraints pdf)
                                   //  "VEGAS" , "MISER", or "PLAIN"  (these are all possible MC integration)
   int nToys = 10000;             // number of toys used for the MC integrations - for Vegas should be probably set to an higher value
   bool scanPosterior = false;    // flag to compute interval by scanning posterior (it is more robust but maybe less precise)
   int nScanPoints = 20;          // number of points for scanning the posterior (if scanPosterior = false it is used only for plotting). Use by default a low value to speed-up tutorial
   int intervalType = 1;          // type of interval (0 is shortest, 1 central, 2 upper limit)
   double   maxPOI = -999;        // force a different value of POI for doing the scan (default is given value)
   double   nSigmaNuisance = -1;   // force integration of nuisance parameters to be within nSigma of their error (do first a model fit to find nuisance error)

};

BayesianNumericalOptions optBayes;

void StandardBayesianNumericalDemo(const char* infile = "",
                                   const char* workspaceName = "combined",
                                   const char* modelConfigName = "ModelConfig",
                                   const char* dataName = "obsData") {

   // option definitions
   double confLevel = optBayes.confLevel;
   TString integrationType = optBayes.integrationType;
   int nToys = optBayes.nToys;
   bool scanPosterior = optBayes.scanPosterior;
   int nScanPoints = optBayes.nScanPoints;
   int intervalType = optBayes.intervalType;
   int  maxPOI =  optBayes.maxPOI;
   double  nSigmaNuisance = optBayes.nSigmaNuisance;

   // -------------------------------------------------------
   // First part is just to access a user-defined file
   // or create the standard example file if it doesn't exist

   const char* filename = "";
   if (!strcmp(infile,"")) {
      filename = "results/example_combined_GaussExample_model.root";
      bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code
      // if file does not exists generate with histfactory
      if (!fileExist) {
#ifdef _WIN32
         cout << "HistFactory file cannot be generated on Windows - exit" << endl;
         return;
#endif
         // Normally this would be run on the command line
         cout <<"will run standard hist2workspace example"<<endl;
         gROOT->ProcessLine(".! prepareHistFactory .");
         gROOT->ProcessLine(".! hist2workspace config/example.xml");
         cout <<"\n\n---------------------"<<endl;
         cout <<"Done creating example input"<<endl;
         cout <<"---------------------\n\n"<<endl;
      }

   }
   else
      filename = infile;

   // Try to open the file
   TFile *file = TFile::Open(filename);

   // if input file was specified byt not found, quit
   if(!file ){
      cout <<"StandardRooStatsDemoMacro: Input file " << filename << " is not found" << endl;
      return;
   }

   // -------------------------------------------------------
   // Tutorial starts here
   // -------------------------------------------------------

   // get the workspace out of the file
   RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName);
   if(!w){
      cout <<"workspace not found" << endl;
      return;
   }

   // get the modelConfig out of the file
   ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName);

   // get the modelConfig out of the file
   RooAbsData* data = w->data(dataName);

   // make sure ingredients are found
   if(!data || !mc){
      w->Print();
      cout << "data or ModelConfig was not found" <<endl;
      return;
   }

   // ------------------------------------------
   // create and use the BayesianCalculator
   // to find and plot the 95% credible interval
   // on the parameter of interest as specified
   // in the model config

   // before we do that, we must specify our prior
   // it belongs in the model config, but it may not have
   // been specified
   RooUniform prior("prior","",*mc->GetParametersOfInterest());
   w->import(prior);
   mc->SetPriorPdf(*w->pdf("prior"));

   // do without systematics
   //mc->SetNuisanceParameters(RooArgSet() );
   if (nSigmaNuisance > 0) {
      RooAbsPdf * pdf = mc->GetPdf();
      assert(pdf);
      RooFitResult * res = pdf->fitTo(*data, Save(true), Minimizer(ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str()), Hesse(true),
                                       PrintLevel(ROOT::Math::MinimizerOptions::DefaultPrintLevel()-1) );

      res->Print();
      RooArgList nuisPar(*mc->GetNuisanceParameters());
      for (int i = 0; i < nuisPar.getSize(); ++i) {
         RooRealVar * v = dynamic_cast<RooRealVar*> (&nuisPar[i] );
         assert( v);
         v->setMin( TMath::Max( v->getMin(), v->getVal() - nSigmaNuisance * v->getError() ) );
         v->setMax( TMath::Min( v->getMax(), v->getVal() + nSigmaNuisance * v->getError() ) );
         std::cout << "setting interval for nuisance  " << v->GetName() << " : [ " << v->getMin() << " , " << v->getMax() << " ]" << std::endl;
      }
   }

   BayesianCalculator bayesianCalc(*data,*mc);
   bayesianCalc.SetConfidenceLevel(confLevel); // 95% interval

   // default of the calculator is central interval.  here use shortest , central or upper limit depending on input
   // doing a shortest interval might require a longer time since it requires a scan of the posterior function
   if (intervalType == 0)  bayesianCalc.SetShortestInterval(); // for shortest interval
   if (intervalType == 1)  bayesianCalc.SetLeftSideTailFraction(0.5); // for central interval
   if (intervalType == 2)  bayesianCalc.SetLeftSideTailFraction(0.); // for upper limit

   if (!integrationType.IsNull() ) {
      bayesianCalc.SetIntegrationType(integrationType); // set integrationType
      bayesianCalc.SetNumIters(nToys); // set number of iterations (i.e. number of toys for MC integrations)
   }

   // in case of toyMC make a nuisance pdf
   if (integrationType.Contains("TOYMC") ) {
      RooAbsPdf * nuisPdf = RooStats::MakeNuisancePdf(*mc, "nuisance_pdf");
      cout << "using TOYMC integration: make nuisance pdf from the model " << std::endl;
      nuisPdf->Print();
      bayesianCalc.ForceNuisancePdf(*nuisPdf);
      scanPosterior = true; // for ToyMC the posterior is scanned anyway so used given points
   }

   // compute interval by scanning the posterior function
   if (scanPosterior)
      bayesianCalc.SetScanOfPosterior(nScanPoints);

   RooRealVar* poi = (RooRealVar*) mc->GetParametersOfInterest()->first();
   if (maxPOI != -999 &&  maxPOI > poi->getMin())
      poi->setMax(maxPOI);

   SimpleInterval* interval = bayesianCalc.GetInterval();

   // print out the interval on the first Parameter of Interest
   cout << "\n>>>> RESULT : " << confLevel*100 << "% interval on " << poi->GetName()<<" is : ["<<
      interval->LowerLimit() << ", "<<
      interval->UpperLimit() <<"] "<<endl;

   // make a plot
   // since plotting may take a long time (it requires evaluating
   // the posterior in many points) this command will speed up
   // by reducing the number of points to plot - do 50

   // ignore errors of PDF if is zero
   RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::Ignore) ;

   cout << "\nDrawing plot of posterior function....." << endl;

   // always plot using numer of scan points
   bayesianCalc.SetScanOfPosterior(nScanPoints);

   RooPlot * plot = bayesianCalc.GetPosteriorPlot();
   plot->Draw();

}
<commit_msg>Add plotting of posterior an option to speed up tutorial<commit_after>/// \file
/// \ingroup tutorial_roostats
/// \notebook -js
/// Standard demo of the numerical Bayesian calculator
///
/// This is a standard demo that can be used with any ROOT file
/// prepared in the standard way.  You specify:
///  - name for input ROOT file
///  - name of workspace inside ROOT file that holds model and data
///  - name of ModelConfig that specifies details for calculator tools
///  - name of dataset
///
/// With default parameters the macro will attempt to run the
/// standard hist2workspace example and read the ROOT file
/// that it produces.
///
/// The actual heart of the demo is only about 10 lines long.
///
/// The BayesianCalculator is based on Bayes's theorem
/// and performs the integration using ROOT's numeric integration utilities
///
/// \macro_image
/// \macro_output
/// \macro_code
///
/// \author Kyle Cranmer

#include "TFile.h"
#include "TROOT.h"
#include "RooWorkspace.h"
#include "RooAbsData.h"
#include "RooRealVar.h"

#include "RooUniform.h"
#include "RooStats/ModelConfig.h"
#include "RooStats/BayesianCalculator.h"
#include "RooStats/SimpleInterval.h"
#include "RooStats/RooStatsUtils.h"
#include "RooPlot.h"
#include "TSystem.h"

#include <cassert>

using namespace RooFit;
using namespace RooStats;

struct BayesianNumericalOptions {

   double confLevel = 0.95 ;  // interval CL
   TString integrationType = "";  // integration Type (default is adaptive (numerical integration)
                                     // possible values are "TOYMC" (toy MC integration, work when nuisances have a constraints pdf)
                                   //  "VEGAS" , "MISER", or "PLAIN"  (these are all possible MC integration)
   int nToys = 10000;             // number of toys used for the MC integrations - for Vegas should be probably set to an higher value
   bool scanPosterior = false;    // flag to compute interval by scanning posterior (it is more robust but maybe less precise)
   bool plotPosterior = false;    // plot posterior function after having computed the interval
   int nScanPoints = 50;          // number of points for scanning the posterior (if scanPosterior = false it is used only for plotting). Use by default a low value to speed-up tutorial
   int intervalType = 1;          // type of interval (0 is shortest, 1 central, 2 upper limit)
   double   maxPOI = -999;        // force a different value of POI for doing the scan (default is given value)
   double   nSigmaNuisance = -1;   // force integration of nuisance parameters to be within nSigma of their error (do first a model fit to find nuisance error)

};

BayesianNumericalOptions optBayes;

void StandardBayesianNumericalDemo(const char* infile = "",
                                   const char* workspaceName = "combined",
                                   const char* modelConfigName = "ModelConfig",
                                   const char* dataName = "obsData") {

   // option definitions
   double confLevel = optBayes.confLevel;
   TString integrationType = optBayes.integrationType;
   int nToys = optBayes.nToys;
   bool scanPosterior = optBayes.scanPosterior;
   bool plotPosterior = optBayes.plotPosterior;
   int nScanPoints = optBayes.nScanPoints;
   int intervalType = optBayes.intervalType;
   int  maxPOI =  optBayes.maxPOI;
   double  nSigmaNuisance = optBayes.nSigmaNuisance;

   // -------------------------------------------------------
   // First part is just to access a user-defined file
   // or create the standard example file if it doesn't exist

   const char* filename = "";
   if (!strcmp(infile,"")) {
      filename = "results/example_combined_GaussExample_model.root";
      bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code
      // if file does not exists generate with histfactory
      if (!fileExist) {
#ifdef _WIN32
         cout << "HistFactory file cannot be generated on Windows - exit" << endl;
         return;
#endif
         // Normally this would be run on the command line
         cout <<"will run standard hist2workspace example"<<endl;
         gROOT->ProcessLine(".! prepareHistFactory .");
         gROOT->ProcessLine(".! hist2workspace config/example.xml");
         cout <<"\n\n---------------------"<<endl;
         cout <<"Done creating example input"<<endl;
         cout <<"---------------------\n\n"<<endl;
      }

   }
   else
      filename = infile;

   // Try to open the file
   TFile *file = TFile::Open(filename);

   // if input file was specified byt not found, quit
   if(!file ){
      cout <<"StandardRooStatsDemoMacro: Input file " << filename << " is not found" << endl;
      return;
   }

   // -------------------------------------------------------
   // Tutorial starts here
   // -------------------------------------------------------

   // get the workspace out of the file
   RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName);
   if(!w){
      cout <<"workspace not found" << endl;
      return;
   }

   // get the modelConfig out of the file
   ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName);

   // get the modelConfig out of the file
   RooAbsData* data = w->data(dataName);

   // make sure ingredients are found
   if(!data || !mc){
      w->Print();
      cout << "data or ModelConfig was not found" <<endl;
      return;
   }

   // ------------------------------------------
   // create and use the BayesianCalculator
   // to find and plot the 95% credible interval
   // on the parameter of interest as specified
   // in the model config

   // before we do that, we must specify our prior
   // it belongs in the model config, but it may not have
   // been specified
   RooUniform prior("prior","",*mc->GetParametersOfInterest());
   w->import(prior);
   mc->SetPriorPdf(*w->pdf("prior"));

   // do without systematics
   //mc->SetNuisanceParameters(RooArgSet() );
   if (nSigmaNuisance > 0) {
      RooAbsPdf * pdf = mc->GetPdf();
      assert(pdf);
      RooFitResult * res = pdf->fitTo(*data, Save(true), Minimizer(ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str()), Hesse(true),
                                       PrintLevel(ROOT::Math::MinimizerOptions::DefaultPrintLevel()-1) );

      res->Print();
      RooArgList nuisPar(*mc->GetNuisanceParameters());
      for (int i = 0; i < nuisPar.getSize(); ++i) {
         RooRealVar * v = dynamic_cast<RooRealVar*> (&nuisPar[i] );
         assert( v);
         v->setMin( TMath::Max( v->getMin(), v->getVal() - nSigmaNuisance * v->getError() ) );
         v->setMax( TMath::Min( v->getMax(), v->getVal() + nSigmaNuisance * v->getError() ) );
         std::cout << "setting interval for nuisance  " << v->GetName() << " : [ " << v->getMin() << " , " << v->getMax() << " ]" << std::endl;
      }
   }

   BayesianCalculator bayesianCalc(*data,*mc);
   bayesianCalc.SetConfidenceLevel(confLevel); // 95% interval

   // default of the calculator is central interval.  here use shortest , central or upper limit depending on input
   // doing a shortest interval might require a longer time since it requires a scan of the posterior function
   if (intervalType == 0)  bayesianCalc.SetShortestInterval(); // for shortest interval
   if (intervalType == 1)  bayesianCalc.SetLeftSideTailFraction(0.5); // for central interval
   if (intervalType == 2)  bayesianCalc.SetLeftSideTailFraction(0.); // for upper limit

   if (!integrationType.IsNull() ) {
      bayesianCalc.SetIntegrationType(integrationType); // set integrationType
      bayesianCalc.SetNumIters(nToys); // set number of iterations (i.e. number of toys for MC integrations)
   }

   // in case of toyMC make a nuisance pdf
   if (integrationType.Contains("TOYMC") ) {
      RooAbsPdf * nuisPdf = RooStats::MakeNuisancePdf(*mc, "nuisance_pdf");
      cout << "using TOYMC integration: make nuisance pdf from the model " << std::endl;
      nuisPdf->Print();
      bayesianCalc.ForceNuisancePdf(*nuisPdf);
      scanPosterior = true; // for ToyMC the posterior is scanned anyway so used given points
   }

   // compute interval by scanning the posterior function
   if (scanPosterior)
      bayesianCalc.SetScanOfPosterior(nScanPoints);

   RooRealVar* poi = (RooRealVar*) mc->GetParametersOfInterest()->first();
   if (maxPOI != -999 &&  maxPOI > poi->getMin())
      poi->setMax(maxPOI);

   SimpleInterval* interval = bayesianCalc.GetInterval();

   // print out the interval on the first Parameter of Interest
   cout << "\n>>>> RESULT : " << confLevel*100 << "% interval on " << poi->GetName()<<" is : ["<<
      interval->LowerLimit() << ", "<<
      interval->UpperLimit() <<"] "<<endl;

   // end in case plotting is not requested
   if (!plotPosterior) return;

   // make a plot
   // since plotting may take a long time (it requires evaluating
   // the posterior in many points) this command will speed up
   // by reducing the number of points to plot - do 50

   // ignore errors of PDF if is zero
   RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::Ignore) ;

   cout << "\nDrawing plot of posterior function....." << endl;

   // always plot using numer of scan points
   bayesianCalc.SetScanOfPosterior(nScanPoints);

   RooPlot * plot = bayesianCalc.GetPosteriorPlot();
   plot->Draw();

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cancelcommandexecution.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 16:24:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
#define _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_
#include <com/sun/star/uno/Exception.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_IOERRORCODE_HPP_
#include <com/sun/star/ucb/IOErrorCode.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCOMMANDPROCESSOR_HPP_
#include <com/sun/star/ucb/XCommandProcessor.hpp>
#endif
#ifndef INCLUDED_UCBHELPERDLLAPI_H
#include "ucbhelper/ucbhelperdllapi.h"
#endif

namespace com { namespace sun { namespace star {
    namespace uno { class Any; }
    namespace ucb { class XCommandEnvironment; }
} } }

namespace ucbhelper
{

//============================================================================
/** Cancel the execution of a command by throwing the appropriate exception.
    If an Interaction Handler is given with the command environment and the
    handler handles the exception by selecting the supplied continuation,
    then this function will put the original exception supplied into a
    com::sun::star::ucb::CommandFailedException and throw the
    CommandFailedException. If no handler was given or the handler was not
    able to handle the exception, then the given exception will be thrown
    directly.

    NOTE THAT THIS FUNCTION NEVER RETURNS! IT ALWAYS THROWS AN EXCEPTION!

    @param rException is the exception describing the error to handle.

    @param xEnv is the command environment that may contain an Interaction
           Handler to use before throwing the appropriate exception.
 */
UCBHELPER_DLLPUBLIC void cancelCommandExecution( const com::sun::star::uno::Any & rException,
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandEnvironment > &
                                    xEnv )
    throw( com::sun::star::uno::Exception );

#if SUPD < 641
/** Cancel the execution of a command by throwing the appropriate exception.
    If an Interaction Handler is given with the command environment and the
    handler handles the exception by selecting the supplied continuation,
    then this function will put the original exception supplied into a
    com::sun::star::ucb::CommandFailedException and throw the
    CommandFailedException. If no handler was given or the handler was not
    able to handle the exception, then the given exception will be thrown
    directly.

    NOTE THAT THIS FUNCTION NEVER RETURNS! IT ALWAYS THROWS AN EXCEPTION!

    @param eError is an IO error code.

    @param rArg is a string argument to pass along with the exception. Each
           IO error code can be combined with one or more additional
           arguments. Refer to com/sun/star/ucb/IOErroprCode.idl for details.

    @param xEnv is the command environment that may contain an Interaction
           Handler to use before throwing the appropriate exception.

    @param rMessage is a text containing additional error information.
           Used as debugging aid only. Passed to the member 'Message' of the
           uno::Exception thrown by this function.

    @param xContext is the command processor executing the command to cancel.
           Used as debugging aid only. Passed to the member 'Context' of the
           uno::Exception thrown by this function.
 */
void cancelCommandExecution( const com::sun::star::ucb::IOErrorCode eError,
                             const rtl::OUString & rArg,
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandEnvironment > &
                                    xEnv,
                             const rtl::OUString & rMessage = rtl::OUString(),
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandProcessor > &
                                    xContext = 0 )
    throw( com::sun::star::uno::Exception );

/** Cancel the execution of a command by throwing the appropriate exception.
    If an Interaction Handler is given with the command environment and the
    handler handles the exception by selecting the supplied continuation,
    then this function will put the original exception supplied into a
    com::sun::star::ucb::CommandFailedException and throw the
    CommandFailedException. If no handler was given or the handler was not
    able to handle the exception, then the given exception will be thrown
    directly.

    NOTE THAT THIS FUNCTION NEVER RETURNS! IT ALWAYS THROWS AN EXCEPTION!

    @param eError is an IO error code.

    @param rArg1 is a string to pass as the first argument with the resulting
           InteractivAugmentedIOException. Each IO error code can be combined
           with one or more additional arguments. Refer to
           com/sun/star/ucb/IOErroprCode.idl for details.

    @param rArg2 is a string to pass as the second argument with the resulting
           InteractivAugmentedIOException. Each IO error code can be combined
           with one or more additional arguments. Refer to
           com/sun/star/ucb/IOErroprCode.idl for details.

    @param xEnv is the command environment that may contain an Interaction
           Handler to use before throwing the appropriate exception.

    @param rMessage is a text containing additional error information.
           Used as debugging aid only. Passed to the member 'Message' of the
           uno::Exception thrown by this function.

    @param xContext is the command processor executing the command to cancel.
           Used as debugging aid only. Passed to the member 'Context' of the
           uno::Exception thrown by this function.
 */
void cancelCommandExecution( const com::sun::star::ucb::IOErrorCode eError,
                             const rtl::OUString & rArg1,
                             const rtl::OUString & rArg2,
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandEnvironment > &
                                    xEnv,
                             const rtl::OUString & rMessage = rtl::OUString(),
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandProcessor > &
                                    xContext = 0 )
    throw( com::sun::star::uno::Exception );
#endif // SUPD, 641

/** Cancel the execution of a command by throwing the appropriate exception.
    If an Interaction Handler is given with the command environment and the
    handler handles the exception by selecting the supplied continuation,
    then this function will put the original exception supplied into a
    com::sun::star::ucb::CommandFailedException and throw the
    CommandFailedException. If no handler was given or the handler was not
    able to handle the exception, then the given exception will be thrown
    directly.

    NOTE THAT THIS FUNCTION NEVER RETURNS! IT ALWAYS THROWS AN EXCEPTION!

    @param eError is an IO error code.

    @param rArgs is a sequeence containing the arguments to pass along with
           the exception. Each IO error code can be combined with one or
           more additional arguments. Refer to com/sun/star/ucb/IOErroprCode.idl
           for details.

    @param xEnv is the command environment that may contain an Interaction
           Handler to use before throwing the appropriate exception.

    @param rMessage is a text containing additional error information.
           Used as debugging aid only. Passed to the member 'Message' of the
           uno::Exception thrown by this function.

    @param xContext is the command processor executing the command to cancel.
           Used as debugging aid only. Passed to the member 'Context' of the
           uno::Exception thrown by this function.
 */
UCBHELPER_DLLPUBLIC void cancelCommandExecution( const com::sun::star::ucb::IOErrorCode eError,
                             const com::sun::star::uno::Sequence<
                                com::sun::star::uno::Any > & rArgs,
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandEnvironment > &
                                    xEnv,
                             const rtl::OUString & rMessage = rtl::OUString(),
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandProcessor > &
                                    xContext = 0 )
    throw( com::sun::star::uno::Exception );
}

#endif // _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
<commit_msg>INTEGRATION: CWS supdremove (1.8.82); FILE MERGED 2007/11/16 10:23:37 vg 1.8.82.1: #i83674# cleanup: remove obsolete SUPD macro use<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cancelcommandexecution.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2008-01-07 08:42:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
#define _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_
#include <com/sun/star/uno/Exception.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_IOERRORCODE_HPP_
#include <com/sun/star/ucb/IOErrorCode.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCOMMANDPROCESSOR_HPP_
#include <com/sun/star/ucb/XCommandProcessor.hpp>
#endif
#ifndef INCLUDED_UCBHELPERDLLAPI_H
#include "ucbhelper/ucbhelperdllapi.h"
#endif

namespace com { namespace sun { namespace star {
    namespace uno { class Any; }
    namespace ucb { class XCommandEnvironment; }
} } }

namespace ucbhelper
{

//============================================================================
/** Cancel the execution of a command by throwing the appropriate exception.
    If an Interaction Handler is given with the command environment and the
    handler handles the exception by selecting the supplied continuation,
    then this function will put the original exception supplied into a
    com::sun::star::ucb::CommandFailedException and throw the
    CommandFailedException. If no handler was given or the handler was not
    able to handle the exception, then the given exception will be thrown
    directly.

    NOTE THAT THIS FUNCTION NEVER RETURNS! IT ALWAYS THROWS AN EXCEPTION!

    @param rException is the exception describing the error to handle.

    @param xEnv is the command environment that may contain an Interaction
           Handler to use before throwing the appropriate exception.
 */
UCBHELPER_DLLPUBLIC void cancelCommandExecution( const com::sun::star::uno::Any & rException,
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandEnvironment > &
                                    xEnv )
    throw( com::sun::star::uno::Exception );

/** Cancel the execution of a command by throwing the appropriate exception.
    If an Interaction Handler is given with the command environment and the
    handler handles the exception by selecting the supplied continuation,
    then this function will put the original exception supplied into a
    com::sun::star::ucb::CommandFailedException and throw the
    CommandFailedException. If no handler was given or the handler was not
    able to handle the exception, then the given exception will be thrown
    directly.

    NOTE THAT THIS FUNCTION NEVER RETURNS! IT ALWAYS THROWS AN EXCEPTION!

    @param eError is an IO error code.

    @param rArgs is a sequeence containing the arguments to pass along with
           the exception. Each IO error code can be combined with one or
           more additional arguments. Refer to com/sun/star/ucb/IOErroprCode.idl
           for details.

    @param xEnv is the command environment that may contain an Interaction
           Handler to use before throwing the appropriate exception.

    @param rMessage is a text containing additional error information.
           Used as debugging aid only. Passed to the member 'Message' of the
           uno::Exception thrown by this function.

    @param xContext is the command processor executing the command to cancel.
           Used as debugging aid only. Passed to the member 'Context' of the
           uno::Exception thrown by this function.
 */
UCBHELPER_DLLPUBLIC void cancelCommandExecution( const com::sun::star::ucb::IOErrorCode eError,
                             const com::sun::star::uno::Sequence<
                                com::sun::star::uno::Any > & rArgs,
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandEnvironment > &
                                    xEnv,
                             const rtl::OUString & rMessage = rtl::OUString(),
                             const com::sun::star::uno::Reference<
                                com::sun::star::ucb::XCommandProcessor > &
                                    xContext = 0 )
    throw( com::sun::star::uno::Exception );
}

#endif // _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
<|endoftext|>


<commit_before>// ObjList.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.
#include "stdafx.h"
#include "ObjList.h"
#ifdef HEEKSCAD
#include "../src/MarkedList.h"
#else
#include "HeeksCADInterface.h"
#endif
#include "../tinyxml/tinyxml.h"

ObjList::ObjList(const ObjList& objlist): HeeksObj(objlist), m_index_list_valid(true) {operator=(objlist);}

void ObjList::Clear()
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		(*It)->m_owner = NULL;
		delete *It;
	}
	m_objects.clear();
	m_index_list.clear();
	m_index_list_valid = true;
}

void ObjList::Clear(std::set<HeeksObj*> &to_delete)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end();)
	{
		if(to_delete.find(*It) != to_delete.end())
		{
			(*It)->m_owner = NULL;
			It = m_objects.erase(It);
		}
		else
			It++;
	}
	m_index_list.clear();
	m_index_list_valid = false;
}

const ObjList& ObjList::operator=(const ObjList& objlist)
{
	HeeksObj::operator=(objlist);
	Clear();
	std::list<HeeksObj*>::const_iterator It;
	for (It=objlist.m_objects.begin();It!=objlist.m_objects.end();It++)
	{
		HeeksObj* new_op = (*It)->MakeACopy();
		if(new_op)Add(new_op, NULL);
	}
	return *this;
}

void ObjList::ClearUndoably(void)
{
	if (m_objects.size() == 0) return;
	std::list<HeeksObj*> objects_to_delete = m_objects;
	std::list<HeeksObj*>::iterator It;
	for (It=objects_to_delete.begin();It!=objects_to_delete.end();It++)
	{
#ifdef HEEKSCAD
		wxGetApp().DeleteUndoably(*It);
#else
		heeksCAD->DeleteUndoably(*It);
#endif
	}
	m_objects.clear();
	LoopItStack.clear();
	m_index_list.clear();
	m_index_list_valid = true;
}

HeeksObj* ObjList::MakeACopy(void) const { return new ObjList(*this); }

void ObjList::GetBox(CBox &box)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		HeeksObj* object = *It;
		if(object->OnVisibleLayer() && object->m_visible)
		{
			object->GetBox(box);
		}
	}
}

void ObjList::glCommands(bool select, bool marked, bool no_color)
{
	HeeksObj::glCommands(select, marked, no_color);
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		HeeksObj* object = *It;
		if(object->OnVisibleLayer() && object->m_visible)
		{
			if(select)glPushName((unsigned long)object);
#ifdef HEEKSCAD
			(*It)->glCommands(select, marked || wxGetApp().m_marked_list->ObjectMarked(object), no_color);
#else
			(*It)->glCommands(select, marked || heeksCAD->ObjectMarked(object), no_color);
#endif
			if(select)glPopName();
		}
	}
}

void ObjList::Draw(wxDC& dc){
	HeeksObj::Draw(dc);
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		HeeksObj* object = *It;
		if(object->OnVisibleLayer() && object->m_visible)
		{
			object->Draw(dc);
		}
	}
}

HeeksObj* ObjList::GetFirstChild()
{
	if (m_objects.size()==0) return NULL;
	LoopIt = m_objects.begin();
	return *LoopIt;
}

HeeksObj* ObjList::GetNextChild()
{
	if (m_objects.size()==0 || LoopIt==m_objects.end()) return NULL;
	LoopIt++;
	if (LoopIt==m_objects.end()) return NULL;
	return *LoopIt;
}

void ObjList::recalculate_index_list()
{
	m_index_list.clear();
	m_index_list.resize(m_objects.size());
	int i = 0;
	for(std::list<HeeksObj*>::iterator It=m_objects.begin(); It!=m_objects.end() ;It++, i++)
	{
		HeeksObj* object = *It;
		m_index_list[i] = object;
	}
	m_index_list_valid = true;
}

HeeksObj* ObjList::GetAtIndex(int index)
{
	if(!m_index_list_valid)
	{
		recalculate_index_list();
	}

	if(index < 0 || index >= (int)(m_index_list.size()))return NULL;
	return m_index_list[index];
}

int ObjList::GetNumChildren()
{
	return m_objects.size();
}

bool ObjList::Add(HeeksObj* object, HeeksObj* prev_object)
{
	if (object==NULL) return false;
	if (!CanAdd(object)) return false;
	if (m_objects.size()==0 || prev_object==NULL)
	{
		m_objects.push_back(object);
		LoopIt = m_objects.end();
		LoopIt--;
	}
	else
	{
		for(LoopIt = m_objects.begin(); LoopIt != m_objects.end(); LoopIt++) { if (*LoopIt==prev_object) break; }
		m_objects.insert(LoopIt, object);
	}
	m_index_list_valid = false;
	HeeksObj::Add(object, prev_object);

#ifdef HEEKSCAD
	if((!wxGetApp().m_in_OpenFile || wxGetApp().m_file_open_or_import_type != FileOpenOrImportTypeHeeks) && object->UsesID() && object->m_id == 0)
	{
		object->SetID(wxGetApp().GetNextID(object->GetIDGroupType()));
	}
#else
	if(!heeksCAD->InOpenFile() && object->UsesID() && object->m_id == 0)
	{
		object->SetID(heeksCAD->GetNextID(object->GetIDGroupType()));
	}
#endif

	return true;
}

void ObjList::Remove(HeeksObj* object)
{
	if (object==NULL) return;
	for(LoopIt = m_objects.begin(); LoopIt != m_objects.end(); LoopIt++){
		if(*LoopIt==object)break;
	}
	if(LoopIt != m_objects.end())
	{
		m_objects.erase(LoopIt);
	}
	m_index_list_valid = false;
	HeeksObj::Remove(object);

#ifdef HEEKSCAD
	wxGetApp().RemoveID(object);
#else
	heeksCAD->RemoveID(object);
#endif
}

void ObjList::KillGLLists(void)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++) (*It)->KillGLLists();
}

void ObjList::WriteBaseXML(TiXmlElement *element)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++) (*It)->WriteXML(element);
	HeeksObj::WriteBaseXML(element);
}

void ObjList::ReadBaseXML(TiXmlElement* element)
{
	// loop through all the objects
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem;	pElem = pElem->NextSiblingElement())
	{
#ifdef HEEKSCAD
		HeeksObj* object = wxGetApp().ReadXMLElement(pElem);
#else
		HeeksObj* object = heeksCAD->ReadXMLElement(pElem);
#endif
		if(object)Add(object, NULL);
	}

	HeeksObj::ReadBaseXML(element);
}

bool ObjList::ModifyByMatrix(const double *m)
{
	bool done_with_add_and_remove = false;
	for(std::list<HeeksObj*>::iterator It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		if((*It)->ModifyByMatrix(m))done_with_add_and_remove = true;
	}

	return done_with_add_and_remove;
}

void ObjList::GetTriangles(void(*callbackfunc)(const double* x, const double* n), double cusp, bool just_one_average_normal)
{
	for(std::list<HeeksObj*>::iterator It=m_objects.begin(); It!=m_objects.end() ;It++) (*It)->GetTriangles(callbackfunc, cusp, just_one_average_normal);
}

<commit_msg>fixed a segment fault when draggin a sketch with solids in.<commit_after>// ObjList.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.
#include "stdafx.h"
#include "ObjList.h"
#ifdef HEEKSCAD
#include "../src/MarkedList.h"
#else
#include "HeeksCADInterface.h"
#endif
#include "../tinyxml/tinyxml.h"

ObjList::ObjList(const ObjList& objlist): HeeksObj(objlist), m_index_list_valid(true) {operator=(objlist);}

void ObjList::Clear()
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		(*It)->m_owner = NULL;
		delete *It;
	}
	m_objects.clear();
	m_index_list.clear();
	m_index_list_valid = true;
}

void ObjList::Clear(std::set<HeeksObj*> &to_delete)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end();)
	{
		if(to_delete.find(*It) != to_delete.end())
		{
			(*It)->m_owner = NULL;
			It = m_objects.erase(It);
		}
		else
			It++;
	}
	m_index_list.clear();
	m_index_list_valid = false;
}

const ObjList& ObjList::operator=(const ObjList& objlist)
{
	HeeksObj::operator=(objlist);
	Clear();
	std::list<HeeksObj*>::const_iterator It;
	for (It=objlist.m_objects.begin();It!=objlist.m_objects.end();It++)
	{
		HeeksObj* new_op = (*It)->MakeACopy();
		if(new_op)Add(new_op, NULL);
	}
	return *this;
}

void ObjList::ClearUndoably(void)
{
	if (m_objects.size() == 0) return;
	std::list<HeeksObj*> objects_to_delete = m_objects;
	std::list<HeeksObj*>::iterator It;
	for (It=objects_to_delete.begin();It!=objects_to_delete.end();It++)
	{
#ifdef HEEKSCAD
		wxGetApp().DeleteUndoably(*It);
#else
		heeksCAD->DeleteUndoably(*It);
#endif
	}
	m_objects.clear();
	LoopItStack.clear();
	m_index_list.clear();
	m_index_list_valid = true;
}

HeeksObj* ObjList::MakeACopy(void) const { return new ObjList(*this); }

void ObjList::GetBox(CBox &box)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		HeeksObj* object = *It;
		if(object->OnVisibleLayer() && object->m_visible)
		{
			object->GetBox(box);
		}
	}
}

void ObjList::glCommands(bool select, bool marked, bool no_color)
{
	HeeksObj::glCommands(select, marked, no_color);
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		HeeksObj* object = *It;
		if(object->OnVisibleLayer() && object->m_visible)
		{
			if(select)glPushName((unsigned long)object);
#ifdef HEEKSCAD
			(*It)->glCommands(select, marked || wxGetApp().m_marked_list->ObjectMarked(object), no_color);
#else
			(*It)->glCommands(select, marked || heeksCAD->ObjectMarked(object), no_color);
#endif
			if(select)glPopName();
		}
	}
}

void ObjList::Draw(wxDC& dc){
	HeeksObj::Draw(dc);
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		HeeksObj* object = *It;
		if(object->OnVisibleLayer() && object->m_visible)
		{
			object->Draw(dc);
		}
	}
}

HeeksObj* ObjList::GetFirstChild()
{
	if (m_objects.size()==0) return NULL;
	LoopIt = m_objects.begin();
	return *LoopIt;
}

HeeksObj* ObjList::GetNextChild()
{
	if (m_objects.size()==0 || LoopIt==m_objects.end()) return NULL;
	LoopIt++;
	if (LoopIt==m_objects.end()) return NULL;
	return *LoopIt;
}

void ObjList::recalculate_index_list()
{
	m_index_list.clear();
	m_index_list.resize(m_objects.size());
	int i = 0;
	for(std::list<HeeksObj*>::iterator It=m_objects.begin(); It!=m_objects.end() ;It++, i++)
	{
		HeeksObj* object = *It;
		m_index_list[i] = object;
	}
	m_index_list_valid = true;
}

HeeksObj* ObjList::GetAtIndex(int index)
{
	if(!m_index_list_valid)
	{
		recalculate_index_list();
	}

	if(index < 0 || index >= (int)(m_index_list.size()))return NULL;
	return m_index_list[index];
}

int ObjList::GetNumChildren()
{
	return m_objects.size();
}

bool ObjList::Add(HeeksObj* object, HeeksObj* prev_object)
{
	if (object==NULL) return false;
	if (!CanAdd(object)) return false;
	if (m_objects.size()==0 || prev_object==NULL)
	{
		m_objects.push_back(object);
		LoopIt = m_objects.end();
		LoopIt--;
	}
	else
	{
		for(LoopIt = m_objects.begin(); LoopIt != m_objects.end(); LoopIt++) { if (*LoopIt==prev_object) break; }
		m_objects.insert(LoopIt, object);
	}
	m_index_list_valid = false;
	HeeksObj::Add(object, prev_object);

#ifdef HEEKSCAD
	if((!wxGetApp().m_in_OpenFile || wxGetApp().m_file_open_or_import_type != FileOpenOrImportTypeHeeks) && object->UsesID() && object->m_id == 0)
	{
		object->SetID(wxGetApp().GetNextID(object->GetIDGroupType()));
	}
#else
	if(!heeksCAD->InOpenFile() && object->UsesID() && object->m_id == 0)
	{
		object->SetID(heeksCAD->GetNextID(object->GetIDGroupType()));
	}
#endif

	return true;
}

void ObjList::Remove(HeeksObj* object)
{
	if (object==NULL) return;
	for(LoopIt = m_objects.begin(); LoopIt != m_objects.end(); LoopIt++){
		if(*LoopIt==object)break;
	}
	if(LoopIt != m_objects.end())
	{
		m_objects.erase(LoopIt);
	}
	m_index_list_valid = false;
	HeeksObj::Remove(object);

#ifdef HEEKSCAD
	wxGetApp().RemoveID(object);
#else
	heeksCAD->RemoveID(object);
#endif
}

void ObjList::KillGLLists(void)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++) (*It)->KillGLLists();
}

void ObjList::WriteBaseXML(TiXmlElement *element)
{
	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++) (*It)->WriteXML(element);
	HeeksObj::WriteBaseXML(element);
}

void ObjList::ReadBaseXML(TiXmlElement* element)
{
	// loop through all the objects
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem;	pElem = pElem->NextSiblingElement())
	{
#ifdef HEEKSCAD
		HeeksObj* object = wxGetApp().ReadXMLElement(pElem);
#else
		HeeksObj* object = heeksCAD->ReadXMLElement(pElem);
#endif
		if(object)Add(object, NULL);
	}

	HeeksObj::ReadBaseXML(element);
}

bool ObjList::ModifyByMatrix(const double *m)
{
	bool done_with_add_and_remove = false;
	std::list<HeeksObj*> copy_list = m_objects;
	for(std::list<HeeksObj*>::iterator It=copy_list.begin(); It!=copy_list.end() ;It++)
	{
		if((*It)->ModifyByMatrix(m))done_with_add_and_remove = true;
	}

	return done_with_add_and_remove;
}

void ObjList::GetTriangles(void(*callbackfunc)(const double* x, const double* n), double cusp, bool just_one_average_normal)
{
	for(std::list<HeeksObj*>::iterator It=m_objects.begin(); It!=m_objects.end() ;It++) (*It)->GetTriangles(callbackfunc, cusp, just_one_average_normal);
}

<|endoftext|>