Exemplo n.º 1
0
    static void cook(FnKat::GeolibCookInterface &interface)
    {
        boost::shared_lock<boost::upgrade_mutex> 
            readerLock(UsdKatanaGetStageLock());

        UsdPrim prim;
        PxrUsdKatanaUsdInArgsRefPtr usdInArgs;

        PxrUsdKatanaUsdInPrivateData* privateData = 
            static_cast<PxrUsdKatanaUsdInPrivateData*>(interface.getPrivateData());

        FnKat::GroupAttribute opArgs = interface.getOpArg();
        
        if (privateData) {
            usdInArgs = privateData->GetUsdInArgs();
        } else {
            FnKat::GroupAttribute additionalOpArgs;
            usdInArgs = InitUsdInArgs(interface, additionalOpArgs);
            opArgs = FnKat::GroupBuilder()
                .update(opArgs)
                .deepUpdate(additionalOpArgs)
                .build();
        }

        if (not usdInArgs) {
            ERROR("Could not initialize PxrUsdIn usdInArgs.");
            return;
        }

        if (interface.atRoot()) {
            interface.stopChildTraversal();

            prim = usdInArgs->GetRootPrim();

            // XXX This info currently gets used to determine whether
            // to correctively rotate cameras. The camera's zUp needs to be
            // recorded until we have no more USD z-Up assets and the katana
            // assets have no more prerotate camera nodes.
            interface.setAttr("info.usd.stageIsZup",
                    FnKat::IntAttribute(UsdUtilsGetCamerasAreZup(usdInArgs->GetStage())));

            // Construct the global camera list at the USD scene root.
            //
            FnKat::StringBuilder cameraListBuilder;

            SdfPathVector cameraPaths = PxrUsdKatanaUtils::FindCameraPaths(prim.GetStage());

            TF_FOR_ALL(cameraPathIt, cameraPaths)
            {
                const std::string path = (*cameraPathIt).GetString();

                // only add cameras to the camera list that are beneath the isolate prim path
                if (path.find(usdInArgs->GetIsolatePath()) != std::string::npos)
                {
                    cameraListBuilder.push_back(
                        TfNormPath(usdInArgs->GetRootLocationPath()+"/"+
                            path.substr(usdInArgs->GetIsolatePath().size())));
                }
            }

            FnKat::StringAttribute cameraListAttr = cameraListBuilder.build();
            if (cameraListAttr.getNumberOfValues() > 0)
            {
                interface.setAttr("cameraList", cameraListAttr);
            }
            
            interface.setAttr("info.usdOpArgs", opArgs);
            
            FnKat::GroupAttribute masterMapping =
                    opArgs.getChildByName("masterMapping");
            if (masterMapping.isValid() && masterMapping.getNumberOfChildren())
            {
                FnGeolibServices::StaticSceneCreateOpArgsBuilder sscb(false);
                
                
                
                for (size_t i = 0, e = masterMapping.getNumberOfChildren();
                        i != e; ++i)
                {
                    std::string masterName = FnKat::DelimiterDecode(
                            masterMapping.getChildName(i));
                    
                    std::string katanaPath =  FnKat::StringAttribute(
                            masterMapping.getChildByIndex(i)
                                    ).getValue("", false);
                    
                    if (katanaPath.empty())
                    {
                        continue;
                    }
                    
                    sscb.createEmptyLocation(katanaPath, "instance source");
                    sscb.setAttrAtLocation(katanaPath,
                            "tabs.scenegraph.stopExpand", FnKat::IntAttribute(1));
                    sscb.setAttrAtLocation(katanaPath, "childPrimPath",
                            FnKat::StringAttribute(masterName));
                }
                
                interface.createChild(
                        "Masters",
                        "PxrUsdIn.MasterIntermediate",
                        FnKat::GroupBuilder()
                            .update(opArgs)
                            .set("staticScene", sscb.build())
                            .build(),
                        FnKat::GeolibCookInterface::ResetRootFalse,
                        new PxrUsdKatanaUsdInPrivateData(
                                usdInArgs->GetRootPrim(), usdInArgs, privateData),
                        PxrUsdKatanaUsdInPrivateData::Delete);
                
                
            }
            
        }
Exemplo n.º 2
0
void InstancerOp::cook(Foundry::Katana::GeolibCookInterface& interface)
{
	if (interface.atRoot())
	{
		interface.stopChildTraversal();
	}

	// find c argument
	FnAttribute::GroupAttribute cGroupAttr = interface.getOpArg("c");
	if (cGroupAttr.isValid())
	{
		if (cGroupAttr.getNumberOfChildren() != 1)
		{
			Foundry::Katana::ReportError(interface, "Invalid attributes.");
			interface.stopChildTraversal();
			return;
		}

		std::string childName = FnAttribute::DelimiterDecode(cGroupAttr.getChildName(0));
		FnAttribute::GroupAttribute childArgs = cGroupAttr.getChildByIndex(0);
		interface.createChild(childName, "", childArgs);
		return;
	}

	FnAttribute::GroupAttribute aGroupAttr = interface.getOpArg("a");
	if (aGroupAttr.isValid())
	{
		// TODO: cache this with Foundry::Katana::GeolibPrivateData...
		std::string sourceLocation;
		FnAttribute::StringAttribute sourceLocationAttr = aGroupAttr.getChildByName("sourceLocation");
		if (sourceLocationAttr.isValid())
		{
			sourceLocation = sourceLocationAttr.getValue("", false);
		}
		
		FnAttribute::IntAttribute instanceTypeAttr = aGroupAttr.getChildByName("instanceType");
		bool threeD = false;
		FnAttribute::IntAttribute threeDAttr = aGroupAttr.getChildByName("threeD");
		if (threeDAttr.isValid())
		{
			threeD = threeDAttr.getValue(0, false) == 1;
		}
		
		bool floatFormat = false;
		FnAttribute::IntAttribute floatFormatMatrixAttr = aGroupAttr.getChildByName("floatFormatMatrix");
		if (floatFormatMatrixAttr.isValid())
		{
			floatFormat = floatFormatMatrixAttr.getValue(0, false) == 1;
		}

		FnAttribute::IntAttribute numInstancesAttr = aGroupAttr.getChildByName("numInstances");
		FnAttribute::IntAttribute groupInstancesAttr = aGroupAttr.getChildByName("groupInstances");

		unsigned int numInstances = (unsigned int)numInstancesAttr.getValue(0, false);
		if (numInstances == 0)
		{
			return;
		}
		
		bool instanceArray = true;
		FnAttribute::IntAttribute instanceArrayAttr = aGroupAttr.getChildByName("instanceArray");
		if (instanceArrayAttr.isValid())
		{
			instanceArray = instanceArrayAttr.getValue(1, false);
		}
		
		bool createInstanceIndexAttribute = false;
		FnAttribute::IntAttribute createInstanceIndexAttributeAttr = aGroupAttr.getChildByName("createInstanceIndexAttribute");
		if (createInstanceIndexAttributeAttr.isValid())
		{
			createInstanceIndexAttribute = createInstanceIndexAttributeAttr.getValue(1, false);
		}
		
		Vec3 areaSpread(20.0f, 20.0f, 20.0f);
		FnAttribute::FloatAttribute areaSpreadAttr = aGroupAttr.getChildByName("areaSpread");
		if (areaSpreadAttr.isValid())
		{
			FnKat::FloatConstVector data = areaSpreadAttr.getNearestSample(0);
		
			areaSpread.x = data[0];
			areaSpread.y = data[1];
			areaSpread.z = data[2];
		}
				
		// we're dangerously assuming that this will be run first...
		if (!threeD)
		{
			create2DGrid(numInstances, areaSpread, aTranslates);
		}
		else
		{
			create3DGrid(numInstances, areaSpread, aTranslates);
		}
		
		if (!instanceArray)
		{
			bool groupInstances = groupInstancesAttr.getValue(0, false);
			if (groupInstances)
			{
				FnAttribute::IntAttribute groupSizeAttr = aGroupAttr.getChildByName("groupSize");
				int groupSize = groupSizeAttr.getValue(0, false);
	
				int groupsNeeded = numInstances / groupSize;
				groupsNeeded += (int)(numInstances % groupSize > 0);
	
				int remainingInstances = numInstances;
				int indexStartCount = 0;
	
				for (int i = 0; i < groupsNeeded; i++)
				{
					std::ostringstream ss;
					ss << "group_" << i;
	
					int thisGroupSize = (remainingInstances >= groupSize) ? groupSize : remainingInstances;
	
					FnAttribute::GroupBuilder childArgsBuilder;
					childArgsBuilder.set("group.index", FnAttribute::IntAttribute(i));
					childArgsBuilder.set("group.indexStart", FnAttribute::IntAttribute(indexStartCount));
					childArgsBuilder.set("group.size", FnAttribute::IntAttribute(thisGroupSize));
					childArgsBuilder.set("group.sourceLoc", FnAttribute::StringAttribute(sourceLocation));
					interface.createChild(ss.str(), "", childArgsBuilder.build());
	
					remainingInstances -= thisGroupSize;
					indexStartCount += thisGroupSize;
				}
			}
			else
			{
				for (int i = 0; i < numInstances; i++)
				{
					std::ostringstream ss;
					ss << "instance_" << i;
	
					FnAttribute::GroupBuilder childArgsBuilder;
					childArgsBuilder.set("leaf.index", FnAttribute::IntAttribute(i));
					childArgsBuilder.set("leaf.sourceLoc", FnAttribute::StringAttribute(sourceLocation));
					interface.createChild(ss.str(), "", childArgsBuilder.build());
				}
			}
		}
		else
		{
			// just create a single instance array location
				
			FnAttribute::GroupBuilder geoGb;
			geoGb.set("instanceSource", FnAttribute::StringAttribute(sourceLocation));
			
			if (floatFormat)
			{
				// we can use FloatAttr for instance array types
				std::vector<float> aMatrixValues(numInstances * 16, 0.0f);
				
				for (int i = 0; i < numInstances; i++)
				{
					const Vec3& trans = aTranslates[i];
					
					// set matrix values
					
					unsigned int matrixStartOffset = i * 16;
					
					aMatrixValues[matrixStartOffset] = 1.0f;
					aMatrixValues[matrixStartOffset + 5] = 1.0f;
					aMatrixValues[matrixStartOffset + 10] = 1.0f;
					
					aMatrixValues[matrixStartOffset + 12] = trans.x;
					aMatrixValues[matrixStartOffset + 13] = trans.y;
					aMatrixValues[matrixStartOffset + 14] = trans.z;
					
					aMatrixValues[matrixStartOffset + 15] = 1.0f;
				}
				
				geoGb.set("instanceMatrix", FnAttribute::FloatAttribute(aMatrixValues.data(), numInstances * 16, 16));
			}
			else
			{
				// double format
				
				std::vector<double> aMatrixValues(numInstances * 16, 0.0);
				
				for (int i = 0; i < numInstances; i++)
				{
					const Vec3& trans = aTranslates[i];
					
					// set matrix values
					
					unsigned int matrixStartOffset = i * 16;
					
					aMatrixValues[matrixStartOffset] = 1.0;
					aMatrixValues[matrixStartOffset + 5] = 1.0;
					aMatrixValues[matrixStartOffset + 10] = 1.0;
					
					aMatrixValues[matrixStartOffset + 12] = trans.x;
					aMatrixValues[matrixStartOffset + 13] = trans.y;
					aMatrixValues[matrixStartOffset + 14] = trans.z;
					
					aMatrixValues[matrixStartOffset + 15] = 1.0;
				}
				
				geoGb.set("instanceMatrix", FnAttribute::DoubleAttribute(aMatrixValues.data(), numInstances * 16, 16));
			}
			
			std::vector<int> aInstanceIndices;
			if (createInstanceIndexAttribute)
			{
				// if we want the optional (for renderers we care about anyway) instanceIndex attribute, add that as well...
				// create array of 0, for each index
				aInstanceIndices.resize(numInstances, 0);
				
				geoGb.set("instanceIndex", FnAttribute::IntAttribute(aInstanceIndices.data(), numInstances, 1));
			}
			
			interface.setAttr("geometry", geoGb.build());
			
			interface.setAttr("type", FnAttribute::StringAttribute("instance array"));			
	
			interface.stopChildTraversal();
		}
		
		return;
	}

	FnAttribute::GroupAttribute group = interface.getOpArg("group");
	if (group.isValid())
	{
		FnAttribute::IntAttribute indexStartAttr = group.getChildByName("indexStart");
		int indexStart = indexStartAttr.getValue(0, false);
		FnAttribute::IntAttribute sizeAttr = group.getChildByName("size");
		int size = sizeAttr.getValue(0 , false);
		
		FnAttribute::StringAttribute sourceLocationAttr = group.getChildByName("sourceLoc");
				
		interface.setAttr("type", FnAttribute::StringAttribute("group"));

		for (int i = indexStart; i < indexStart + size; i++)
		{
			std::ostringstream ss;
			ss << "instance_" << i;

			FnAttribute::GroupBuilder childArgsBuilder;
			childArgsBuilder.set("leaf.index", FnAttribute::IntAttribute(i));
			childArgsBuilder.set("leaf.sourceLoc", sourceLocationAttr);
			interface.createChild(ss.str(), "", childArgsBuilder.build());
		}

		interface.stopChildTraversal();
	}

	FnAttribute::GroupAttribute leaf = interface.getOpArg("leaf");
	if (leaf.isValid())
	{
		FnAttribute::IntAttribute indexAttr = leaf.getChildByName("index");
		int index = indexAttr.getValue(0 , false);

		FnAttribute::GroupBuilder geoGb;

		FnAttribute::StringAttribute sourceLocationAttr = leaf.getChildByName("sourceLoc");
		if (sourceLocationAttr.isValid())
		{			
			geoGb.set("instanceSource", sourceLocationAttr);
		}
		
		interface.setAttr("type", FnAttribute::StringAttribute("instance"));
		interface.setAttr("geometry", geoGb.build());
		
		FnAttribute::GroupBuilder xformGb;
		const Vec3& trans = aTranslates[index];
		double transValues[3] = { trans.x, trans.y, trans.z };
		xformGb.set("translate", FnAttribute::DoubleAttribute(transValues, 3, 3));
		
		interface.setAttr("xform", xformGb.build());

		interface.stopChildTraversal();
	}
}