Пример #1
0
bool
MayaPrimWriter::writePrimAttrs(const MDagPath &dagT, const UsdTimeCode &usdTime, UsdGeomImageable &primSchema) 
{
    MStatus status;
    MFnDependencyNode depFn(getDagPath().node());
    MFnDependencyNode depFn2(dagT.node()); // optionally also scan a shape's transform if merging transforms

    if (getArgs().exportVisibility) {
        bool isVisible  = true;   // if BOTH shape or xform is animated, then visible
        bool isAnimated = false;  // if either shape or xform is animated, then animated

        PxrUsdMayaUtil::getPlugValue(depFn, "visibility", &isVisible, &isAnimated);

        if ( dagT.isValid() ) {
            bool isVis, isAnim;
            if (PxrUsdMayaUtil::getPlugValue(depFn2, "visibility", &isVis, &isAnim)){
                isVisible = isVisible and isVis;
                isAnimated = isAnimated or isAnim;
            }
        }

        TfToken const &visibilityTok = (isVisible ? UsdGeomTokens->inherited : 
                                        UsdGeomTokens->invisible);
        if (usdTime.IsDefault() != isAnimated ) {
            if (usdTime.IsDefault())
                primSchema.CreateVisibilityAttr(VtValue(visibilityTok), true);
            else
                primSchema.CreateVisibilityAttr().Set(visibilityTok, usdTime);
        }
    }

    UsdPrim usdPrim = primSchema.GetPrim();

    // There is no Gprim abstraction in this module, so process the few
    // gprim attrs here.
    UsdGeomGprim gprim = UsdGeomGprim(usdPrim);
    if (gprim and usdTime.IsDefault()){

        PxrUsdMayaPrimWriterContext* unused = NULL;
        PxrUsdMayaTranslatorGprim::Write(
                getDagPath().node(),
                gprim,
                unused);

    }

    _writeUsdInfo(dagT, usdTime, usdPrim);
    
    // Write user-tagged export attributes. Write attributes on the transform
    // first, and then attributes on the shape node. This means that attribute
    // name collisions will always be handled by taking the shape node's value
    // if we're merging transforms and shapes.
    if (dagT.isValid() and !(dagT == getDagPath())) {
        PxrUsdMayaWriteUtil::WriteUserExportedAttributes(dagT, usdPrim, usdTime);
    }
    PxrUsdMayaWriteUtil::WriteUserExportedAttributes(getDagPath(), usdPrim, usdTime);

    return true;
}
Пример #2
0
bool MayaMeshWriter::isMeshValid() 
{
    MStatus status = MS::kSuccess;

    // Sanity checks
    MFnMesh lMesh( getDagPath(), &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
        return false;
    }

    unsigned int numVertices = lMesh.numVertices();
    unsigned int numPolygons = lMesh.numPolygons();
    if (numVertices < 3 && numVertices > 0)
    {
        MString err = lMesh.fullPathName() +
            " is not a valid mesh, because it only has ";
        err += numVertices;
        err += " points.";
        MGlobal::displayError(err);
    }
    if (numPolygons == 0)
    {
        MGlobal::displayWarning(lMesh.fullPathName() + " has no polygons.");
    }
    return true;
}
Пример #3
0
		MStatus Object::setShapesVisibility(bool visible, MTypeId & typeId) {
			MStatus status;
			MDagPath dagPath = getDagPath(status);

			if (!status) {
				status.perror("Object::getDagPath");
				return status;
			}

			unsigned int numShapes;

			if (!(status = dagPath.numberOfShapesDirectlyBelow(numShapes))) {
				status.perror("MDagPath::numberOfShapesDirectlyBelow");
				return status;
			}

			for(unsigned int i = 0; i < numShapes; ++i) {
				MDagPath shape = dagPath;

				if (!(status = shape.extendToShapeDirectlyBelow(i))) {
					status.perror("MDagPath::extendToShapeDirectlyBelow");
					return status;
				}

				MFnDagNode shape_dagNode(shape);

				if (shape_dagNode.typeId(&status) == typeId) {
					MPlug visibilityPlug(shape.node(), shape_dagNode.findPlug("visibility", &status));

					if (!status) {
						status.perror("MFnDagNode::findPlug");
						return status;
					}

					if (!(status = visibilityPlug.setBool(visible))) {
						status.perror("MPlug::setBool");
						return status;
					}
				}
				else if (!status) {
					status.perror("MFnDagNode::typeId");
					return status;
				}
			}

			return MStatus::kSuccess;
		}
