Пример #1
0
static void initCallback(
    int   argc,
    char *argv[]
) {
    const char *methodName = 0;
    if(0<argc) {
        methodName = argv[1];
    }
    if(0==methodName) {
        methodName = "";
    }
    if(0==methodName[0]) {
        methodName = "help";
    }
    gCallback = Callback::find(methodName);
    fprintf(stderr, "\n");

    info("starting command \"%s\"", gCallback->name());

    if(argv[1]) {
        auto i = 0;
        while('-'==argv[1][i]) {
            argv[1][i++] = 'x';
        }
    }

    auto ir = gCallback->init(argc, (const char **)argv);
    if(ir<0) {
        errFatal("callback init failed");
    }
    gNeedTXHash = gCallback->needTXHash();
}
Пример #2
0
ntlWorld::ntlWorld(string filename, bool commandlineMode) 
{
#ifndef ELBEEM_PLUGIN

		initDefaults();
#	ifdef NOGUI
		commandlineMode = true; // remove warning...
#	endif // NOGUI

		// load config
		setPointers( getRenderGlobals() );
		parseFile( filename.c_str() );
#	ifndef NOGUI
		// setup opengl display, save first animation step for start time 
		// init after parsing file...
		if(!commandlineMode) {
			mpOpenGLRenderer = new ntlOpenGLRenderer( mpGlob );
		}
#	endif // NOGUI
		finishWorldInit();

#else // ELBEEM_PLUGIN
	errFatal("ntlWorld::init","Cfg file parsing not supported for API version! "<<filename<<" "<<commandlineMode, SIMWORLD_INITERROR);
#endif // ELBEEM_PLUGIN
}
Пример #3
0
/******************************************************************************
 * Default constructor
 *****************************************************************************/
ntlTree::ntlTree() :
  mStart(0.0), mEnd(0.0), mMaxDepth( 5 ), mMaxListLength( 5 ), mpRoot( NULL) ,
  mpNodeStack( NULL), mpVertices( NULL ), mpVertNormals( NULL ), mpTriangles( NULL ),
  mCurrentDepth(0), mCurrentNodes(0), mTriDoubles(0)
{
  errFatal( "ntlTree","Uninitialized BSP Tree!\n",SIMWORLD_INITERROR );
  return;
}
Пример #4
0
 static char *canonicalize_file_name(
     const char *fileName
 ) {
     auto r = (char*)cygwin_create_path(CCP_WIN_A_TO_POSIX, fileName);
     if(0==r) {
         errFatal("can't canonicalize path %s", fileName);
     }
     return r;
 }
