コード例 #1
0
std::string Pothos::Topology::dumpJSON(const std::string &request)
{
    //extract input request
    Poco::JSON::Parser p; p.parse(request.empty()?"{}":request);
    auto configObj = p.getHandler()->asVar().extract<Poco::JSON::Object::Ptr>();
    assert(configObj);
    const auto modeConfig = configObj->optValue<std::string>("mode", "flat");

    //parse request into traversal arguments
    const bool flatten = (modeConfig == "flat");
    const bool traverse = (modeConfig != "rendered");
    const auto &flows = (modeConfig == "rendered")?_impl->activeFlatFlows:_impl->flows;

    //replace rendered names with names from flattened hierarchy
    Poco::JSON::Object::Ptr flatBlocks;
    if (modeConfig == "rendered")
    {
        Poco::JSON::Parser pFlat; pFlat.parse(this->dumpJSON("{\"mode\":\"flat\"}"));
        auto flatObj = pFlat.getHandler()->asVar().extract<Poco::JSON::Object::Ptr>();
        assert(flatObj);
        flatBlocks = flatObj->getObject("blocks");
        assert(flatBlocks);
    }

    //output object
    Poco::JSON::Object::Ptr topObj(new Poco::JSON::Object());

    //create blocks map
    Poco::JSON::Object::Ptr blocksObj(new Poco::JSON::Object());
    topObj->set("blocks", blocksObj);
    for (const auto &block : getObjSetFromFlowList(flows))
    {
        //gather block info
        Poco::JSON::Object::Ptr blockObj(new Poco::JSON::Object());
        const auto blockId = block.call<std::string>("uid");
        blocksObj->set(blockId, blockObj);

        //replace rendered names with names from flattened hierarchy
        blockObj->set("name", block.call<std::string>("getName"));
        if (flatBlocks and flatBlocks->has(blockId))
        {
            blockObj->set("name", flatBlocks->getObject(blockId)->getValue<std::string>("name"));
        }

        //input port info
        Poco::JSON::Array::Ptr inputsArray(new Poco::JSON::Array());
        for (const auto &portInfo : block.call<std::vector<PortInfo>>("inputPortInfo"))
        {
            inputsArray->add(portInfoToObj(portInfo));
        }
        if (inputsArray->size() > 0) blockObj->set("inputs", inputsArray);

        //output port info
        Poco::JSON::Array::Ptr outputsArray(new Poco::JSON::Array());
        for (const auto &portInfo : block.call<std::vector<PortInfo>>("outputPortInfo"))
        {
            outputsArray->add(portInfoToObj(portInfo));
        }
        if (outputsArray->size() > 0) blockObj->set("outputs", outputsArray);

        //sub-topology info
        if (traverse and this->uid() != blockId) try
        {
            auto subDump = block.call<std::string>("dumpJSON", "{\"mode\":\"top\"}");
            Poco::JSON::Parser psub; psub.parse(subDump);
            auto subObj = psub.getHandler()->asVar().extract<Poco::JSON::Object::Ptr>();
            assert(subObj);
            std::vector<std::string> names; subObj->getNames(names);
            for (const auto &name : names) blockObj->set(name, subObj->get(name));
        }
        catch (const Pothos::Exception &){}
    }

    //create connections list
    Poco::JSON::Array::Ptr connsArray(new Poco::JSON::Array());
    topObj->set("connections", connsArray);
    for (const auto &flow : flows)
    {
        Poco::JSON::Object::Ptr connObj(new Poco::JSON::Object());
        connsArray->add(connObj);
        connObj->set("srcId", flow.src.uid);
        connObj->set("srcName", flow.src.name);
        connObj->set("dstId", flow.dst.uid);
        connObj->set("dstName", flow.dst.name);
    }

    //recursive flatten when instructed
    while (flatten and flattenDump(topObj));

    //return the string-formatted result
    std::stringstream ss; topObj->stringify(ss, 4);
    return ss.str();
}
コード例 #2
0
ファイル: Emitter.cpp プロジェクト: applejuicejen/FluidSim
void Emitter::Initialize(float _num_particles,  ngl::Vec3 _initial_pos, float _range, ngl::Vec3 _initial_vel, float _lifespan, float _mass)
{
  //int boundary_particles = 10;
//  float count = 0.6f/2;
//  float half_size = 20.0f/2.0f;

//  for(float i = -half_size; i <= half_size; i +=count)
//  {
//    for(float j = -half_size; j <= half_size; j +=count)
//    {

//      Particle p(true);
//      p.setGhost(true);
//      p.setColour(ngl::Vec3(1,0,0));
//      p.setPosition(ngl::Vec3(i, j, half_size));
//      p.setInitPosition(ngl::Vec3(i, j, half_size));
//      p.setLifespan(_lifespan);
//      p.setMass(_mass);
//      p.setVelocity(_initial_vel);
//      p.setInitVelocity(_initial_vel);
//      m_particles.push_back(p);
//    }
//  }
  //std::cout<<"num ghost particles: "<< m_particles.size()<<std::endl;

  for(int i = 0; i < _num_particles; i++)
  {
     ngl::Real theta_rand = 0 + static_cast <float>(rand())/static_cast<float> (RAND_MAX/(M_PI*2));
     ngl::Real y_theta_rand = 0 + static_cast <float>(rand())/static_cast<float> (RAND_MAX/(M_PI*2));

     float x_radius_rand =  _range + static_cast <float>(rand())/static_cast<float> (RAND_MAX/(_range/2));
     float y_radius_rand =  static_cast <float>(rand())/static_cast<float> (RAND_MAX/(_range*1.2));
     float z_radius_rand =  -(_range+2) + static_cast <float>(rand())/static_cast<float> (RAND_MAX/((_range+2)*2));


     ngl::Real x = ((float)cos(theta_rand))*x_radius_rand;
     ngl::Real z = ((float)sin(theta_rand))*x_radius_rand;
     ngl::Real y = ((float)cos(y_theta_rand))*x_radius_rand;
     ngl::Vec3 init_pos = ngl::Vec3(_initial_pos.m_x + x_radius_rand, _initial_pos.m_y+y_radius_rand, _initial_pos.m_z + z_radius_rand);

    Particle p(true);
    p.setGhost(false);
    p.setPosition(init_pos);
    p.setPrevPosition(init_pos);
    p.setInitPosition(init_pos);
    p.setLifespan(_lifespan);
    p.setMass(_mass);
    p.setVelocity(_initial_vel);
    p.setInitVelocity(_initial_vel);
    m_particles.push_back(p);
  }
  //std::cout<<"num of particles: "<< m_particles.size()<<std::endl;
  m_last_emission = m_current_time;


  m_archive.reset(new AbcG::OArchive(Alembic::AbcCoreOgawa::WriteArchive(), "particlesOut.abc"));

  AbcG::TimeSampling ts(1.0f/24.0f, 0.0f);
  AbcG::OObject topObj(*m_archive.get(), AbcG::kTop);
  Alembic::Util::uint32_t tsidx = topObj.getArchive().addTimeSampling(ts);
  m_partsOut.reset(new AbcG::OPoints(topObj, "FluidSim", tsidx));
  m_rgbOut.reset(new AbcG::OC4fArrayProperty(m_partsOut->getSchema(), ".colour", false, AbcG::kVertexScope, tsidx));
}
コード例 #3
0
/***********************************************************************
 * Parse a single documentation block for markup
 **********************************************************************/
