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(); }
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)); }
/*********************************************************************** * 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; }
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); }
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); } }
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); }