void kinematicSingleLayer::evolveRegion()
{
    if (debug)
    {
        InfoInFunction << endl;
    }

    // Update film coverage indicator
    correctAlpha();

    // Update film wall and surface velocities
    updateSurfaceVelocities();

    // Update sub-models to provide updated source contributions
    updateSubmodels();

    // Solve continuity for deltaRho_
    solveContinuity();

    // Implicit pressure source coefficient - constant
    tmp<volScalarField> tpp(this->pp());

    for (int oCorr=1; oCorr<=nOuterCorr_; oCorr++)
    {
        // Explicit pressure source contribution - varies with delta_
        tmp<volScalarField> tpu(this->pu());

        // Solve for momentum for U_
        tmp<fvVectorMatrix> UEqn = solveMomentum(tpu(), tpp());

        // Film thickness correction loop
        for (int corr=1; corr<=nCorr_; corr++)
        {
            // Solve thickness for delta_
            solveThickness(tpu(), tpp(), UEqn());
        }
    }

    // Update deltaRho_ with new delta_
    deltaRho_ == delta_*rho_;

    // Reset source terms for next time integration
    resetPrimaryRegionSourceTerms();
}
//-----------------------------------------------------------------------
void AtlasImageTool::process (void)
{
	Ogre::Root root("", "", "atlas.log");
	Ogre::ResourceGroupManager::getSingleton().addResourceLocation(mImagePath, "FileSystem");
	Ogre::StringVector::iterator itInputFileName;
	Ogre::StringVector::iterator itFrame;
	Ogre::StringVector::iterator itAlpha;

	itAlpha = mAlpha.begin();
	if (mInputFrames.empty() || mInputFrames[0] == Ogre::StringUtil::BLANK)
	{
		// No Frames are assigned so just add them
		for (itInputFileName = mInputFileNames.begin(); itInputFileName != mInputFileNames.end(); ++itInputFileName)
		{
			Ogre::String imageFileName = *itInputFileName;
			Ogre::Image image;
			image.load(imageFileName, "General");

			if (itAlpha != mAlpha.end() && *itAlpha != Ogre::StringUtil::BLANK)
			{
				Ogre::Real alpha = Ogre::StringConverter::parseReal(*itAlpha);
				correctAlpha(image, alpha);
				itAlpha++;
			}

			mAtlasImage.addImage(&image);
		}
	}
	else
	{
		// Frames are assigned, so generate intermediate images
		itInputFileName = mInputFileNames.begin();
		Ogre::Real alpha = 1.0f;
		Ogre::String nextImageFileName = *itInputFileName;
		Ogre::Image nextImage;
		itFrame = mInputFrames.begin();
		size_t nextFrame = Ogre::StringConverter::parseUnsignedInt(*itFrame);
		nextImage.load(nextImageFileName, "General");
		size_t frameCounter = 0;

		if (!mAlpha.empty() && mAlpha[0] != Ogre::StringUtil::BLANK)
		{
			itAlpha = mAlpha.begin();
			Ogre::Real alpha = Ogre::StringConverter::parseReal(*itAlpha);
			correctAlpha(nextImage, alpha);
			itAlpha++;
		}

		mAtlasImage.addImage(&nextImage);
		frameCounter++;
		itInputFileName++;
		itFrame++;

		while (itInputFileName != mInputFileNames.end())
		{
			// Get the next filename
			Ogre::Image firstImage(nextImage);
			nextImageFileName = *itInputFileName;
			nextImage.load(nextImageFileName, "General");

			if (itAlpha != mAlpha.end() && *itAlpha != Ogre::StringUtil::BLANK)
			{
				Ogre::Real alpha = Ogre::StringConverter::parseReal(*itAlpha);
				correctAlpha(nextImage, alpha);
				itAlpha++;
			}

			if (itFrame != mInputFrames.end())
			{
				size_t firstFrame = nextFrame;
				nextFrame = Ogre::StringConverter::parseUnsignedInt(*itFrame);
				itFrame++;
				frameCounter++;

				// Generate and add interpolated images to the atlas image
				size_t numberOfFrames = nextFrame - firstFrame;
				for (size_t i = 1; i < numberOfFrames; ++i)
				{
					Ogre::Real fraction = (Ogre::Real)i / (Ogre::Real)numberOfFrames;
					Ogre::Image interpolatedImage;
					size_t pixelSize = Ogre::PixelUtil::getNumElemBytes(firstImage.getFormat());
					size_t bufferSize = firstImage.getWidth() * firstImage.getHeight() * pixelSize;
					Ogre::uchar* data = OGRE_ALLOC_T(Ogre::uchar, bufferSize, Ogre::MEMCATEGORY_GENERAL);
					interpolatedImage.loadDynamicImage(data, firstImage.getWidth(), firstImage.getHeight(), 1, firstImage.getFormat(), true);
					interpolate (interpolatedImage, firstImage, nextImage, fraction);
					mAtlasImage.addImage(&interpolatedImage);
					frameCounter++;
				}
			}
			mAtlasImage.addImage(&nextImage);
			frameCounter++;
			itInputFileName++;
		}
	}

	mAtlasImage._compile();
	mAtlasImage.save(mImagePath + "//" + mOutputImage);
}
Exemple #3
0
void pseudoCycle()
{


        printf("Starting VOF Loops\n");



/*        Copying values to pseudo variables*/

        for (k=0; k<(zNumberOfCells+5); k++)
	 for (j=0; j<(yNumberOfCells+5); j++)
	  for(i=0; i<(xNumberOfCells+5); i++)
	{
	   
                tauAlpha[i][j][k][l-1]  = alpha[i][j][k][l-1];

	}        
        
        nPseudoLoops = 5;
        for(pseudoLoops=0;pseudoLoops<=nPseudoLoops;pseudoLoops++)
        {

/*                Solving in pseudo time */
        
                alphaEqnCoeff();
	
        	alphaEqn();
        	
        
        
                
        /*        Checking convergence        	*/
        
        	pseudoMaxRes = 0;
        	pseudoTotalRes = 0;
                for (j=2;j<=nym;j++)
        	{
        		for (k=2;k<=nzm;k++)
		        {
        			for(i=2;i<=nxm;i++)
        			{
        				ieast  = i + 1;
        	  			iwest  = i - 1;
        	  			jnorth = j + 1;
        	  			jsouth = j - 1;
        	  			ktop   = k + 1;
        	  			kbottom= k - 1;
        	  			
        	  			pseudoRes[i][j][k] = (tauAlpha[i][j][k][l] - tauAlpha[i][j][k][l-1])/dtau; 
        	  			
/*        	  			printf("tauAlpha = %e  %e\n",tauAlpha[i][j][k][l],tauAlpha[i][j][k][l-1]);*/

                                        pseudoTotalRes += fabs(pseudoRes[i][j][k]);
        				if(fabs(pseudoRes[i][j][k])>pseudoMaxRes)	pseudoMaxRes = fabs(pseudoRes[i][j][k]);
        				
        
				        //if(alpha[i][j][k][l]!=1.0&&alpha[i][j][k][l]!=1.0)		printf("alpha[%d][%d][%d] = %e \n",i,j,k,alpha[i][j][k][l]);
        
        /*				if(alphaRes[20][20][2]!=0)	printf(" alphaRes[%d][%d][%d] = %e\n",20,20,2,alphaRes[20][20][2]);*/
        
        	  			
        			}
            		}
            	}
            	
            	
            	
            	pseudoMeanRes = pseudoTotalRes/((double)((nxm-1)*(nym-1)*(nzm-1)));
	        if(pseudoMeanRes==0)		pseudoNormRes = 0;
	        else			        pseudoNormRes = pseudoMaxRes/pseudoMeanRes;
            	
    	
            	if(fabs(pseudoMaxRes)>pseudoTimeAccuracy)		nPseudoLoops = nPseudoLoops + 1;
            	
            	
            	
/*            	Shift in pseudo time*/
            	
            	shiftPseudo();
            	
/*            	printf("pseudoMaxRes = %e \n",pseudoMaxRes);*/
            	
    	}
    	
    	printf("pseudoMaxRes = %e \n",pseudoMaxRes);
    	printf("No of pseudo loops = %d \n",nPseudoLoops);
    	
    	
/*    	Copying back values from pseudo varibales*/
    	
        for (k=0; k<(zNumberOfCells+5); k++)
	 for (j=0; j<(yNumberOfCells+5); j++)
	  for(i=0; i<(xNumberOfCells+5); i++)
	{
	   
                alpha[i][j][k][l]  = tauAlpha[i][j][k][l];

	} 		
	
	
	correctAlpha();
}
kinematicSingleLayer::kinematicSingleLayer
(
    const word& modelType,
    const fvMesh& mesh,
    const dimensionedVector& g,
    const word& regionType,
    const bool readFields
)
:
    surfaceFilmModel(modelType, mesh, g, regionType),

    momentumPredictor_(solution().subDict("PISO").lookup("momentumPredictor")),
    nOuterCorr_(solution().subDict("PISO").lookupOrDefault("nOuterCorr", 1)),
    nCorr_(readLabel(solution().subDict("PISO").lookup("nCorr"))),
    nNonOrthCorr_
    (
        readLabel(solution().subDict("PISO").lookup("nNonOrthCorr"))
    ),

    cumulativeContErr_(0.0),

    deltaSmall_("deltaSmall", dimLength, SMALL),
    deltaCoLimit_(solution().lookupOrDefault("deltaCoLimit", 1e-4)),

    rho_
    (
        IOobject
        (
            "rhof",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimDensity, 0.0),
        zeroGradientFvPatchScalarField::typeName
    ),
    mu_
    (
        IOobject
        (
            "muf",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimPressure*dimTime, 0.0),
        zeroGradientFvPatchScalarField::typeName
    ),
    sigma_
    (
        IOobject
        (
            "sigmaf",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimMass/sqr(dimTime), 0.0),
        zeroGradientFvPatchScalarField::typeName
    ),

    delta_
    (
        IOobject
        (
            "deltaf",
            time().timeName(),
            regionMesh(),
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        regionMesh()
    ),
    alpha_
    (
        IOobject
        (
            "alpha",
            time().timeName(),
            regionMesh(),
            IOobject::READ_IF_PRESENT,
            IOobject::AUTO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimless, 0.0),
        zeroGradientFvPatchScalarField::typeName
    ),
    U_
    (
        IOobject
        (
            "Uf",
            time().timeName(),
            regionMesh(),
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        regionMesh()
    ),
    Us_
    (
        IOobject
        (
            "Usf",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        U_,
        zeroGradientFvPatchScalarField::typeName
    ),
    Uw_
    (
        IOobject
        (
            "Uwf",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        U_,
        zeroGradientFvPatchScalarField::typeName
    ),
    deltaRho_
    (
        IOobject
        (
            delta_.name() + "*" + rho_.name(),
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", delta_.dimensions()*rho_.dimensions(), 0.0),
        zeroGradientFvPatchScalarField::typeName
    ),

    phi_
    (
        IOobject
        (
            "phi",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("0", dimLength*dimMass/dimTime, 0.0)
    ),

    primaryMassTrans_
    (
        IOobject
        (
            "primaryMassTrans",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimMass, 0.0),
        zeroGradientFvPatchScalarField::typeName
    ),
    cloudMassTrans_
    (
        IOobject
        (
            "cloudMassTrans",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimMass, 0.0),
        zeroGradientFvPatchScalarField::typeName
    ),
    cloudDiameterTrans_
    (
        IOobject
        (
            "cloudDiameterTrans",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimLength, -1.0),
        zeroGradientFvPatchScalarField::typeName
    ),

    USp_
    (
        IOobject
        (
            "USpf",
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedVector
        (
            "zero", dimMass*dimVelocity/dimArea/dimTime, Zero
        ),
        this->mappedPushedFieldPatchTypes<vector>()
    ),
    pSp_
    (
        IOobject
        (
            "pSpf",
            time_.timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimPressure, 0.0),
        this->mappedPushedFieldPatchTypes<scalar>()
    ),
    rhoSp_
    (
        IOobject
        (
            "rhoSpf",
            time_.timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimMass/dimTime/dimArea, 0.0),
        this->mappedPushedFieldPatchTypes<scalar>()
    ),

    USpPrimary_
    (
        IOobject
        (
            USp_.name(), // must have same name as USp_ to enable mapping
            time().timeName(),
            primaryMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        primaryMesh(),
        dimensionedVector("zero", USp_.dimensions(), Zero)
    ),
    pSpPrimary_
    (
        IOobject
        (
            pSp_.name(), // must have same name as pSp_ to enable mapping
            time().timeName(),
            primaryMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        primaryMesh(),
        dimensionedScalar("zero", pSp_.dimensions(), 0.0)
    ),
    rhoSpPrimary_
    (
        IOobject
        (
            rhoSp_.name(), // must have same name as rhoSp_ to enable mapping
            time().timeName(),
            primaryMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        primaryMesh(),
        dimensionedScalar("zero", rhoSp_.dimensions(), 0.0)
    ),

    UPrimary_
    (
        IOobject
        (
            "U", // must have same name as U to enable mapping
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedVector("zero", dimVelocity, Zero),
        this->mappedFieldAndInternalPatchTypes<vector>()
    ),
    pPrimary_
    (
        IOobject
        (
            "p", // must have same name as p to enable mapping
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimPressure, 0.0),
        this->mappedFieldAndInternalPatchTypes<scalar>()
    ),
    rhoPrimary_
    (
        IOobject
        (
            "rho", // must have same name as rho to enable mapping
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimDensity, 0.0),
        this->mappedFieldAndInternalPatchTypes<scalar>()
    ),
    muPrimary_
    (
        IOobject
        (
            "thermo:mu", // must have same name as mu to enable mapping
            time().timeName(),
            regionMesh(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        regionMesh(),
        dimensionedScalar("zero", dimPressure*dimTime, 0.0),
        this->mappedFieldAndInternalPatchTypes<scalar>()
    ),

    filmThermo_(filmThermoModel::New(*this, coeffs_)),

    availableMass_(regionMesh().nCells(), 0.0),

    injection_(*this, coeffs_),

    transfer_(*this, coeffs_),

    turbulence_(filmTurbulenceModel::New(*this, coeffs_)),

    forces_(*this, coeffs_),

    addedMassTotal_(0.0)
{
    if (readFields)
    {
        transferPrimaryRegionThermoFields();

        correctAlpha();

        correctThermoFields();

        deltaRho_ == delta_*rho_;

        surfaceScalarField phi0
        (
            IOobject
            (
                "phi",
                time().timeName(),
                regionMesh(),
                IOobject::READ_IF_PRESENT,
                IOobject::AUTO_WRITE,
                false
            ),
            fvc::flux(deltaRho_*U_)
        );

        phi_ == phi0;
    }
}
Exemple #5
0
void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc,
	scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings)
{
	// minimap pixel color - the average color of a texture
	if (tsettings.enable_minimap && !tiledef[0].name.empty())
		minimap_color = tsrc->getTextureAverageColor(tiledef[0].name);

	// Figure out the actual tiles to use
	TileDef tdef[6];
	for (u32 j = 0; j < 6; j++) {
		tdef[j] = tiledef[j];
		if (tdef[j].name.empty())
			tdef[j].name = "unknown_node.png";
	}
	// also the overlay tiles
	TileDef tdef_overlay[6];
	for (u32 j = 0; j < 6; j++)
		tdef_overlay[j] = tiledef_overlay[j];
	// also the special tiles
	TileDef tdef_spec[6];
	for (u32 j = 0; j < CF_SPECIAL_COUNT; j++)
		tdef_spec[j] = tiledef_special[j];

	bool is_liquid = false;

	u8 material_type = (alpha == 255) ?
		TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;

	switch (drawtype) {
	default:
	case NDT_NORMAL:
		material_type = (alpha == 255) ?
			TILE_MATERIAL_OPAQUE : TILE_MATERIAL_ALPHA;
		solidness = 2;
		break;
	case NDT_AIRLIKE:
		solidness = 0;
		break;
	case NDT_LIQUID:
		assert(liquid_type == LIQUID_SOURCE);
		if (tsettings.opaque_water)
			alpha = 255;
		solidness = 1;
		is_liquid = true;
		break;
	case NDT_FLOWINGLIQUID:
		assert(liquid_type == LIQUID_FLOWING);
		solidness = 0;
		if (tsettings.opaque_water)
			alpha = 255;
		is_liquid = true;
		break;
	case NDT_GLASSLIKE:
		solidness = 0;
		visual_solidness = 1;
		break;
	case NDT_GLASSLIKE_FRAMED:
		solidness = 0;
		visual_solidness = 1;
		break;
	case NDT_GLASSLIKE_FRAMED_OPTIONAL:
		solidness = 0;
		visual_solidness = 1;
		drawtype = tsettings.connected_glass ? NDT_GLASSLIKE_FRAMED : NDT_GLASSLIKE;
		break;
	case NDT_ALLFACES:
		solidness = 0;
		visual_solidness = 1;
		break;
	case NDT_ALLFACES_OPTIONAL:
		if (tsettings.leaves_style == LEAVES_FANCY) {
			drawtype = NDT_ALLFACES;
			solidness = 0;
			visual_solidness = 1;
		} else if (tsettings.leaves_style == LEAVES_SIMPLE) {
			for (u32 j = 0; j < 6; j++) {
				if (!tdef_spec[j].name.empty())
					tdef[j].name = tdef_spec[j].name;
			}
			drawtype = NDT_GLASSLIKE;
			solidness = 0;
			visual_solidness = 1;
		} else {
			drawtype = NDT_NORMAL;
			solidness = 2;
			for (TileDef &td : tdef)
				td.name += std::string("^[noalpha");
		}
		if (waving >= 1)
			material_type = TILE_MATERIAL_WAVING_LEAVES;
		break;
	case NDT_PLANTLIKE:
		solidness = 0;
		if (waving >= 1)
			material_type = TILE_MATERIAL_WAVING_PLANTS;
		break;
	case NDT_FIRELIKE:
		solidness = 0;
		break;
	case NDT_MESH:
	case NDT_NODEBOX:
		solidness = 0;
		if (waving == 1)
			material_type = TILE_MATERIAL_WAVING_PLANTS;
		else if (waving == 2)
			material_type = TILE_MATERIAL_WAVING_LEAVES;
		break;
	case NDT_TORCHLIKE:
	case NDT_SIGNLIKE:
	case NDT_FENCELIKE:
	case NDT_RAILLIKE:
		solidness = 0;
		break;
	case NDT_PLANTLIKE_ROOTED:
		solidness = 2;
		break;
	}

	if (is_liquid) {
		// Vertex alpha is no longer supported, correct if necessary.
		correctAlpha(tdef, 6);
		correctAlpha(tdef_overlay, 6);
		correctAlpha(tdef_spec, CF_SPECIAL_COUNT);
		material_type = (alpha == 255) ?
			TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT;
	}

	u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype);

	u8 overlay_material = material_type;
	if (overlay_material == TILE_MATERIAL_OPAQUE)
		overlay_material = TILE_MATERIAL_BASIC;
	else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE)
		overlay_material = TILE_MATERIAL_LIQUID_TRANSPARENT;

	u32 overlay_shader = shdsrc->getShader("nodes_shader", overlay_material, drawtype);

	// Tiles (fill in f->tiles[])
	for (u16 j = 0; j < 6; j++) {
		tiles[j].world_aligned = isWorldAligned(tdef[j].align_style,
				tsettings.world_aligned_mode, drawtype);
		fillTileAttribs(tsrc, &tiles[j].layers[0], tiles[j], tdef[j],
				color, material_type, tile_shader,
				tdef[j].backface_culling, tsettings);
		if (!tdef_overlay[j].name.empty())
			fillTileAttribs(tsrc, &tiles[j].layers[1], tiles[j], tdef_overlay[j],
					color, overlay_material, overlay_shader,
					tdef[j].backface_culling, tsettings);
	}

	u8 special_material = material_type;
	if (drawtype == NDT_PLANTLIKE_ROOTED) {
		if (waving == 1)
			special_material = TILE_MATERIAL_WAVING_PLANTS;
		else if (waving == 2)
			special_material = TILE_MATERIAL_WAVING_LEAVES;
	}
	u32 special_shader = shdsrc->getShader("nodes_shader", special_material, drawtype);

	// Special tiles (fill in f->special_tiles[])
	for (u16 j = 0; j < CF_SPECIAL_COUNT; j++)
		fillTileAttribs(tsrc, &special_tiles[j].layers[0], special_tiles[j], tdef_spec[j],
				color, special_material, special_shader,
				tdef_spec[j].backface_culling, tsettings);

	if (param_type_2 == CPT2_COLOR ||
			param_type_2 == CPT2_COLORED_FACEDIR ||
			param_type_2 == CPT2_COLORED_WALLMOUNTED)
		palette = tsrc->getPalette(palette_name);

	if (drawtype == NDT_MESH && !mesh.empty()) {
		// Meshnode drawtype
		// Read the mesh and apply scale
		mesh_ptr[0] = client->getMesh(mesh);
		if (mesh_ptr[0]){
			v3f scale = v3f(1.0, 1.0, 1.0) * BS * visual_scale;
			scaleMesh(mesh_ptr[0], scale);
			recalculateBoundingBox(mesh_ptr[0]);
			meshmanip->recalculateNormals(mesh_ptr[0], true, false);
		}
	}

	//Cache 6dfacedir and wallmounted rotated clones of meshes
	if (tsettings.enable_mesh_cache && mesh_ptr[0] &&
			(param_type_2 == CPT2_FACEDIR
			|| param_type_2 == CPT2_COLORED_FACEDIR)) {
		for (u16 j = 1; j < 24; j++) {
			mesh_ptr[j] = cloneMesh(mesh_ptr[0]);
			rotateMeshBy6dFacedir(mesh_ptr[j], j);
			recalculateBoundingBox(mesh_ptr[j]);
			meshmanip->recalculateNormals(mesh_ptr[j], true, false);
		}
	} else if (tsettings.enable_mesh_cache && mesh_ptr[0]
			&& (param_type_2 == CPT2_WALLMOUNTED ||
			param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
		static const u8 wm_to_6d[6] = { 20, 0, 16 + 1, 12 + 3, 8, 4 + 2 };
		for (u16 j = 1; j < 6; j++) {
			mesh_ptr[j] = cloneMesh(mesh_ptr[0]);
			rotateMeshBy6dFacedir(mesh_ptr[j], wm_to_6d[j]);
			recalculateBoundingBox(mesh_ptr[j]);
			meshmanip->recalculateNormals(mesh_ptr[j], true, false);
		}
		rotateMeshBy6dFacedir(mesh_ptr[0], wm_to_6d[0]);
		recalculateBoundingBox(mesh_ptr[0]);
		meshmanip->recalculateNormals(mesh_ptr[0], true, false);
	}
}