tmp<GeomField>
coupledInfo<MeshType>::subSetField
(
    const GeomField& f,
    const ZeroType& zeroValue,
    const labelList& internalMapper
) const
{
    typedef typename GeomField::InternalField InternalField;
    typedef typename GeomField::PatchFieldType PatchFieldType;
    typedef typename GeomField::GeometricBoundaryField GeomBdyFieldType;
    typedef typename GeomField::DimensionedInternalField DimInternalField;

    // Create and map the internal-field values
    InternalField internalField(f.internalField(), internalMapper);

    // Create and map the patch field values
    label nPatches = subMesh().boundary().size();
    PtrList<PatchFieldType> patchFields(nPatches);

    // Define patch type names, assumed to be
    // common for volume and surface fields
    word emptyType(emptyPolyPatch::typeName);
    word processorType(processorPolyPatch::typeName);

    // Create dummy types for initial field creation
    forAll(patchFields, patchI)
    {
        if (patchI == (nPatches - 1))
        {
            // Artificially set last patch
            patchFields.set
            (
                patchI,
                PatchFieldType::New
                (
                    emptyType,
                    subMesh().boundary()[patchI],
                    DimInternalField::null()
                )
            );
        }
        else
        {
            patchFields.set
            (
                patchI,
                PatchFieldType::New
                (
                    PatchFieldType::calculatedType(),
                    subMesh().boundary()[patchI],
                    DimInternalField::null()
                )
            );
        }
    }

    // Create new field from pieces
    tmp<GeomField> subFld
    (
        new GeomField
        (
            IOobject
            (
                "subField_" + f.name(),
                subMesh().time().timeName(),
                subMesh(),
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            subMesh(),
            f.dimensions(),
            internalField,
            patchFields
        )
    );

    // Set correct references for patch internal fields,
    // and map values from the supplied geometric field
    GeomBdyFieldType& bf = subFld().boundaryField();

    forAll(bf, patchI)
    {
        if (patchI == (nPatches - 1))
        {
            // Artificially set last patch
            bf.set
            (
                patchI,
                PatchFieldType::New
                (
                    emptyType,
                    subMesh().boundary()[patchI],
                    subFld().dimensionedInternalField()
                )
            );
        }
        else
        if (isA<processorPolyPatch>(subMesh().boundary()[patchI].patch()))
        {
            bf.set
            (
                patchI,
                PatchFieldType::New
                (
                    processorType,
                    subMesh().boundary()[patchI],
                    subFld().dimensionedInternalField()
                )
            );

            // Avoid dealing with uninitialised values
            // by artificially assigning to zero
            bf[patchI] == zeroValue;
        }
        else
        {
            bf.set
            (
                patchI,
                PatchFieldType::New
                (
                    f.boundaryField()[patchI],
                    subMesh().boundary()[patchI],
                    subFld().dimensionedInternalField(),
                    subMeshMapper(*this, patchI)
                )
            );
        }
    }

    return subFld;
}
void coupledInfo<MeshType>::setField
(
    const wordList& fieldNames,
    const dictionary& fieldDicts,
    const label internalSize,
    PtrList<GeomField>& fields
) const
{
    typedef typename GeomField::InternalField InternalField;
    typedef typename GeomField::PatchFieldType PatchFieldType;
    typedef typename GeomField::GeometricBoundaryField GeomBdyFieldType;
    typedef typename GeomField::DimensionedInternalField DimInternalField;

    // Size up the pointer list
    fields.setSize(fieldNames.size());

    // Define patch type names, assumed to be
    // common for volume and surface fields
    word emptyType(emptyPolyPatch::typeName);
    word processorType(processorPolyPatch::typeName);

    forAll(fieldNames, i)
    {
        // Create and map the patch field values
        label nPatches = subMesh().boundary().size();

        // Create field parts
        PtrList<PatchFieldType> patchFields(nPatches);

        // Read dimensions
        dimensionSet dimSet
        (
            fieldDicts.subDict(fieldNames[i]).lookup("dimensions")
        );

        // Read the internal field
        InternalField internalField
        (
            "internalField",
            fieldDicts.subDict(fieldNames[i]),
            internalSize
        );

        // Create dummy types for initial field creation
        forAll(patchFields, patchI)
        {
            if (patchI == (nPatches - 1))
            {
                // Artificially set last patch
                patchFields.set
                (
                    patchI,
                    PatchFieldType::New
                    (
                        emptyType,
                        subMesh().boundary()[patchI],
                        DimInternalField::null()
                    )
                );
            }
            else
            {
                patchFields.set
                (
                    patchI,
                    PatchFieldType::New
                    (
                        PatchFieldType::calculatedType(),
                        subMesh().boundary()[patchI],
                        DimInternalField::null()
                    )
                );
            }
        }

        // Create field with dummy patches
        fields.set
        (
            i,
            new GeomField
            (
                IOobject
                (
                    fieldNames[i],
                    subMesh().time().timeName(),
                    subMesh(),
                    IOobject::NO_READ,
                    IOobject::NO_WRITE,
                    false
                ),
                subMesh(),
                dimSet,
                internalField,
                patchFields
            )
        );

        // Set correct references for patch internal fields,
        // and fetch values from the supplied geometric field dictionaries
        GeomBdyFieldType& bf = fields[i].boundaryField();

        forAll(bf, patchI)
        {
            if (patchI == (nPatches - 1))
            {
                // Artificially set last patch
                bf.set
                (
                    patchI,
                    PatchFieldType::New
                    (
                        emptyType,
                        subMesh().boundary()[patchI],
                        fields[i].dimensionedInternalField()
                    )
                );
            }
            else
            if (isA<processorPolyPatch>(subMesh().boundary()[patchI].patch()))
            {
                bf.set
                (
                    patchI,
                    PatchFieldType::New
                    (
                        processorType,
                        subMesh().boundary()[patchI],
                        fields[i].dimensionedInternalField()
                    )
                );
            }
            else
            {
                bf.set
                (
                    patchI,
                    PatchFieldType::New
                    (
                        subMesh().boundary()[patchI],
                        fields[i].dimensionedInternalField(),
                        fieldDicts.subDict
                        (
                            fieldNames[i]
                        ).subDict("boundaryField").subDict
                        (
                            subMesh().boundary()[patchI].name()
                        )
                    )
                );
            }
        }
    }
Exemple #3
0
NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params)
{
	#if NAZARA_UTILITY_SAFE
	if (!m_impl)
	{
		NazaraError("Mesh not created");
		return nullptr;
	}

	if (m_impl->animationType != nzAnimationType_Static)
	{
		NazaraError("Mesh must be static");
		return nullptr;
	}

	if (!params.IsValid())
	{
		NazaraError("Parameters must be valid");
		return nullptr;
	}
	#endif

	NzBoxf aabb;
	std::unique_ptr<NzIndexBuffer> indexBuffer;
	std::unique_ptr<NzVertexBuffer> vertexBuffer;

	NzMatrix4f matrix(primitive.matrix);
	matrix.ApplyScale(params.scale);

	NzVertexDeclaration* declaration = NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent);

	switch (primitive.type)
	{
		case nzPrimitiveType_Box:
		{
			unsigned int indexCount;
			unsigned int vertexCount;
			NzComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount);

			indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
			indexBuffer->SetPersistent(false);

			vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
			vertexBuffer->SetPersistent(false);

			NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
			NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

			NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
			break;
		}

		case nzPrimitiveType_Cone:
		{
			unsigned int indexCount;
			unsigned int vertexCount;
			NzComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount);

			indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
			indexBuffer->SetPersistent(false);

			vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
			vertexBuffer->SetPersistent(false);

			NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
			NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

			NzGenerateCone(primitive.cone.length, primitive.cone.radius, primitive.cone.subdivision, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
			break;
		}

		case nzPrimitiveType_Plane:
		{
			unsigned int indexCount;
			unsigned int vertexCount;
			NzComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount);

			indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
			indexBuffer->SetPersistent(false);

			vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
			vertexBuffer->SetPersistent(false);

			NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
			NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

			NzGeneratePlane(primitive.plane.subdivision, primitive.plane.size, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
			break;
		}

		case nzPrimitiveType_Sphere:
		{
			switch (primitive.sphere.type)
			{
				case nzSphereType_Cubic:
				{
					unsigned int indexCount;
					unsigned int vertexCount;
					NzComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount);

					indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
					indexBuffer->SetPersistent(false);

					vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
					vertexBuffer->SetPersistent(false);

					NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
					NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

					NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
					break;
				}

				case nzSphereType_Ico:
				{
					unsigned int indexCount;
					unsigned int vertexCount;
					NzComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount);

					indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
					indexBuffer->SetPersistent(false);

					vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
					vertexBuffer->SetPersistent(false);

					NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
					NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

					NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
					break;
				}

				case nzSphereType_UV:
				{
					unsigned int indexCount;
					unsigned int vertexCount;
					NzComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount);

					indexBuffer.reset(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indexCount, params.storage, nzBufferUsage_Static));
					indexBuffer->SetPersistent(false);

					vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
					vertexBuffer->SetPersistent(false);

					NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
					NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_WriteOnly);

					NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, matrix, primitive.textureCoords, static_cast<NzMeshVertex*>(vertexMapper.GetPointer()), indexMapper.begin(), &aabb);
					break;
				}
			}
			break;
		}
	}

	std::unique_ptr<NzStaticMesh> subMesh(new NzStaticMesh(this));
	if (!subMesh->Create(vertexBuffer.get()))
	{
		NazaraError("Failed to create StaticMesh");
		return nullptr;
	}
	vertexBuffer.release();

	if (params.optimizeIndexBuffers)
		indexBuffer->Optimize();

	subMesh->SetIndexBuffer(indexBuffer.get());
	indexBuffer.release();

	subMesh->SetAABB(aabb);
	AddSubMesh(subMesh.get());

	return subMesh.release();
}