Пример #5
0
//! helper to check if a bounding box was specified in the right way
bool checkBoundingBox(ntlVec3Gfx s, ntlVec3Gfx e, string checker) {
	if( (s[0]>e[0]) ||
			(s[1]>e[1]) ||
			(s[2]>e[2]) ) {
		errFatal("checkBoundingBox","Check by '"<<checker<<"' for BB "<<s<<":"<<e<<" failed! Aborting...",SIMWORLD_INITERROR);
		return 1;
	}
	return 0;
}
Пример #6
0
static std::string getBlockchainDir() {
    auto dir = getenv("BLOCKCHAIN_DIR");
    if(0==dir) {
        dir = getenv("HOME");
        if(0==dir) {
            errFatal("please  specify either env. variable HOME or BLOCKCHAIN_DIR");
        }
    }
    return getNormalizedDirName(
        dir              +
        std::string("/") +
        kCoinDirName
    );
}
Пример #7
0
static void parseInput(
    const Block   *block,
    const uint8_t *&p,
    const uint8_t *txHash,
    uint64_t      inputIndex
) {
    if(!skip) {
        startInput(p);
    }

        auto upTXHash = p;
        const Chunk *upTX = 0;
        if(gNeedTXHash && !skip) {
            auto isGenTX = (0==memcmp(gNullHash.v, upTXHash, sizeof(gNullHash)));
            if(likely(false==isGenTX)) {
                auto i = gTXOMap.find(upTXHash);
                if(unlikely(gTXOMap.end()==i)) {
                    errFatal("failed to locate upstream transaction");
                }
                upTX = i->second;
            }
        }

        SKIP(uint256_t, dummyUpTXhash, p);
        LOAD(uint32_t, upOutputIndex, p);
        LOAD_VARINT(inputScriptSize, p);

        if(!skip && 0!=upTX) {
            auto inputScript = p;
            auto upTXOutputs = upTX->getData();
                parseOutputs<false, true>(
                    upTXOutputs,
                    upTXHash,
                    upOutputIndex,
                    txHash,
                    inputIndex,
                    inputScript,
                    inputScriptSize
                );
            upTX->releaseData();
        }

        p += inputScriptSize;
        SKIP(uint32_t, sequence, p);

    if(!skip) {
        endInput(p);
    }
}
Пример #8
0
void SimulationObject::initGeoTree() {
	// unused!! overriden by solver interface	
	if(mpGlob == NULL) { 
		errFatal("SimulationObject::initGeoTree error","Requires globals!", SIMWORLD_INITERROR); 
		return;
	}
	ntlScene *scene = mpGlob->getSimScene();
	mpGiObjects = scene->getObjects();

	if(mpGiTree != NULL) delete mpGiTree;
	char treeFlag = (1<<(mGeoInitId+4));
	mpGiTree = new ntlTree( 20, 4, // warning - fixed values for depth & maxtriangles here...
												scene, treeFlag );
	// unused!! overriden by solver interface	
}
Пример #9
0
static void parseInput(
    const uint8_t *&p,
    const uint8_t *txHash,
    uint64_t      inputIndex
)
{
    if(!skip) startInput(p);

        const uint8_t *upTXHash = p;
        const uint8_t *upTXOutputs = 0;

        if(gNeedTXHash && !skip) {
            bool isGenTX = (0==memcmp(gNullHash.v, upTXHash, sizeof(gNullHash)));
            if(likely(false==isGenTX)) {
                auto i = gTXMap.find(upTXHash);
                if(unlikely(gTXMap.end()==i))
                    errFatal("failed to locate upstream TX");
                upTXOutputs = i->second;
            }
        }

        SKIP(uint256_t, dummyUpTXhash, p);
        LOAD(uint32_t, upOutputIndex, p);
        LOAD_VARINT(inputScriptSize, p);

        if(!skip && 0!=upTXOutputs) {
            const uint8_t *inputScript = p;
            parseOutputs<false, true>(
                upTXOutputs,
                upTXHash,
                upOutputIndex,
                txHash,
                inputIndex,
                inputScript,
                inputScriptSize
            );
        }

        p += inputScriptSize;
        SKIP(uint32_t, sequence, p);

    if(!skip) endInput(p);
}
Пример #10
0
  virtual void edge(
    uint64_t       value,
    const uint8_t *upTXHash,
    uint64_t       outputIndex,
    const uint8_t *outputScript,
    uint64_t       outputScriptSize,
    const uint8_t *downTXHash,
    uint64_t       inputIndex,
    const uint8_t *inputScript,
    uint64_t       inputScriptSize
    ) {
    uint256_t h;
    uint32_t  oi = outputIndex;

    memcpy(h.v, upTXHash, kSHA256ByteSize);

    uintptr_t ih  = reinterpret_cast<uintptr_t>(h.v);
    uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
    h32[0] ^= oi;

    auto src = outputMap.find(h.v);

    if (outputMap.end() == src) {
      errFatal("unconnected input");
    }

    if (blkID >= firstBlock) {
      fprintf(
        inputFile,
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu32 "\n"
        ,
        inputID++,
        src->second,
        txID,
        (uint32_t)inputIndex
        );
    } else {
      inputID++;
    }
  }
Пример #11
0
    virtual void edge(
        uint64_t      value,
        const uint8_t *upTXHash,
        uint64_t      outputIndex,
        const uint8_t *outputScript,
        uint64_t      outputScriptSize,
        const uint8_t *downTXHash,
        uint64_t      inputIndex,
        const uint8_t *inputScript,
        uint64_t      inputScriptSize
    )
    {
        uint256_t h;
        uint32_t oi = outputIndex;
        memcpy(h.v, upTXHash, kSHA256ByteSize);

        uintptr_t ih = reinterpret_cast<uintptr_t>(h.v);
        uint32_t *h32 = reinterpret_cast<uint32_t*>(ih);
        h32[0] ^= oi;

        auto src = outputMap.find(h.v);
        if(outputMap.end()==src) errFatal("unconnected input");

        // id BIGINT PRIMARY KEY
        // outputID BIGINT
        // txID BIGINT
        // offset INT
        fprintf(
            inputFile,
            "%" PRIu64 "\t"
            "%" PRIu64 "\t"
            "%" PRIu64 "\t"
            "%" PRIu32 "\n"
            ,
            inputID++,
            src->second,
            txID,
            (uint32_t)outputIndex
        );
    }