static Poco::JSON::Object::Ptr parseCommentBlockForMarkup(const CodeBlock &commentBlock)
{
    Poco::JSON::Object::Ptr topObj(new Poco::JSON::Object());
    Poco::JSON::Array calls;
    Poco::JSON::Array keywords;
    Poco::JSON::Array::Ptr aliases(new Poco::JSON::Array());
    Poco::JSON::Array categories;
    Poco::JSON::Array params;
    Poco::JSON::Array::Ptr topDocs(new Poco::JSON::Array());
    Poco::JSON::Object::Ptr currentParam;

    std::string state;
    std::string indent;

    std::string instruction;
    std::string payload;

    //search for the markup begin tag and record the indent
    for (const auto &codeLine : commentBlock)
    {
        std::string line = codeLine.text;
        Poco::RegularExpression::MatchVec matches;

        if (not state.empty())
        {
            if (line.size() >= indent.size() and line.substr(0, indent.size()) != indent)
            {
                if (codeLine.lineNo == commentBlock.back().lineNo) line = "";
                else throw Pothos::SyntaxException("Inconsistent indentation", codeLine.toString());
            }

            if (line.size() >= indent.size()) line = line.substr(indent.size());
            else line = "";

            Poco::RegularExpression("^\\|(\\w+)\\s+(.*)$").match(line, 0, matches);
            if (not matches.empty())
            {
                assert(matches.size() == 3);
                instruction = line.substr(matches[1].offset, matches[1].length);
                payload = line.substr(matches[2].offset, matches[2].length);
            }
        }

        if (state.empty())
        {
            Poco::RegularExpression("^(.*)\\|PothosDoc\\s+(.*)$").match(line, 0, matches);
            if (matches.empty()) continue;
            assert(matches.size() == 3);
            indent = line.substr(matches[1].offset, matches[1].length);
            topObj->set("name", Poco::trim(line.substr(matches[2].offset, matches[2].length)));
            state = "DOC";
        }
        else if (matches.empty() and state == "DOC")
        {
            topDocs->add(line);
        }
        else if (matches.empty() and state == "PARAM")
        {
            auto array = currentParam->getArray("desc");
            array->add(line);
            currentParam->set("desc", stripDocArray(array));
        }
        else if (instruction == "category" and state == "DOC")
        {
            categories.add(Poco::trim(payload));
        }
        else if (instruction == "keywords" and state == "DOC")
        {
            for (const auto &keyword : Poco::StringTokenizer(
                payload, " \t", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY))
            {
                keywords.add(Poco::trim(keyword));
            }
        }
        else if (instruction == "alias" and state == "DOC")
        {
            const std::string alias(Poco::trim(payload));
            try {Pothos::PluginPath(alias);}
            catch (const Pothos::PluginPathError &)
            {
                throw Pothos::SyntaxException("Invalid alias path", codeLine.toString());
            }
            aliases->add(alias);
        }
        else if (instruction == "param" and (state == "DOC" or state == "PARAM"))
        {
            payload = bracketEscapeEncode(payload);
            Poco::RegularExpression::MatchVec fields;
            Poco::RegularExpression("^\\s*(\\w+)(\\s*\\[(.*)\\]\\s*)?(.*)$").match(payload, 0, fields);
            if (fields.empty()) throw Pothos::SyntaxException(
                "Expected |param key[name] description",
                codeLine.toString());

            assert(fields.size() == 5);
            const std::string key = bracketEscapeDecode(Poco::trim(payload.substr(fields[1].offset, fields[1].length)));
            std::string name = titleCase(key);
            if (fields[3].length != 0) name = bracketEscapeDecode(Poco::trim(payload.substr(fields[3].offset, fields[3].length)));
            const std::string desc = bracketEscapeDecode(Poco::trim(payload.substr(fields[4].offset, fields[4].length)));

            currentParam = Poco::JSON::Object::Ptr(new Poco::JSON::Object());
            params.add(currentParam);
            currentParam->set("key", key);
            currentParam->set("name", name);
            Poco::JSON::Array::Ptr descArr(new Poco::JSON::Array());
            descArr->add(desc);
            currentParam->set("desc", descArr);
            state = "PARAM";
        }
        else if (instruction == "default" and state == "PARAM")
        {
            if (currentParam->has("default")) throw Pothos::SyntaxException(
                "Multiple occurrence of |default for param",
                codeLine.toString());
            currentParam->set("default", payload);
        }
        else if (instruction == "units" and state == "PARAM")
        {
            if (currentParam->has("units")) throw Pothos::SyntaxException(
                "Multiple occurrence of |units for param",
                codeLine.toString());
            currentParam->set("units", payload);
        }
        else if (instruction == "widget" and state == "PARAM")
        {
            if (currentParam->has("widgetType")) throw Pothos::SyntaxException(
                "Multiple occurrence of |widget for param",
                codeLine.toString());
            Poco::RegularExpression::MatchVec fields;
            Poco::RegularExpression("^\\s*(\\w+)\\s*\\((.*)\\)$").match(payload, 0, fields);
            if (fields.empty()) throw Pothos::SyntaxException(
                "Expected |widget SpinBox(args...)",
                codeLine.toString());

            assert(fields.size() == 3);
            const std::string widgetType = Poco::trim(payload.substr(fields[1].offset, fields[1].length));
            const std::string argsStr = Poco::trim(payload.substr(fields[2].offset, fields[2].length));

            currentParam->set("widgetType", widgetType);
            loadArgs(codeLine, *currentParam, argsStr, "widgetArgs", "widgetKwargs");
        }
        else if (instruction == "tab" and state == "PARAM")
        {
            if (currentParam->has("tab")) throw Pothos::SyntaxException(
                "Multiple occurrence of |tab for param",
                codeLine.toString());
            currentParam->set("tab", payload);
        }
        else if (instruction == "preview" and state == "PARAM")
        {
            if (currentParam->has("preview")) throw Pothos::SyntaxException(
                "Multiple occurrence of preview for param",
                codeLine.toString());
            Poco::RegularExpression::MatchVec fields;
            Poco::RegularExpression("^\\s*(\\w+)(\\s*\\((.*)\\))?$").match(payload, 0, fields);
            if (fields.empty()) throw Pothos::SyntaxException(
                "Expected |preview previewType(args...)",
                codeLine.toString());

            assert(fields.size() == 2 or fields.size() == 4);
            const std::string previewType = Poco::trim(payload.substr(fields[1].offset, fields[1].length));

            if (previewType != "disable" and
                previewType != "enable" and
                previewType != "valid" and
                previewType != "invalid" and
                previewType != "when"
            ) throw Pothos::SyntaxException(
                "Only supports enable/disable/valid/invalid/when as value for preview option of param",
                codeLine.toString());

            currentParam->set("preview", previewType);
            if (fields.size() == 4)
            {
                const std::string argsStr = Poco::trim(payload.substr(fields[3].offset, fields[3].length));
                loadArgs(codeLine, *currentParam, argsStr, "previewArgs", "previewKwargs");
            }
        }
        else if (instruction == "option" and state == "PARAM")
        {
            payload = bracketEscapeEncode(payload);
            Poco::RegularExpression::MatchVec fields;
            Poco::RegularExpression("^(\\s*\\[(.*)\\]\\s*)?(.*)$").match(payload, 0, fields);
            if (fields.empty()) throw Pothos::SyntaxException(
                "Expected |option [name] value",
                codeLine.toString());

            assert(fields.size() == 4);
            const std::string value = bracketEscapeDecode(Poco::trim(payload.substr(fields[3].offset, fields[3].length)));
            std::string name = titleCase(value);
            if (fields[2].length != 0) name = bracketEscapeDecode(Poco::trim(payload.substr(fields[2].offset, fields[2].length)));

            Poco::JSON::Object option;
            option.set("value", value);
            option.set("name", name);
            if (not currentParam->has("options")) currentParam->set(
                "options", Poco::JSON::Array::Ptr(new Poco::JSON::Array()));
            currentParam->getArray("options")->add(option);
        }
        else if (instruction == "factory" and (state == "DOC" or state == "PARAM"))
        {
            Poco::RegularExpression::MatchVec fields;
            Poco::RegularExpression("^\\s*(/.*)\\s*\\((.*)\\)$").match(payload, 0, fields);
            if (fields.empty()) throw Pothos::SyntaxException(
                "Expected |factory /registry/path(args...)",
                codeLine.toString());

            assert(fields.size() == 3);
            const std::string path = Poco::trim(payload.substr(fields[1].offset, fields[1].length));
            const std::string argsStr = Poco::trim(payload.substr(fields[2].offset, fields[2].length));

            //add the path
            try {Pothos::PluginPath(path);}
            catch (const Pothos::PluginPathError &)
            {
                throw Pothos::SyntaxException("Invalid factory path", codeLine.toString());
            }
            if (topObj->has("path")) throw Pothos::SyntaxException(
                "Multiple occurrence of |factory", codeLine.toString());
            topObj->set("path", path);

            //split and extract args
            loadArgs(codeLine, *topObj, argsStr);

            state = "DOC";
        }
        else if ((instruction == "setter" or instruction == "initializer") and (state == "DOC" or state == "PARAM"))
        {
            Poco::RegularExpression::MatchVec fields;
            Poco::RegularExpression("^\\s*(\\w+)\\s*\\((.*)\\)$").match(payload, 0, fields);
            if (fields.empty()) throw Pothos::SyntaxException(
                "Expected |"+instruction+" setFooBar(args...)",
                codeLine.toString());

            assert(fields.size() == 3);
            const std::string callName = Poco::trim(payload.substr(fields[1].offset, fields[1].length));
            const std::string argsStr = Poco::trim(payload.substr(fields[2].offset, fields[2].length));

            //add to calls
            Poco::JSON::Object call;
            call.set("type", instruction);
            call.set("name", callName);
            loadArgs(codeLine, call, argsStr);
            calls.add(call);

            state = "DOC";
        }
        else if (instruction == "mode" and (state == "DOC" or state == "PARAM"))
        {
            if (topObj->has("mode")) throw Pothos::SyntaxException(
                "Multiple occurrence of |mode",
                codeLine.toString());
            topObj->set("mode", payload);
        }
    }

    //empty state means this was a regular comment block, return null
    if (state.empty()) return Poco::JSON::Object::Ptr();

    topDocs = stripDocArray(topDocs);
    if (topDocs->size() > 0) topObj->set("docs", topDocs);
    if (categories.size() > 0) topObj->set("categories", categories);
    if (keywords.size() > 0) topObj->set("keywords", keywords);
    if (aliases->size() > 0) topObj->set("aliases", aliases);
    if (params.size() > 0) topObj->set("params", params);
    if (calls.size() > 0) topObj->set("calls", calls);

    //sanity check for required stuff
    if (not topObj->has("path"))
    {
        throw Pothos::SyntaxException("missing |factory declaration");
    }

    return topObj;
}
コード例 #4
0
ファイル: alembic.cpp プロジェクト: tsks/mmdbridge
static void export_alembic_xform_by_buffer(AlembicArchive &archive, const RenderedBuffer & renderedBuffer, int renderedBufferIndex)
{
	Alembic::AbcGeom::OObject topObj(*archive.archive, Alembic::AbcGeom::kTop);

	Alembic::AbcGeom::OXform xform;
	if (archive.xform_map.find(renderedBufferIndex) != archive.xform_map.end())
	{
		xform = archive.xform_map[renderedBufferIndex];
	}
	else
	{
		xform = Alembic::AbcGeom::OXform(topObj, "xform_" + umbase::UMStringUtil::number_to_string(renderedBufferIndex), archive.timesampling);
		archive.xform_map[renderedBufferIndex] = xform;
	}
		
	bool isFirstMesh = false;
	Alembic::AbcGeom::OPolyMesh polyMesh;
	if (archive.mesh_map.find(renderedBufferIndex) != archive.mesh_map.end())
	{
		polyMesh = archive.mesh_map[renderedBufferIndex];
	}
	else
	{
		polyMesh = Alembic::AbcGeom::OPolyMesh(xform, "mesh_" + to_string(renderedBufferIndex), archive.timesampling);
		archive.mesh_map[renderedBufferIndex] = polyMesh;
		isFirstMesh = true;

		Alembic::AbcGeom::OPolyMeshSchema &meshSchema = polyMesh.getSchema();
		archive.schema_map[renderedBufferIndex] = meshSchema;
	}

	Alembic::AbcGeom::OPolyMeshSchema &meshSchema = archive.schema_map[renderedBufferIndex];
	meshSchema.setTimeSampling(archive.timesampling);
		
	std::vector<Alembic::Util::int32_t> faceList;
	std::vector<Alembic::Util::int32_t> faceCountList;
		
	const RenderedBuffer::UVList &uvList = renderedBuffer.uvs;
	const RenderedBuffer::VertexList &vertexList = renderedBuffer.vertecies;
	const RenderedBuffer::NormalList &normalList =  renderedBuffer.normals;
	RenderedBuffer::UVList& temporary_uv = archive.temporary_uv_list;
	temporary_uv.resize(uvList.size());
	RenderedBuffer::NormalList& temporary_normal = archive.temporary_normal_list;
	temporary_normal.resize(normalList.size());
	RenderedBuffer::VertexList& temporary_vertex = archive.temporary_vertex_list;
	temporary_vertex.resize(vertexList.size());

	const int materialSize = static_cast<int>(renderedBuffer.materials.size());

	int totalFaceCount = 0;
	for (int k = 0; k < materialSize; ++k)
	{
		RenderedMaterial* material = renderedBuffer.materials.at(k);
		totalFaceCount += material->surface.faces.size();
	}
		
	if (archive.surface_size_map.find(renderedBufferIndex) == archive.surface_size_map.end())
	{
		archive.surface_size_map[renderedBufferIndex] = 0;
	}
	int& preSurfaceSize = archive.surface_size_map[renderedBufferIndex];
	bool isFirstSurface = totalFaceCount != preSurfaceSize;
	if (!isFirstMesh && isFirstSurface)
	{
		return;
	}
	preSurfaceSize = totalFaceCount;

	faceCountList.resize(totalFaceCount);
	faceList.resize(totalFaceCount * 3);

	int faceCounter = 0;
	for (int k = 0; k < materialSize; ++k)
	{
		RenderedMaterial* material = renderedBuffer.materials.at(k);
		const int faceSize = material->surface.faces.size();
		for (int n = 0; n < faceSize; ++n)
		{
			UMVec3i face = material->surface.faces[n];
			faceList[faceCounter * 3 + 0] = (face.x - 1);
			faceList[faceCounter * 3 + 1] = (face.y - 1);
			faceList[faceCounter * 3 + 2] = (face.z - 1);
			faceCountList[faceCounter] = 3;
			++faceCounter;
		}
	}

	Alembic::AbcGeom::OPolyMeshSchema::Sample sample;
				
	// vertex
	for (int n = 0, nsize = vertexList.size(); n < nsize; ++n)
	{
		temporary_vertex[n].z = -vertexList[n].z;
	}
	Alembic::AbcGeom::P3fArraySample positions( (const Imath::V3f *) &temporary_vertex.front(), temporary_vertex.size());
	sample.setPositions(positions);
				
	// face index
	if (isFirstMesh)
	{
		Alembic::Abc::Int32ArraySample faceIndices(faceList);
		Alembic::Abc::Int32ArraySample faceCounts(faceCountList);
		sample.setFaceIndices(faceIndices);
		sample.setFaceCounts(faceCounts);
	}

	// UVs
	if (!uvList.empty() && archive.is_export_uvs)
	{
		for (int n = 0, nsize = uvList.size(); n < nsize; ++n)
		{
			temporary_uv[n].y = 1.0f - uvList[n].y;
		}
		Alembic::AbcGeom::OV2fGeomParam::Sample uvSample;
		uvSample.setScope(Alembic::AbcGeom::kVertexScope );
		uvSample.setVals(Alembic::AbcGeom::V2fArraySample( ( const Imath::V2f *) &temporary_uv.front(), temporary_uv.size()));
		sample.setUVs(uvSample);
	}

	// Normals
	if (!normalList.empty() && archive.is_export_normals)
	{
		for (int n = 0, nsize = normalList.size(); n < nsize; ++n)
		{
			temporary_normal[n].z = -normalList[n].z;
		}
		Alembic::AbcGeom::ON3fGeomParam::Sample normalSample;
		normalSample.setScope(Alembic::AbcGeom::kVertexScope );
		normalSample.setVals(Alembic::AbcGeom::N3fArraySample( (const Alembic::AbcGeom::N3f *) &temporary_normal.front(), temporary_normal.size()));
		sample.setNormals(normalSample);
	}

	meshSchema.set(sample);

}
コード例 #5
0
ファイル: alembic.cpp プロジェクト: tsks/mmdbridge
static void export_alembic_xform_by_material_direct(AlembicArchive &archive, const RenderedBuffer & renderedBuffer, int renderedBufferIndex)
{
	Alembic::AbcGeom::OObject topObj(*archive.archive, Alembic::AbcGeom::kTop);

	for (int k = 0, ksize = static_cast<int>(renderedBuffer.materials.size()); k < ksize; ++k)
	{
		Alembic::AbcGeom::OPolyMesh polyMesh;
		const int key = renderedBufferIndex * 10000 + k;
				
		Alembic::AbcGeom::OXform xform;
		if (archive.xform_map.find(key) != archive.xform_map.end())
		{
			xform = archive.xform_map[key];
		}
		else
		{
			xform = Alembic::AbcGeom::OXform(topObj, "xform_" + to_string(renderedBufferIndex) + "_material_" + to_string(k) , archive.timesampling);
			archive.xform_map[key] = xform;
		}

		bool isFirstMesh = false;
		if (archive.mesh_map.find(key) != archive.mesh_map.end())
		{
			polyMesh = archive.mesh_map[key];
		}
		else
		{
			polyMesh = Alembic::AbcGeom::OPolyMesh(xform, "mesh_" + to_string(renderedBufferIndex) + "_material_" + to_string(k), archive.timesampling);
			archive.mesh_map[key] = polyMesh;
			isFirstMesh = true;

			Alembic::AbcGeom::OPolyMeshSchema &meshSchema = polyMesh.getSchema();
			archive.schema_map[key] = meshSchema;
		}

		if (archive.surface_size_map.find(key) == archive.surface_size_map.end())
		{
			archive.surface_size_map[key] = 0;
		}
			
		Alembic::AbcGeom::OPolyMeshSchema &meshSchema = archive.schema_map[key];
		meshSchema.setTimeSampling(archive.timesampling);

		Alembic::AbcGeom::OPolyMeshSchema::Sample empty;
			
		std::vector<Alembic::Util::int32_t> faceList;
		std::vector<Alembic::Util::int32_t> faceCountList;

		const RenderedBuffer::UVList &uvList = renderedBuffer.uvs;
		const RenderedBuffer::VertexList &vertexList = renderedBuffer.vertecies;
		const RenderedBuffer::NormalList &normalList =  renderedBuffer.normals;

		RenderedBuffer::VertexList vertexListByMaterial;
		RenderedBuffer::UVList uvListByMaterial;
		RenderedBuffer::NormalList normalListByMaterial;

		RenderedMaterial* material = renderedBuffer.materials.at(k);
		const int materialSurfaceSize = static_cast<int>(material->surface.faces.size());
		vertexListByMaterial.resize(materialSurfaceSize * 3);
		faceList.resize(materialSurfaceSize * 3);
		faceCountList.resize(materialSurfaceSize);

		if (!uvList.empty())
		{
			uvListByMaterial.resize(materialSurfaceSize * 3);
		}
		if (!normalList.empty())
		{
			normalListByMaterial.resize(materialSurfaceSize * 3);
		}
			
		int& preSurfaceSize = archive.surface_size_map[key];
		bool isFirstSurface = material->surface.faces.size() != preSurfaceSize;
		if (!isFirstMesh && isFirstSurface)
		{
			continue;
		}

		// re assign par material
		int lastIndex = 0;

		for (int n = 0; n < materialSurfaceSize; ++n)
		{
			UMVec3i face = material->surface.faces[n];

			const int f1 = face.x - 1;
			const int f2 = face.y - 1;
			const int f3 = face.z - 1;
			int vi1 = n * 3 + 0;
			int vi2 = n * 3 + 1;
			int vi3 = n * 3 + 2;

			vertexListByMaterial[vi1] = vertexList.at(f1);
			vertexListByMaterial[vi2] = vertexList.at(f2);
			vertexListByMaterial[vi3] = vertexList.at(f3);
			if (!uvList.empty() && archive.is_export_uvs)
			{
				uvListByMaterial[vi1] = uvList.at(f1);
				uvListByMaterial[vi2] = uvList.at(f2);
				uvListByMaterial[vi3] = uvList.at(f3);
			}
			if (!normalList.empty() && archive.is_export_normals)
			{
				normalListByMaterial[vi1] = normalList.at(f1);
				normalListByMaterial[vi2] = normalList.at(f2);
				normalListByMaterial[vi3] = normalList.at(f3);
			}
			faceList[vi1] = vi1;
			faceList[vi2] = vi2;
			faceList[vi3] = vi3;
			faceCountList[n] = 3;
		}

		preSurfaceSize = material->surface.faces.size();
				
		for (int n = 0, nsize = vertexListByMaterial.size(); n < nsize; ++n)
		{
			vertexListByMaterial[n].z = -vertexListByMaterial[n].z;
		}

		Alembic::AbcGeom::OPolyMeshSchema::Sample sample;
				
		// vertex
		Alembic::AbcGeom::P3fArraySample positions( (const Imath::V3f *) &vertexListByMaterial.front(), vertexListByMaterial.size());
		sample.setPositions(positions);
				
		// face index
		if (isFirstMesh)
		{
			Alembic::Abc::Int32ArraySample faceIndices(faceList);
			Alembic::Abc::Int32ArraySample faceCounts(faceCountList);
			sample.setFaceIndices(faceIndices);
			sample.setFaceCounts(faceCounts);
		}

		// UVs
		if (!uvListByMaterial.empty() && archive.is_export_uvs)
		{
			for (int n = 0, nsize = uvListByMaterial.size(); n < nsize; ++n)
			{
				uvListByMaterial[n].y = 1.0f - uvListByMaterial[n].y;
			}
			Alembic::AbcGeom::OV2fGeomParam::Sample uvSample;
			uvSample.setScope(Alembic::AbcGeom::kVertexScope );
			uvSample.setVals(Alembic::AbcGeom::V2fArraySample( ( const Imath::V2f *) &uvListByMaterial.front(), uvListByMaterial.size()));
			sample.setUVs(uvSample);
		}

		// Normals
		if (!normalListByMaterial.empty() && archive.is_export_normals)
		{
			for (int n = 0, nsize = normalListByMaterial.size(); n < nsize; ++n)
			{
				normalListByMaterial[n].z = -normalListByMaterial[n].z;
			}
			Alembic::AbcGeom::ON3fGeomParam::Sample normalSample;
			normalSample.setScope(Alembic::AbcGeom::kVertexScope );
			normalSample.setVals(Alembic::AbcGeom::N3fArraySample( (const Alembic::AbcGeom::N3f *) &normalListByMaterial.front(), normalListByMaterial.size()));
			sample.setNormals(normalSample);
		}
			
		meshSchema.set(sample);
	}
}
コード例 #6
0
ファイル: alembic.cpp プロジェクト: tsks/mmdbridge
static void export_alembic_camera(AlembicArchive &archive, const RenderedBuffer & renderedBuffer, bool isUseEuler)
{
	static const int cameraKey = 0xFFFFFF;
	Alembic::AbcGeom::OObject topObj(*archive.archive, Alembic::AbcGeom::kTop);

	Alembic::AbcGeom::OXform xform;
	if (archive.xform_map.find(cameraKey) != archive.xform_map.end())
	{
		xform = archive.xform_map[cameraKey];
	}
	else
	{
		xform = Alembic::AbcGeom::OXform(topObj, "camera_xform", archive.timesampling);
		archive.xform_map[cameraKey] = xform;

		Alembic::AbcGeom::OXformSchema &xformSchema = xform.getSchema();
		archive.xform_schema_map[cameraKey] = xformSchema;
	}
		
	// set camera transform
	{
		Alembic::AbcGeom::OXformSchema &xformSchema = archive.xform_schema_map[cameraKey];
		xformSchema.setTimeSampling(archive.timesampling);
		
		Alembic::AbcGeom::XformSample xformSample;

		D3DXMATRIX convertMat(
			1, 0, 0, 0,
			0, 1, 0, 0,
			0, 0, -1, 0,
			0, 0, 0, 1);

		D3DXMATRIX convertedWordInv;
		::D3DXMatrixMultiply(&convertedWordInv, &renderedBuffer.world_inv, &convertMat);
			
		D3DXVECTOR3 eye;
		{
			D3DXVECTOR3 v;
			UMGetCameraEye(&v);
			d3d_vector3_transform(eye, v,convertedWordInv);
		}
			
		D3DXVECTOR3 at;
		{
			D3DXVECTOR3 v;
			UMGetCameraAt(&v);
			d3d_vector3_transform(at, v, convertedWordInv);
		}

		D3DXVECTOR3 up;
		{
			D3DXVECTOR3 v;
			UMGetCameraUp(&v);
			d3d_vector3_dir_transform(up, v, convertedWordInv);
			::D3DXVec3Normalize(&up, &up);
		}

		Imath::V3d trans((double)eye.x, (double)eye.y, (double)(eye.z));
		xformSample.setTranslation(trans);

		D3DXMATRIX view;
		::D3DXMatrixLookAtLH(&view, &eye, &at, &up);

		Imath::M44d rot(
			-view.m[0][0], view.m[0][1], view.m[0][2], 0,
			-view.m[1][0], view.m[1][1], view.m[1][2], 0,
			view.m[2][0], -view.m[2][1], -view.m[2][2], 0,
			0, 0, 0, 1);

		Imath::Quatd quat = Imath::extractQuat(rot);
		quat.normalize();

		if (isUseEuler)
		{
			Imath::V3d imeuler;
			quatToEuler(imeuler, quat);

			//UMMat44d umrot(
			//	-view.m[0][0], view.m[0][1], view.m[0][2], 0,
			//	-view.m[1][0], view.m[1][1], view.m[1][2], 0,
			//	view.m[2][0], -view.m[2][1], -view.m[2][2], 0,
			//	0, 0, 0, 1);
			//UMVec3d umeuler = umbase::um_matrix_to_euler_xyz(umrot.transposed());
			xformSample.setXRotation(umbase::um_to_degree(imeuler.y));
			xformSample.setYRotation(umbase::um_to_degree(imeuler.x));
			xformSample.setZRotation(-umbase::um_to_degree(imeuler.z));
		}
		else
		{
			xformSample.setRotation(quat.axis(), umbase::um_to_degree(quat.angle()));
		}

		xformSchema.set(xformSample);
	}
		
	Alembic::AbcGeom::OCamera camera;
	if (archive.camera_map.find(cameraKey) != archive.camera_map.end())
	{
		camera = archive.camera_map[cameraKey];
	}
	else
	{
		camera = Alembic::AbcGeom::OCamera(xform, "camera", archive.timesampling);
		archive.camera_map[cameraKey] = camera;
			
		Alembic::AbcGeom::OCameraSchema &cameraSchema = camera.getSchema();
		archive.camera_schema_map[cameraKey] = cameraSchema;
	}

	Alembic::AbcGeom::OCameraSchema &cameraSchema = archive.camera_schema_map[cameraKey];
	cameraSchema.setTimeSampling(archive.timesampling);
	Alembic::AbcGeom::CameraSample sample;

	D3DXVECTOR4 v;
	UMGetCameraFovLH(&v);

	sample.setNearClippingPlane(v.z);
	sample.setFarClippingPlane(v.w);

	double fovy = v.x;
	double aspect = v.y;
	double fovx = 2.0 * atan(tan(fovy / 2.0)*(aspect));
	double w = BridgeParameter::instance().frame_width / 10.0;
	double h = BridgeParameter::instance().frame_height / 10.0;
	double focalLength = w / (2.0 * tan(fovx / 2.0));

	sample.setHorizontalAperture(w / 10.0);
	sample.setVerticalAperture(h / 10.0);
	sample.setFocalLength(focalLength);

	cameraSchema.set(sample);
}