Пример #4
0
		MStatus Object::getRotation(MEulerRotation & rotation) {
			MStatus status;

			MFnTransform transform(getDagPath(status));

			if (!status) {
				status.perror("Base::getDagPath");
				return status;
			}

			if (!(status = transform.getRotation(rotation))) {
				status.perror("MFnTransform::getRotation");
				return status;
			}

			return MStatus::kSuccess;
		}
Пример #5
0
		bool Object::isAnyShapeVisible(MTypeId & typeId, MStatus & status) {
			MDagPath dagPath = getDagPath(status);

			if (!status) {
				status.perror("Object::getDagPath");
				return false;
			}

			unsigned int numShapes;

			if (!(status = dagPath.numberOfShapesDirectlyBelow(numShapes))) {
				status.perror("MDagPath::numberOfShapesDirectlyBelow");
				return false;
			}

			for(unsigned int i = 0; i < numShapes; ++i) {
				MDagPath shape = dagPath;

				if (!(status = shape.extendToShapeDirectlyBelow(i))) {
					status.perror("MDagPath::extendToShapeDirectlyBelow");
					return false;
				}

				MFnDagNode shape_dagNode(shape);

				if (shape_dagNode.typeId(&status) == typeId) {
					MPlug visibilityPlug(shape.node(), shape_dagNode.findPlug("visibility", &status));

					if (!status) {
						status.perror("MFnDagNode::findPlug");
						return false;
					}

					if (visibilityPlug.asBool()) {
						status = MStatus::kSuccess;
						return true;
					}
				}
			}

			status = MStatus::kSuccess;
			return false;
		}
Пример #6
0
		MStatus Object::getTranslation(MVector & vector, MSpace::Space space) {
			MStatus status;

			MFnTransform transform(getDagPath(status));

			if (!status) {
				status.perror("Base::getDagPath");
				return status;
			}

			vector = transform.getTranslation(space, &status);

			if (!status) {
				status.perror("MFnTransform::getTranslation");
				return status;
			}

			return MStatus::kSuccess;
		}
Пример #7
0
		MStatus Object::getTransform(MTransformationMatrix & matrix) {
			MStatus status;

			MFnTransform transform(getDagPath(status));

			if (!status) {
				status.perror("Base::getDagPath");
				return status;
			}

			matrix = transform.transformation(&status);

			if (!status) {
				status.perror("MFnTransform::transformation");
				return status;
			}

			return MStatus::kSuccess;
		}