Пример #12
0
/*! check status (e.g. stop/abort) from calling program, returns !=0 if sth. happened... */
int SimulationObject::checkCallerStatus(int status, int frame) {
	//return 0; // DEBUG
	int ret = 0;
	if((mpElbeemSettings)&&(mpElbeemSettings->runsimCallback)) {
		ret = (mpElbeemSettings->runsimCallback)(mpElbeemSettings->runsimUserData, status,frame);
		if(ret!=FLUIDSIM_CBRET_CONTINUE) {
			if(ret==FLUIDSIM_CBRET_STOP) {
				debMsgStd("SimulationObject::notifySolverOfDump",DM_NOTIFY,"Got stop signal from caller",1);
				setElbeemState( SIMWORLD_STOP );
			}
			else if(ret==FLUIDSIM_CBRET_ABORT) {
				errFatal("SimulationObject::notifySolverOfDump","Got abort signal from caller, aborting...", SIMWORLD_GENERICERROR );
				mPanic = 1;
			}
			else {
				errMsg("SimulationObject::notifySolverOfDump","Invalid callback return value: "<<ret<<", ignoring... ");
			}
		}
	}

	//debMsgStd("SimulationObject::checkCallerStatus",DM_MSG, "s="<<status<<",f="<<frame<<" "<<this->getName()<<" ret="<<ret);
	if(isSimworldOk()) return 0;
	return 1;
}
Пример #13
0
static std::string getNormalizedDirName(
    const std::string &dirName
) {

    auto t = canonicalize_file_name(dirName.c_str());
    if(0==t) {
        errFatal(
            "problem accessing directory %s",
            dirName.c_str()
        );
    }

    auto r = std::string(t);
    free(t);

    auto sz = r.size();
    if(0<sz) {
        if('/'==r[sz-1]) {
            r = std::string(r, 0, sz-2);
        }
    }

    return r;
}
Пример #14
0
int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
{
	if(! isSimworldOk() ) return 1;
	
	// already inited?
	if(mpLbm) return 0;
	
	mpGlob = glob;
	if(!getVisible()) {
		mpAttrs->setAllUsed();
		return 0;
	}


	mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"LbmSolverInterface", "mGeoInitId", false);
	//mDimension, mSolverType are deprecated
	string mSolverType(""); 
	mSolverType = mpAttrs->readString("solver", mSolverType, "SimulationObject","mSolverType", false ); 

	mpLbm = createSolver(); 
  /* check lbm pointer */
	if(mpLbm == NULL) {
		errFatal("SimulationObject::initializeLbmSimulation","Unable to init LBM solver! ", SIMWORLD_INITERROR);
		return 2;
	}
	debMsgStd("SimulationObject::initialized",DM_MSG,"IdStr:"<<mpLbm->getIdString() <<" LBM solver! ", 2);

	mpParts = new ParticleTracer();

	// for non-param simulations
	mpLbm->setParametrizer( mpParam );
	mpParam->setAttrList( getAttributeList() );
	// not needed.. done in solver_init: mpParam->setSize ... in solver_interface
	mpParam->parseAttrList();

	mpLbm->setAttrList( getAttributeList() );
	mpLbm->setSwsAttrList( getSwsAttributeList() );
	mpLbm->parseAttrList();
	mpParts->parseAttrList( getAttributeList() );

	if(! isSimworldOk() ) return 3;
	mpParts->setName( getName() + "_part" );
	mpParts->initialize( glob );
	if(! isSimworldOk() ) return 4;
	
	// init material settings
	string matMc("default");
	matMc = mpAttrs->readString("material_surf", matMc, "SimulationObject","matMc", false );
	mShowSurface   = mpAttrs->readInt("showsurface", mShowSurface, "SimulationObject","mShowSurface", false ); 
	mShowParticles = mpAttrs->readInt("showparticles", mShowParticles, "SimulationObject","mShowParticles", false ); 

	checkBoundingBox( mGeoStart, mGeoEnd, "SimulationObject::initializeSimulation" );
	mpLbm->setLbmInitId( mGeoInitId );
	mpLbm->setGeoStart( mGeoStart );
	mpLbm->setGeoEnd( mGeoEnd );
	mpLbm->setRenderGlobals( mpGlob );
	mpLbm->setName( getName() + "_lbm" );
	mpLbm->setParticleTracer( mpParts );
	if(mpElbeemSettings) {
		// set further settings from API struct init
		if(mpElbeemSettings->outputPath) this->mOutFilename = string(mpElbeemSettings->outputPath);
		mpLbm->initDomainTrafo( mpElbeemSettings->surfaceTrafo );
		mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing);
		mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs);
		mpLbm->setSizeX(mpElbeemSettings->resolutionxyz);
		mpLbm->setSizeY(mpElbeemSettings->resolutionxyz);
		mpLbm->setSizeZ(mpElbeemSettings->resolutionxyz);
		mpLbm->setPreviewSize(mpElbeemSettings->previewresxyz);
		mpLbm->setRefinementDesired(mpElbeemSettings->maxRefine);
		mpLbm->setGenerateParticles(mpElbeemSettings->generateParticles);
		// set initial particles
		mpParts->setNumInitialParticles(mpElbeemSettings->numTracerParticles);
		
		// surface generation flag
		mpLbm->setSurfGenSettings(mpElbeemSettings->mFsSurfGenSetting);

		string dinitType = string("no");
		if     (mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_PARTSLIP) dinitType = string("part"); 
		else if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_FREESLIP) dinitType = string("free"); 
		else /*if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_NOSLIP)*/ dinitType = string("no"); 
		mpLbm->setDomainBound(dinitType);
		mpLbm->setDomainPartSlip(mpElbeemSettings->domainobsPartslip);
		mpLbm->setDumpVelocities(mpElbeemSettings->generateVertexVectors);
		mpLbm->setFarFieldSize(mpElbeemSettings->farFieldSize);
		debMsgStd("SimulationObject::initialize",DM_MSG,"Added domain bound: "<<dinitType<<" ps="<<mpElbeemSettings->domainobsPartslip<<" vv"<<mpElbeemSettings->generateVertexVectors<<","<<mpLbm->getDumpVelocities(), 9 );

		debMsgStd("SimulationObject::initialize",DM_MSG,"Set ElbeemSettings values "<<mpLbm->getGenerateParticles(),10);
	}

	if(! mpLbm->initializeSolverMemory()   )         { errMsg("SimulationObject::initialize","initializeSolverMemory failed"); mPanic=true; return 10; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverMemory status"); mPanic=true; return 11; } 
	if(! mpLbm->initializeSolverGrids()    )         { errMsg("SimulationObject::initialize","initializeSolverGrids  failed"); mPanic=true; return 12; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverGrids  status"); mPanic=true; return 13; } 
	if(! mpLbm->initializeSolverPostinit() )         { errMsg("SimulationObject::initialize","initializeSolverPostin failed"); mPanic=true; return 14; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverPostin status"); mPanic=true; return 15; } 

	// print cell type stats
	bool printStats = true;
	if(glob_mpnum>0) printStats=false; // skip in this case
	if(printStats) {
		const int jmax = sizeof(CellFlagType)*8;
		int totalCells = 0;
		int flagCount[jmax];
		for(int j=0; j<jmax ; j++) flagCount[j] = 0;
		int diffInits = 0;
		LbmSolverInterface::CellIdentifier cid = mpLbm->getFirstCell();
		for(; mpLbm->noEndCell( cid );
					mpLbm->advanceCell( cid ) ) {
			int flag = mpLbm->getCellFlag(cid,0);
			int flag2 = mpLbm->getCellFlag(cid,1);
			if(flag != flag2) {
				diffInits++;
			}
			for(int j=0; j<jmax ; j++) {
				if( flag&(1<<j) ) flagCount[j]++;
			}
			totalCells++;
		}
		mpLbm->deleteCellIterator( &cid );

		char charNl = '\n';
		debugOutNnl("SimulationObject::initializeLbmSimulation celltype stats: " <<charNl, 5);
		debugOutNnl("no. of cells = "<<totalCells<<", "<<charNl ,5);
		for(int j=0; j<jmax ; j++) {
			std::ostringstream out;
			if(flagCount[j]>0) {
				out<<"\t" << flagCount[j] <<" x "<< convertCellFlagType2String( (CellFlagType)(1<<j) ) <<", " << charNl;
				debugOutNnl(out.str(), 5);
			}
		}
		// compute dist. of empty/bnd - fluid - if
		// cfEmpty   = (1<<0), cfBnd  = (1<< 2), cfFluid   = (1<<10), cfInter   = (1<<11),
		if(1){
			std::ostringstream out;
			out.precision(2); out.width(4);
			int totNum = flagCount[1]+flagCount[2]+flagCount[7]+flagCount[8];
			double ebFrac = (double)(flagCount[1]+flagCount[2]) / totNum;
			double flFrac = (double)(flagCount[7]) / totNum;
			double ifFrac = (double)(flagCount[8]) / totNum;
			//???
			out<<"\tFractions: [empty/bnd - fluid - interface - ext. if]  =  [" << ebFrac<<" - " << flFrac<<" - " << ifFrac<<"] "<< charNl;

			if(diffInits > 0) {
				debMsgStd("SimulationObject::initializeLbmSimulation",DM_MSG,"celltype Warning: Diffinits="<<diffInits<<"!" , 5);
			}
			debugOutNnl(out.str(), 5);
		}
	} // cellstats

	// might be modified by mpLbm
	//mpParts->setStart( mGeoStart );?  mpParts->setEnd( mGeoEnd );?
	mpParts->setStart( mpLbm->getGeoStart() );
	mpParts->setEnd(   mpLbm->getGeoEnd()   );
	mpParts->setCastShadows( false );
	mpParts->setReceiveShadows( false );
	mpParts->searchMaterial( glob->getMaterials() );

	// this has to be inited here - before, the values might be unknown
	IsoSurface *surf = mpLbm->getSurfaceGeoObj();
	if(surf) {
		surf->setName( "final" ); // final surface mesh 
		// warning - this might cause overwriting effects for multiple sims and geom dump...
		surf->setCastShadows( true );
		surf->setReceiveShadows( false );
		surf->searchMaterial( glob->getMaterials() );
		if(mShowSurface) mObjects.push_back( surf );
	}
	
#ifdef ELBEEM_PLUGIN
	mShowParticles=1; // for e.g. dumping
#endif // ELBEEM_PLUGIN
	if((mpLbm->getGenerateParticles()>0.0)||(mpParts->getNumInitialParticles()>0)) {
		mShowParticles=1;
		mpParts->setDumpParts(true);
	}
		//debMsgStd("SimulationObject::init",DM_NOTIFY,"Using envvar ELBEEM_DUMPPARTICLE to set mShowParticles, DEBUG!",1);
	//}  // DEBUG ENABLE!!!!!!!!!!
	if(mShowParticles) {
		mObjects.push_back(mpParts);
	}

	// add objects to display for debugging (e.g. levelset particles)
	vector<ntlGeometryObject *> debugObjs = mpLbm->getDebugObjects();
	for(size_t i=0;i<debugObjs.size(); i++) {
		debugObjs[i]->setCastShadows( false );
		debugObjs[i]->setReceiveShadows( false );
		debugObjs[i]->searchMaterial( glob->getMaterials() );
		mObjects.push_back( debugObjs[i] );
		debMsgStd("SimulationObject::init",DM_NOTIFY,"Added debug obj "<<debugObjs[i]->getName(), 10 );
	}
	return 0;
}
Пример #15
0
/******************************************************************************
 * Only dump time dep. objects to file
 *****************************************************************************/
int ntlBlenderDumper::renderScene( void )
{
    char nrStr[5];								/* nr conversion */
    ntlRenderGlobals *glob = mpGlob;
    ntlScene *scene = mpGlob->getSimScene();
    bool debugOut = false;
    bool debugRender = false;
#if ELBEEM_PLUGIN==1
    debugOut = false;
#endif // ELBEEM_PLUGIN==1

    vector<string> gmName; 	 // gm names
    vector<string> gmMat;    // materials for gm
    int numGMs = 0;					 // no. of .obj models created

    if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY,"Dumping geometry data", 1);
    long startTime = getTime();
    snprintf(nrStr, 5, "%04d", glob->getAniCount() );

    // local scene vars
    vector<ntlTriangle> Triangles;
    vector<ntlVec3Gfx>  Vertices;
    vector<ntlVec3Gfx>  VertNormals;

    // check geo objects
    int idCnt = 0;          // give IDs to objects
    for (vector<ntlGeometryClass*>::iterator iter = scene->getGeoClasses()->begin();
            iter != scene->getGeoClasses()->end(); iter++) {
        if(!(*iter)->getVisible()) continue;
        int tid = (*iter)->getTypeId();

        if(tid & GEOCLASSTID_OBJECT) {
            // normal geom. objects -> ignore
        }
        if(tid & GEOCLASSTID_SHADER) {
            ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter); //dynamic_cast<ntlGeometryShader*>(*iter);
            string outname = geoshad->getOutFilename();
            if(outname.length()<1) outname = mpGlob->getOutFilename();
            geoshad->notifyShaderOfDump(DUMP_FULLGEOMETRY, glob->getAniCount(),nrStr,outname);

            for (vector<ntlGeometryObject*>::iterator siter = geoshad->getObjectsBegin();
                    siter != geoshad->getObjectsEnd();
                    siter++) {
                if(debugOut) debMsgStd("ntlBlenderDumper::BuildScene",DM_MSG,"added shader geometry "<<(*siter)->getName(), 8);

                (*siter)->notifyOfDump(DUMP_FULLGEOMETRY, glob->getAniCount(),nrStr,outname, this->mSimulationTime);
                bool doDump = false;
                bool isPreview = false;
                // only dump final&preview surface meshes
                if( (*siter)->getName().find( "final" ) != string::npos) {
                    doDump = true;
                } else if( (*siter)->getName().find( "preview" ) != string::npos) {
                    doDump = true;
                    isPreview = true;
                }
                if(!doDump) continue;

                // dont quit, some objects need notifyOfDump call
                if((glob_mpactive) && (glob_mpindex>0)) {
                    continue; //return 0;
                }

                // only dump geo shader objects
                Triangles.clear();
                Vertices.clear();
                VertNormals.clear();
                (*siter)->initialize( mpGlob );
                (*siter)->getTriangles(this->mSimulationTime, &Triangles, &Vertices, &VertNormals, idCnt);
                idCnt ++;

                // WARNING - this is dirty, but simobjs are the only geoshaders right now
                SimulationObject *sim = (SimulationObject *)geoshad;
                LbmSolverInterface *lbm = sim->getSolver();


                // always dump mesh, even empty ones...

                // dump to binary file
                std::ostringstream boutfilename("");
                //boutfilename << ecrpath.str() << outname <<"_"<< (*siter)->getName() <<"_" << nrStr << ".obj";
                boutfilename << outname <<"_"<< (*siter)->getName() <<"_" << nrStr;
                if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"B-Dumping: "<< (*siter)->getName()
                                           <<", triangles:"<<Triangles.size()<<", vertices:"<<Vertices.size()<<
                                           " to "<<boutfilename.str() , 7);
                gzFile gzf;

                // output velocities if desired
                if((!isPreview) && (lbm->getDumpVelocities())) {
                    std::ostringstream bvelfilename;
                    bvelfilename << boutfilename.str();
                    bvelfilename << ".bvel.gz";
                    gzf = gzopen(bvelfilename.str().c_str(), "wb9");
                    if(gzf) {
                        int numVerts;
                        if(sizeof(numVerts)!=4) {
                            errMsg("ntlBlenderDumper::renderScene","Invalid int size");
                            return 1;
                        }
                        numVerts = Vertices.size();
                        gzwrite(gzf, &numVerts, sizeof(numVerts));
                        for(size_t i=0; i<Vertices.size(); i++) {
                            // returns smoothed velocity, scaled by frame time
                            ntlVec3Gfx v = lbm->getVelocityAt( Vertices[i][0], Vertices[i][1], Vertices[i][2] );
                            // translation not necessary, test rotation & scaling?
                            for(int j=0; j<3; j++) {
                                float vertp = v[j];
                                //if(i<20) errMsg("ntlBlenderDumper","DUMP_VEL final "<<i<<" = "<<v);
                                gzwrite(gzf, &vertp, sizeof(vertp));
                            }
                        }
                        gzclose( gzf );
                    }
                }

                // compress all bobj's
                boutfilename << ".bobj.gz";
                gzf = gzopen(boutfilename.str().c_str(), "wb1"); // wb9 is slow for large meshes!
                if (!gzf) {
                    errMsg("ntlBlenderDumper::renderScene","Unable to open output '"<<boutfilename<<"' ");
                    return 1;
                }

                // dont transform velocity output, this is handled in blender
                // current transform matrix
                ntlMatrix4x4<gfxReal> *trafo;
                trafo = lbm->getDomainTrafo();
                if(trafo) {
                    // transform into source space
                    for(size_t i=0; i<Vertices.size(); i++) {
                        Vertices[i] = (*trafo) * Vertices[i];
                    }
                }
                // rotate vertnormals
                ntlMatrix4x4<gfxReal> rottrafo;
                rottrafo.initId();
                if(lbm->getDomainTrafo()) {
                    // dont modifiy original!
                    rottrafo = *lbm->getDomainTrafo();
                    ntlVec3Gfx rTrans,rScale,rRot,rShear;
                    rottrafo.decompose(rTrans,rScale,rRot,rShear);
                    rottrafo.initRotationXYZ(rRot[0],rRot[1],rRot[2]);
                    // only rotate here...
                    for(size_t i=0; i<Vertices.size(); i++) {
                        VertNormals[i] = rottrafo * VertNormals[i];
                        normalize(VertNormals[i]); // remove scaling etc.
                    }
                }


                // write to file
                int numVerts;
                if(sizeof(numVerts)!=4) {
                    errMsg("ntlBlenderDumper::renderScene","Invalid int size");
                    return 1;
                }
                numVerts = Vertices.size();
                gzwrite(gzf, &numVerts, sizeof(numVerts));
                for(size_t i=0; i<Vertices.size(); i++) {
                    for(int j=0; j<3; j++) {
                        float vertp = Vertices[i][j];
                        gzwrite(gzf, &vertp, sizeof(vertp));
                    }
                }

                // should be the same as Vertices.size
                if(VertNormals.size() != (size_t)numVerts) {
                    errMsg("ntlBlenderDumper::renderScene","Normals have to have same size as vertices!");
                    VertNormals.resize( Vertices.size() );
                }
                gzwrite(gzf, &numVerts, sizeof(numVerts));
                for(size_t i=0; i<VertNormals.size(); i++) {
                    for(int j=0; j<3; j++) {
                        float normp = VertNormals[i][j];
                        gzwrite(gzf, &normp, sizeof(normp));
                    }
                }

                int numTris = Triangles.size();
                gzwrite(gzf, &numTris, sizeof(numTris));
                for(size_t i=0; i<Triangles.size(); i++) {
                    for(int j=0; j<3; j++) {
                        int triIndex = Triangles[i].getPoints()[j];
                        gzwrite(gzf, &triIndex, sizeof(triIndex));
                    }
                }
                gzclose( gzf );
                debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY," Wrote: '"<<boutfilename.str()<<"' ", 2);
                numGMs++;
            }
        }

    }

    // output ecr config file
    if(numGMs>0) {
        if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Objects dumped: "<<numGMs, 10);
    } else {
        if((glob_mpactive) && (glob_mpindex>0)) {
            // ok, nothing to do anyway...
        } else {
            errFatal("ntlBlenderDumper::renderScene","No objects to dump! Aborting...",SIMWORLD_INITERROR);
            return 1;
        }
    }

    // debug timing
    long stopTime = getTime();
    debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Scene #"<<nrStr<<" dump time: "<< getTimeString(stopTime-startTime) <<" ", 10);

    // still render for preview...
    if(debugRender) {
        debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY,"Performing preliminary render", 1);
        ntlWorld::renderScene();
    }
    else {
        // next frame
        glob->setAniCount( glob->getAniCount() +1 );
    }

    return 0;
}
Пример #16
0
//ntlTree::ntlTree(int depth, int objnum, vector<ntlVec3Gfx> *vertices, vector<ntlVec3Gfx> *normals, vector<ntlTriangle> *trilist) :
ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
  mStart(0.0), mEnd(0.0), mMaxDepth( depth ), mMaxListLength( objnum ), mpRoot( NULL) ,
  mpNodeStack( NULL), mpTBB( NULL ),
	mTriangleMask( 0xFFFF ),
  mCurrentDepth(0), mCurrentNodes(0), mTriDoubles(0)
{  
	// init scene data pointers
	mpVertices = scene->getVertexPointer();
	mpVertNormals = scene->getVertexNormalPointer();
	mpTriangles = scene->getTrianglePointer();
	mTriangleMask = triFlagMask;

  if(mpTriangles == NULL) {
    errFatal( "ntlTree Cons","no triangle list!\n",SIMWORLD_INITERROR);
    return;
  }
  if(mpTriangles->size() == 0) {
    warnMsg( "ntlTree::ntlTree","No triangles ("<< mpTriangles->size()  <<")!\n");
		mStart = mEnd = ntlVec3Gfx(0,0,0);
    return;
  }
  if(depth>=BSP_STACK_SIZE) {
    errFatal( "ntlTree::ntlTree","Depth to high ("<< mMaxDepth  <<")!\n", SIMWORLD_INITERROR );
    return;
  }

  /* check triangles (a bit inefficient, but we dont know which vertices belong
     to this tree), and generate bounding boxes */
	mppTriangles = new vector<ntlTriangle *>;
	int noOfTriangles = mpTriangles->size();
	mpTBB = new TriangleBBox[ noOfTriangles ];
	int bbCount = 0;
  mStart = mEnd = (*mpVertices)[ mpTriangles->front().getPoints()[0] ];
	//errMsg("TreeDebug","Start");
  for (vector<ntlTriangle>::iterator iter = mpTriangles->begin();
       iter != mpTriangles->end(); 
       iter++ ) {
		//errorOut(" d "<< convertFlags2String((int)(*iter).getFlags()) <<" "<< convertFlags2String( (int)mTriangleMask)<<" add? "<<( ((int)(*iter).getFlags() & (int)mTriangleMask) != 0 ) );
		// discard triangles that dont match mask
		if( ((int)(*iter).getFlags() & (int)mTriangleMask) == 0 ) {
			continue;
		}

		// test? TODO
		ntlVec3Gfx tnormal = (*mpVertNormals)[ (*iter).getPoints()[0] ]+
			(*mpVertNormals)[ (*iter).getPoints()[1] ]+
			(*mpVertNormals)[ (*iter).getPoints()[2] ];
		ntlVec3Gfx triangleNormal = (*iter).getNormal();
		if( equal(triangleNormal, ntlVec3Gfx(0.0)) ) continue;
		if( equal(       tnormal, ntlVec3Gfx(0.0)) ) continue;
		// */

		ntlVec3Gfx bbs, bbe;
		//errMsg("TreeDebug","Triangle");
		for(int i=0;i<3;i++) {
			int index = (*iter).getPoints()[i];
			ntlVec3Gfx tp = (*mpVertices)[ index ];
			//errMsg("TreeDebug","  Point "<<i<<" = "<<tp<<" ");
			if(tp[0] < mStart[0]) mStart[0]= tp[0];
			if(tp[0] > mEnd[0])   mEnd[0]= tp[0];
			if(tp[1] < mStart[1]) mStart[1]= tp[1];
			if(tp[1] > mEnd[1])   mEnd[1]= tp[1];
			if(tp[2] < mStart[2]) mStart[2]= tp[2];
			if(tp[2] > mEnd[2])   mEnd[2]= tp[2];
			if(i==0) {
				bbs = bbe = tp; 
			} else {
				if( tp[0] < bbs[0] ) bbs[0] = tp[0];
				if( tp[0] > bbe[0] ) bbe[0] = tp[0];
				if( tp[1] < bbs[1] ) bbs[1] = tp[1];
				if( tp[1] > bbe[1] ) bbe[1] = tp[1];
				if( tp[2] < bbs[2] ) bbs[2] = tp[2];
				if( tp[2] > bbe[2] ) bbe[2] = tp[2];
			}
		}
		mppTriangles->push_back( &(*iter) );
		//errMsg("TreeDebug","Triangle "<<(*mpVertices)[(*iter).getPoints()[0]]<<" "<<(*mpVertices)[(*iter).getPoints()[1]]<<" "<<(*mpVertices)[(*iter).getPoints()[2]]<<" ");

		// add BB
		mpTBB[ bbCount ].start = bbs;
		mpTBB[ bbCount ].end = bbe;
		(*iter).setBBoxId( bbCount );
		bbCount++;
  }
	
	

  /* slighlty enlarge bounding tolerance for tree 
     to avoid problems with triangles paralell to slabs */
  mStart -= ntlVec3Gfx( getVecEpsilon() );
  mEnd   += ntlVec3Gfx( getVecEpsilon() );

  /* init root node and stack */
  mpNodeStack = new BSPStack;
  mpRoot = new BSPNode;
  mpRoot->min = mStart;
  mpRoot->max = mEnd;
  mpRoot->axis = AXIS_X;
  mpRoot->members = mppTriangles;
	mpRoot->child[0] = mpRoot->child[1] = NULL;
	mpRoot->cloneVec = 0;
	globalSortingPoints = mpVertices;
	mpTriDist = new char[ mppTriangles->size() ];
	mNumNodes = 1;
	mAbortSubdiv = 0;

  /* create tree */
  debugOutInter( "Generating BSP Tree...  (Nodes "<< mCurrentNodes <<
						", Depth "<<mCurrentDepth<< ") ", 2, 2000 );
  subdivide(mpRoot, 0, AXIS_X);
  debMsgStd("ntlTree::ntlTree",DM_MSG,"Generated Tree: Nodes "<< mCurrentNodes <<
							 ", Depth "<<mCurrentDepth<< " with "<<noOfTriangles<<" triangles", 2 );

	delete [] mpTriDist;
	delete [] mpTBB;
	mpTriDist = NULL;
	mpTBB = NULL;

	/* calculate some stats about tree */
	int noLeafs = 0;
	gfxReal avgDepth = 0.0;
	gfxReal triPerLeaf = 0.0;
	int totalTris = 0;
	
	calcStats(mpRoot,0, noLeafs, avgDepth, triPerLeaf, totalTris);
	avgDepth /= (gfxReal)noLeafs;
	triPerLeaf /= (gfxReal)noLeafs;
	debMsgStd("ntlTree::ntlTree",DM_MSG,"Tree ("<<doSort<<","<<chooseAxis<<") Stats: Leafs:"<<noLeafs<<", avgDepth:"<<avgDepth<<
			", triPerLeaf:"<<triPerLeaf<<", triDoubles:"<<mTriDoubles<<", totalTris:"<<totalTris
			<<" nodes:"<<mNumNodes
			//<<" T"<< (totalTris%3)  // 0=ich, 1=f, 2=a
			, 2 );

	if(mAbortSubdiv) {
		errMsg("ntlTree::ntlTree","Aborted... "<<mNumNodes);
  	deleteNode(mpRoot);
		mpRoot = NULL;
	}
}