Пример #8
0
// virtual
bool MayaNurbsCurveWriter::writeNurbsCurveAttrs(const UsdTimeCode &usdTime, UsdGeomNurbsCurves &primSchema)
{
    MStatus status = MS::kSuccess;

    // Write parent class attrs
    writeTransformAttrs(usdTime, primSchema);

    // Return if usdTime does not match if shape is animated
    if (usdTime.IsDefault() == isShapeAnimated() ) {
        // skip shape as the usdTime does not match if shape isAnimated value
        return true; 
    }

    MFnDependencyNode fnDepNode(getDagPath().node(), &status);
    MString name = fnDepNode.name();

    MFnNurbsCurve curveFn( getDagPath(), &status );
    if (!status) {
        MGlobal::displayError("MFnNurbsCurve() failed for MayaNurbsCurveWriter");
        return false;
    }

    // Get curve attrs ======
    unsigned int numCurves = 1; // Assuming only 1 curve for now
    VtArray<int> curveOrder(numCurves);
    VtArray<int> curveVertexCounts(numCurves);
    VtArray<float> curveWidths(numCurves);
    VtArray<GfVec2d> ranges(numCurves);

    curveOrder[0] = curveFn.degree()+1;
    curveVertexCounts[0] = curveFn.numCVs();
    TF_AXIOM(curveOrder[0] <= curveVertexCounts[0] );
    curveWidths[0] = 1.0; // TODO: Retrieve from custom attr

    double mayaKnotDomainMin;
    double mayaKnotDomainMax;
    status = curveFn.getKnotDomain(mayaKnotDomainMin, mayaKnotDomainMax);
    TF_AXIOM(status == MS::kSuccess);
    ranges[0][0] = mayaKnotDomainMin;
    ranges[0][1] = mayaKnotDomainMax;

    MPointArray mayaCurveCVs;
    status = curveFn.getCVs(mayaCurveCVs, MSpace::kObject);
    TF_AXIOM(status == MS::kSuccess);
    VtArray<GfVec3f> points(mayaCurveCVs.length()); // all CVs batched together
    for (unsigned int i=0; i < mayaCurveCVs.length(); i++) {
        points[i].Set(mayaCurveCVs[i].x, mayaCurveCVs[i].y, mayaCurveCVs[i].z);
    }

    MDoubleArray mayaCurveKnots;
    status = curveFn.getKnots(mayaCurveKnots);
    TF_AXIOM(status == MS::kSuccess);
    VtArray<double> curveKnots(mayaCurveKnots.length()); // all knots batched together
    for (unsigned int i=0; i < mayaCurveKnots.length(); i++) {
        curveKnots[i] = mayaCurveKnots[i];
    }

    // Gprim
    VtArray<GfVec3f> extent(2);
    UsdGeomCurves::ComputeExtent(points, curveWidths, &extent);
    primSchema.CreateExtentAttr().Set(extent, usdTime);

    // Curve
    primSchema.GetOrderAttr().Set(curveOrder);   // not animatable
    primSchema.GetCurveVertexCountsAttr().Set(curveVertexCounts); // not animatable
    primSchema.GetWidthsAttr().Set(curveWidths); // not animatable
    primSchema.GetKnotsAttr().Set(curveKnots);   // not animatable
    primSchema.GetRangesAttr().Set(ranges); // not animatable
    primSchema.GetPointsAttr().Set(points, usdTime); // CVs

    // TODO: Handle periodic and non-periodic cases

    return true;
}
Пример #9
0
// virtual
bool MayaMeshWriter::writeMeshAttrs(const UsdTimeCode &usdTime, UsdGeomMesh &primSchema)
{

    MStatus status = MS::kSuccess;

    // Write parent class attrs
    writeTransformAttrs(usdTime, primSchema);

    // Return if usdTime does not match if shape is animated
    if (usdTime.IsDefault() == isShapeAnimated() ) {
        // skip shape as the usdTime does not match if shape isAnimated value
        return true; 
    }

    MFnMesh lMesh( getDagPath(), &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
        return false;
    }
    unsigned int numVertices = lMesh.numVertices();
    unsigned int numPolygons = lMesh.numPolygons();

    // Set mesh attrs ==========
    // Get points
    // TODO: Use memcpy()
    const float* mayaRawPoints = lMesh.getRawPoints(&status);
    VtArray<GfVec3f> points(numVertices);
    for (unsigned int i = 0; i < numVertices; i++) {
        unsigned int floatIndex = i*3;
        points[i].Set(mayaRawPoints[floatIndex],
                      mayaRawPoints[floatIndex+1],
                      mayaRawPoints[floatIndex+2]);
    }
    primSchema.GetPointsAttr().Set(points, usdTime); // ANIMATED

    // Compute the extent using the raw points
    VtArray<GfVec3f> extent(2);
    UsdGeomPointBased::ComputeExtent(points, &extent);
    primSchema.CreateExtentAttr().Set(extent, usdTime);

    // Get faceVertexIndices
    unsigned int numFaceVertices = lMesh.numFaceVertices(&status);
    VtArray<int>     faceVertexCounts(numPolygons);
    VtArray<int>     faceVertexIndices(numFaceVertices);
    MIntArray mayaFaceVertexIndices; // used in loop below
    unsigned int curFaceVertexIndex = 0;
    for (unsigned int i = 0; i < numPolygons; i++) {
        lMesh.getPolygonVertices(i, mayaFaceVertexIndices);
        faceVertexCounts[i] = mayaFaceVertexIndices.length();
        for (unsigned int j=0; j < mayaFaceVertexIndices.length(); j++) {
            faceVertexIndices[ curFaceVertexIndex ] = mayaFaceVertexIndices[j]; // push_back
            curFaceVertexIndex++;
        }
    }
    primSchema.GetFaceVertexCountsAttr().Set(faceVertexCounts);   // not animatable
    primSchema.GetFaceVertexIndicesAttr().Set(faceVertexIndices); // not animatable

    // Read usdSdScheme attribute. If not set, we default to defaultMeshScheme
    // flag that can be user defined and initialized to catmullClark
    TfToken sdScheme = PxrUsdMayaMeshUtil::getSubdivScheme(lMesh, getArgs().defaultMeshScheme);    
    primSchema.CreateSubdivisionSchemeAttr(VtValue(sdScheme), true);

    // Polygonal Mesh Case
    if (sdScheme==UsdGeomTokens->none) {
        // Support for standard USD bool and with Mojito bool tag
        TfToken normalInterp=PxrUsdMayaMeshUtil::getEmitNormals(lMesh, UsdGeomTokens->none);
        
        if (normalInterp==UsdGeomTokens->faceVarying) {
            // Get References to members of meshData object
            MFloatVectorArray normalArray;
            MFloatVectorArray vertexNormalArray;
 
            lMesh.getNormals(normalArray, MSpace::kObject);

            // Iterate through each face in the mesh.
            vertexNormalArray.setLength(lMesh.numFaceVertices());
            VtArray<GfVec3f> meshNormals(lMesh.numFaceVertices());
            size_t faceVertIdx = 0;
            for (MItMeshPolygon faceIter(getDagPath()); !faceIter.isDone(); faceIter.next()) {
                // Iterate through each face-vertex.
                for (size_t locVertIdx = 0; locVertIdx < faceIter.polygonVertexCount();
                        ++locVertIdx, ++faceVertIdx) {
                    int index=faceIter.normalIndex(locVertIdx);
                    for (int j=0;j<3;j++) {
                        meshNormals[faceVertIdx][j]=normalArray[index][j];
                    }
                }
            }
            primSchema.GetNormalsAttr().Set(meshNormals, usdTime);
            primSchema.SetNormalsInterpolation(normalInterp);
        }
    } else {
        TfToken sdInterpBound = PxrUsdMayaMeshUtil::getSubdivInterpBoundary(
            lMesh, UsdGeomTokens->edgeAndCorner);

        primSchema.CreateInterpolateBoundaryAttr(VtValue(sdInterpBound), true);
        
        TfToken sdFVInterpBound = PxrUsdMayaMeshUtil::getSubdivFVInterpBoundary(
            lMesh);

        primSchema.CreateFaceVaryingLinearInterpolationAttr(
            VtValue(sdFVInterpBound), true);

        assignSubDivTagsToUSDPrim( lMesh, primSchema);
    }

    // Holes - we treat InvisibleFaces as holes
    MUintArray mayaHoles = lMesh.getInvisibleFaces();
    if (mayaHoles.length() > 0) {
        VtArray<int> subdHoles(mayaHoles.length());
        for (unsigned int i=0; i < mayaHoles.length(); i++) {
            subdHoles[i] = mayaHoles[i];
        }
        // not animatable in Maya, so we'll set default only
        primSchema.GetHoleIndicesAttr().Set(subdHoles);
    }

    // == Write UVSets as Vec2f Primvars
    MStringArray uvSetNames;
    if (getArgs().exportMeshUVs) {
        status = lMesh.getUVSetNames(uvSetNames);
    }
    for (unsigned int i=0; i < uvSetNames.length(); i++) {
        // Initialize the VtArray to the max possible size (facevarying)
        VtArray<GfVec2f> uvValues(numFaceVertices);
        TfToken interpolation=TfToken();
        // Gather UV data and interpolation into a Vec2f VtArray and try to compress if possible
        if (_GetMeshUVSetData(lMesh, uvSetNames[i], &uvValues, &interpolation) == MS::kSuccess) {
        
            // XXX:bug 118447
            // We should be able to configure the UV map name that triggers this
            // behavior, and the name to which it exports.
            // The UV Set "map1" is renamed st. This is a Pixar/USD convention
            TfToken setName(uvSetNames[i].asChar());
            if (setName == "map1") setName=UsdUtilsGetPrimaryUVSetName();
       
            // Create the primvar and set the values
            UsdGeomPrimvar uvSet = 
                primSchema.CreatePrimvar(setName, SdfValueTypeNames->Float2Array, interpolation);
            uvSet.Set( uvValues ); // not animatable
        }
    }
    
    // == Gather ColorSets
    MStringArray colorSetNames;
    if (getArgs().exportColorSets) {
        status = lMesh.getColorSetNames(colorSetNames);
    }
    // shaderColor is used in our pipeline as displayColor.
    // shaderColor is used to fill faces where the colorset is not assigned
    MColorArray shaderColors;
    MObjectArray shaderObjs;
    
    VtArray<GfVec3f> shadersRGBData;
    TfToken shadersRGBInterp;
    VtArray<float> shadersAlphaData;
    TfToken shadersAlphaInterp;

    // If exportDisplayColor is set to true or we have color sets,
    // gather color & opacity from the shader including per face
    // assignment. Color set require this to initialize unauthored/unpainted faces 
    if (getArgs().exportDisplayColor or colorSetNames.length()>0) {
        PxrUsdMayaUtil::GetLinearShaderColor(lMesh, numPolygons, 
                &shadersRGBData, &shadersRGBInterp, 
                &shadersAlphaData, &shadersAlphaInterp);
    }

    for (unsigned int i=0; i < colorSetNames.length(); i++) {

        bool isDisplayColor=false;

        if (colorSetNames[i]=="displayColor") {
            if (not getArgs().exportDisplayColor)
                continue;
            isDisplayColor=true;
        }
        
        if (colorSetNames[i]=="displayOpacity") {
            MGlobal::displayWarning("displayOpacity on mesh:" + lMesh.fullPathName() + 
            " is a reserved PrimVar name in USD. Skipping...");
            continue;
        }

        VtArray<GfVec3f> RGBData;
        TfToken RGBInterp;
        VtArray<GfVec4f> RGBAData;
        TfToken RGBAInterp;
        VtArray<float> AlphaData;
        TfToken AlphaInterp;
        MFnMesh::MColorRepresentation colorSetRep;
        bool clamped=false;

        // If displayColor uses shaderValues for non authored areas
        // and allow RGB and Alpha to have different interpolation
        // For all other colorSets the non authored values are set 
        // to (1,1,1,1) and RGB and Alpha will have the same interplation
        // since they will be emitted as a Vec4f
        if (not _GetMeshColorSetData( lMesh, colorSetNames[i],
                                        isDisplayColor,
                                        shadersRGBData, shadersAlphaData,
                                        &RGBData, &RGBInterp,
                                        &RGBAData, &RGBAInterp,
                                        &AlphaData, &AlphaInterp,
                                        &colorSetRep, &clamped)) {
            MGlobal::displayWarning("Unable to retrieve colorSet data: " +
                    colorSetNames[i] + " on mesh: "+ lMesh.fullPathName() + ". Skipping...");
            continue;
        }

        if (isDisplayColor) {
            // We tag the resulting displayColor/displayOpacity primvar as
            // authored to make sure we reconstruct the colorset on import
            // The RGB is also convererted From DisplayToLinear
            
            
            _setDisplayPrimVar( primSchema, colorSetRep,
                                RGBData, RGBInterp,
                                AlphaData, AlphaInterp,
                                clamped, true);
        } else {
            TfToken colorSetNameToken = TfToken(
                    PxrUsdMayaUtil::SanitizeColorSetName(
                        std::string(colorSetNames[i].asChar())));
            if (colorSetRep == MFnMesh::kAlpha) {
                    _createAlphaPrimVar(primSchema, colorSetNameToken,
                        AlphaData, AlphaInterp, clamped);
            } else if (colorSetRep == MFnMesh::kRGB) {
                    _createRGBPrimVar(primSchema, colorSetNameToken,
                        RGBData, RGBInterp, clamped);
            } else if (colorSetRep == MFnMesh::kRGBA) {
                    _createRGBAPrimVar(primSchema, colorSetNameToken,
                        RGBAData, RGBAInterp, clamped);
            }
        }
    }
    // Set displayColor and displayOpacity only if they are NOT authored already
    // Since this primvar will come from the shader and not a colorset,
    // we are not adding the clamp attribute as custom data
    // If a displayColor/displayOpacity is added, it's not considered authored
    // we don't need to reconstruct this as a colorset since it orgininated
    // from bound shader[s], so the authored flag is set to false
    // Given that this RGB is for display, we do DisplayToLinear conversion
    if (getArgs().exportDisplayColor) {
        _setDisplayPrimVar( primSchema, MFnMesh::kRGBA,
                                shadersRGBData, shadersRGBInterp,
                                shadersAlphaData, shadersAlphaInterp,
                                false, false);
    }
    return true;
}
Пример #10
0
/* virtual */
bool MayaCameraWriter::writeCameraAttrs(const UsdTimeCode &usdTime, UsdGeomCamera &primSchema)
{
    // Since write() above will take care of any animation on the camera's
    // transform, we only want to proceed here if:
    // - We are at the default time and NO attributes on the shape are animated.
    //    OR
    // - We are at a non-default time and some attribute on the shape IS animated.
    if (usdTime.IsDefault() == isShapeAnimated()) {
        return true;
    }

    MStatus status;

    MFnCamera camFn(getDagPath(), &status);
    CHECK_MSTATUS_AND_RETURN(status, false);

    // NOTE: We do not use a GfCamera and then call SetFromCamera() below
    // because we want the xformOps populated by the parent class to survive.
    // Using SetFromCamera() would stomp them with a single "transform" xformOp.

    // Set the type of projection.
    if (camFn.isOrtho()) {
        primSchema.GetProjectionAttr().Set(UsdGeomTokens->orthographic, usdTime);
    } else {
        primSchema.GetProjectionAttr().Set(UsdGeomTokens->perspective, usdTime);
    }

    // Setup the aperture.
    primSchema.GetHorizontalApertureAttr().Set(
        float(PxrUsdMayaUtil::ConvertInchesToMM(
                camFn.horizontalFilmAperture() *
                camFn.lensSqueezeRatio())),
        usdTime);
    primSchema.GetVerticalApertureAttr().Set(
        float(PxrUsdMayaUtil::ConvertInchesToMM(
                camFn.verticalFilmAperture() *
                camFn.lensSqueezeRatio())),
        usdTime);

    primSchema.GetHorizontalApertureOffsetAttr().Set(
        float(camFn.horizontalFilmOffset()), usdTime);
    primSchema.GetVerticalApertureOffsetAttr().Set(
        float(camFn.verticalFilmOffset()), usdTime);

    // Set the lens parameters.
    primSchema.GetFocalLengthAttr().Set(
        float(camFn.focalLength()), usdTime);

    // Always export focus distance and fStop regardless of what
    // camFn.isDepthOfField() says. Downstream tools can choose to ignore or
    // override them.
    primSchema.GetFocusDistanceAttr().Set(
        float(camFn.focusDistance()), usdTime);
    primSchema.GetFStopAttr().Set(
        float(camFn.fStop()), usdTime);

    // Set the clipping planes.
    GfVec2f clippingRange(camFn.nearClippingPlane(), camFn.farClippingPlane());
    primSchema.GetClippingRangeAttr().Set(clippingRange, usdTime);

    return true;
}